{"info":{"name":"SKU.io API","description":"Auto-generated from the SKU.io OpenAPI spec — the same source that powers https://developer.sku.io. Set the `baseUrl` variable to your tenant (default https://app.sku.io — replace `app` with your subdomain) and put a Personal Access Token in the `token` variable (Settings → Developer → Personal Access Tokens). Spec version 1.0.0.","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"auth":{"type":"bearer","bearer":[{"key":"token","value":"{{token}}","type":"string"}]},"variable":[{"key":"baseUrl","value":"https://app.sku.io","type":"string"},{"key":"token","value":"","type":"string"}],"item":[{"name":"Core API","item":[{"name":"Accounting","item":[{"name":"Get Sync Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/accounting/sync-settings","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings"]},"description":"Returns the accounting sync settings for the configured integration, including per-type sync enable/disable controls and sync start dates.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/accounting/sync-settings","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 5,\n    \"integration_name\": \"Xero\",\n    \"sync_controls_by_type\": {\n      \"sales_order_invoice\": {\n        \"enabled\": true,\n        \"sync_start_date\": \"2024-01-01\",\n        \"label\": \"Sales Order Invoice\"\n      },\n      \"purchase_order_invoice\": {\n        \"enabled\": true,\n        \"sync_start_date\": null,\n        \"label\": \"Purchase Order Invoice\"\n      },\n      \"credit_note\": {\n        \"enabled\": false,\n        \"sync_start_date\": null,\n        \"label\": \"Credit Note\"\n      }\n    }\n  }\n}"}]},{"name":"Update Sync Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/accounting/sync-settings","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings"]},"description":"Updates the accounting sync settings. Unsubmitted types are preserved (partial updates supported).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nsync_controls_by_type keys must be valid AccountingTransactionTypeEnum values.\nEach type: enabled (required boolean) + sync_start_date (nullable date)","body":{"mode":"raw","raw":"{\n  \"sync_controls_by_type\": {\n    \"sales_order_invoice\": {\n      \"enabled\": true,\n      \"sync_start_date\": \"2024-01-01\"\n    },\n    \"credit_note\": {\n      \"enabled\": false,\n      \"sync_start_date\": null\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/accounting/sync-settings","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 5,\n    \"integration_name\": \"Xero\",\n    \"sync_controls_by_type\": {\n      \"sales_order_invoice\": {\n        \"enabled\": true,\n        \"sync_start_date\": \"2024-01-01\",\n        \"label\": \"Sales Order Invoice\"\n      }\n    }\n  },\n  \"message\": \"Sync settings updated successfully.\"\n}"}]},{"name":"Get Transaction Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/accounting/sync-settings/types","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings","types"]},"description":"Returns all available accounting transaction types with their human-readable labels.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/accounting/sync-settings/types","host":["{{baseUrl}}"],"path":["api","accounting","sync-settings","types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"value\": \"sales_order_invoice\",\n      \"label\": \"Sales Order Invoice\"\n    },\n    {\n      \"value\": \"purchase_order_invoice\",\n      \"label\": \"Purchase Order Invoice\"\n    },\n    {\n      \"value\": \"credit_note\",\n      \"label\": \"Credit Note\"\n    },\n    {\n      \"value\": \"payment\",\n      \"label\": \"Payment\"\n    }\n  ]\n}"}]},{"name":"Get Accounting Integration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/accounting/integration","host":["{{baseUrl}}"],"path":["api","accounting","integration"]},"description":"Returns the currently configured accounting integration instance (QBO or Xero).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/accounting/integration","host":["{{baseUrl}}"],"path":["api","accounting","integration"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 5,\n  \"integration_id\": 3,\n  \"name\": \"My Xero\",\n  \"is_active\": true,\n  \"created_at\": \"2023-01-01T00:00:00.000000Z\"\n}"}]}]},{"name":"Financials","item":[{"name":"Recalculate Daily Financials","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financials/daily-financials/recalculate","host":["{{baseUrl}}"],"path":["api","financials","daily-financials","recalculate"]},"description":"Triggers recalculation of the specified daily financial summary records. For large datasets (using filters), processing is dispatched as a background job.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)\n\nRequest body:\n- ids (array, optional): Array of daily financial summary IDs to recalculate\n- filters (string, optional): Filter string to select records for recalculation (triggers background job)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1500,\n    1501,\n    1502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financials/daily-financials/recalculate","host":["{{baseUrl}}"],"path":["api","financials","daily-financials","recalculate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Recalculation successful\"\n}"}]},{"name":"Get Daily Financial Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]},"description":"Returns the details of a single daily financial summary record.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1500,\n    \"date\": \"2024-01-14\",\n    \"reportable\": {\n      \"id\": 100,\n      \"type\": \"App\\\\Models\\\\Product\",\n      \"product\": {\n        \"id\": 100,\n        \"sku\": \"SKU-001\",\n        \"brand\": \"ACME\"\n      }\n    },\n    \"quantity\": 25,\n    \"quantity_returned\": 2,\n    \"num_orders\": 10,\n    \"revenue\": 1250,\n    \"total_revenue\": 1175,\n    \"cost\": 500,\n    \"total_cost\": 460,\n    \"profit\": 715,\n    \"profit_margin\": 60.85,\n    \"created_at\": \"2024-01-14T23:59:59.000000Z\",\n    \"updated_at\": \"2024-01-15T01:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Daily Financial Summary","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]},"description":"Updates the specified daily financial summary record.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1500\n  },\n  \"message\": \"Updated successfully.\"\n}"}]},{"name":"Delete Daily Financial Summary","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]},"description":"Deletes the specified daily financial summary record.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/financials/daily-summary/{daily_summary}","host":["{{baseUrl}}"],"path":["api","financials","daily-summary",":daily_summary"],"variable":[{"key":"daily_summary","value":"1500","description":"Daily financial summary record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted successfully.\"\n}"}]},{"name":"Create Daily Financial Summary","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financials/daily-summary","host":["{{baseUrl}}"],"path":["api","financials","daily-summary"]},"description":"Creates a new daily financial summary record.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financials/daily-summary","host":["{{baseUrl}}"],"path":["api","financials","daily-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1501\n  },\n  \"message\": \"Created successfully.\"\n}"}]},{"name":"Get Financial Summary by Period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financials/summary-by-period?period=monthly&trailing_days=90","host":["{{baseUrl}}"],"path":["api","financials","summary-by-period"],"query":[{"key":"period","value":"monthly","description":"Period grouping (required). Values: daily, weekly, monthly, quarterly, yearly","disabled":true},{"key":"trailing_days","value":"90","description":"Number of trailing days to include in the report (optional). If omitted, uses all available data.","disabled":true}]},"description":"Returns aggregated financial data (revenue, cost, profit) grouped by the specified time period. Used for financial trend charts and reporting dashboards.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)\n\nResponse: Array of period summaries with:\n- period: The period label (e.g. '2024-01', 'Q1 2024')\n- revenue, cost, profit: Aggregated financial totals\n- num_orders: Total order count for the period"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financials/summary-by-period?period=monthly&trailing_days=90","host":["{{baseUrl}}"],"path":["api","financials","summary-by-period"],"query":[{"key":"period","value":"monthly","description":"Period grouping (required). Values: daily, weekly, monthly, quarterly, yearly","disabled":true},{"key":"trailing_days","value":"90","description":"Number of trailing days to include in the report (optional). If omitted, uses all available data.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"period\": \"2024-01\",\n      \"revenue\": 45250,\n      \"cost\": 18100,\n      \"profit\": 27150,\n      \"num_orders\": 182\n    },\n    {\n      \"period\": \"2023-12\",\n      \"revenue\": 38900,\n      \"cost\": 15560,\n      \"profit\": 23340,\n      \"num_orders\": 156\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Financial Summary by Period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financials/products/{product_id}/summary-by-period?period=monthly&trailing_days=180","host":["{{baseUrl}}"],"path":["api","financials","products",":product_id","summary-by-period"],"query":[{"key":"period","value":"monthly","description":"Period grouping (required). Values: daily, weekly, monthly, quarterly, yearly","disabled":true},{"key":"trailing_days","value":"180","description":"Number of trailing days to include (optional)","disabled":true}],"variable":[{"key":"product_id","value":"100","description":"Product ID"}]},"description":"Returns financial summary data for a specific product, grouped by the specified time period. Used for product-level financial analytics.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)\n\nResponse: Array of period summaries with revenue, cost, profit broken down for the specific product."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financials/products/{product_id}/summary-by-period?period=monthly&trailing_days=180","host":["{{baseUrl}}"],"path":["api","financials","products",":product_id","summary-by-period"],"query":[{"key":"period","value":"monthly","description":"Period grouping (required). Values: daily, weekly, monthly, quarterly, yearly","disabled":true},{"key":"trailing_days","value":"180","description":"Number of trailing days to include (optional)","disabled":true}],"variable":[{"key":"product_id","value":"100","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"period\": \"2024-01\",\n      \"revenue\": 1250,\n      \"cost\": 500,\n      \"profit\": 750,\n      \"num_orders\": 10,\n      \"quantity\": 25\n    },\n    {\n      \"period\": \"2023-12\",\n      \"revenue\": 980,\n      \"cost\": 392,\n      \"profit\": 588,\n      \"num_orders\": 8,\n      \"quantity\": 20\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List Top Products by Financial Metric","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financials/top-products?metric=revenue&limit=10","host":["{{baseUrl}}"],"path":["api","financials","top-products"],"query":[{"key":"metric","value":"revenue","description":"Metric to rank products by (required). Values: 'revenue', 'profit'","disabled":true},{"key":"limit","value":"10","description":"Number of top products to return (optional, default: 10)","disabled":true}]},"description":"Returns the top-performing products ranked by the specified financial metric. Used for dashboard widgets and financial analysis.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)\n\nResponse fields per product:\n- product.id, product.name, product.sku, product.image_url\n- product.brand: {id, name} (when available)\n- quantity_sold: Total units sold\n- revenue: Total revenue generated\n- costs: Total cost of goods sold\n- profit: Total profit (revenue - costs)\n- num_orders: Total number of orders"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financials/top-products?metric=revenue&limit=10","host":["{{baseUrl}}"],"path":["api","financials","top-products"],"query":[{"key":"metric","value":"revenue","description":"Metric to rank products by (required). Values: 'revenue', 'profit'","disabled":true},{"key":"limit","value":"10","description":"Number of top products to return (optional, default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product\": {\n        \"id\": 100,\n        \"name\": \"Widget A\",\n        \"sku\": \"SKU-001\",\n        \"image_url\": \"https://cdn.example.com/products/sku-001.jpg\",\n        \"brand\": {\n          \"id\": 5,\n          \"name\": \"ACME Brand\"\n        }\n      },\n      \"quantity_sold\": 250,\n      \"revenue\": 12500,\n      \"costs\": 5000,\n      \"profit\": 7500,\n      \"num_orders\": 100\n    },\n    {\n      \"product\": {\n        \"id\": 101,\n        \"name\": \"Widget B\",\n        \"sku\": \"SKU-002\",\n        \"image_url\": null,\n        \"brand\": null\n      },\n      \"quantity_sold\": 180,\n      \"revenue\": 9000,\n      \"costs\": 3600,\n      \"profit\": 5400,\n      \"num_orders\": 72\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Recalculate Sales Order Line Financials","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financials/sales-order-line-financials/recalculate-lines","host":["{{baseUrl}}"],"path":["api","financials","sales-order-line-financials","recalculate-lines"]},"description":"Triggers recalculation of financial data for the specified sales order lines. For large datasets (using filters), processing is chunked and dispatched as background jobs (10,000 records per chunk).\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required)\n\nRequest body:\n- ids (array, optional): Array of sales order line IDs to recalculate\n- filters (string, optional): Filter string to select records for recalculation (triggers chunked background jobs)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8001,\n    8002,\n    8003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financials/sales-order-line-financials/recalculate-lines","host":["{{baseUrl}}"],"path":["api","financials","sales-order-line-financials","recalculate-lines"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Recalculation successful\"\n}"}]},{"name":"Export Sales Order Line Financials","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines/export","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines","export"]},"description":"Exports sales order line financials. The endpoint picks one of two response modes based on dataset size:\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n1. SYNC (≤ 1,000 rows or scope=current_page) — streams the file inline as the response body. Content-Type is text/csv or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.\n\n2. QUEUED (> 1,000 rows) — dispatches a background job and returns a JSON envelope with the tracked_job_log_id. The frontend should poll the tracked job log endpoints; when the job completes the resulting file is fetched via the export/download endpoint.\n\nAuthentication: Requires Bearer token (Power User access required).\n\nFilters and sorts mirror the List Sales Order Line Financials endpoint.\n\nExported columns now include an 'Allocation' column (after 'Revenue Allocated') — 'Cost-corrected' when the line's revenue was re-allocated in proportion to bundle-group COGS, otherwise 'Document'."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines/export","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary file — CSV or XLSX>"}]},{"name":"Download Sales Order Line Financials Export","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines/export/download?file=sales-order-financials-2026-05-22-13-00-00.xlsx","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines","export","download"],"query":[{"key":"file","value":"sales-order-financials-2026-05-22-13-00-00.xlsx","description":"Filename returned in the completed tracked job's results.file. The server basenames this value and serves from the model-exports disk; unknown filenames yield 404.","disabled":true}]},"description":"Downloads a completed background export produced by Export Sales Order Line Financials (queued path). The filename is the one reported in the tracked job log's results.file field.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Power User access required).\n\nResponse is the binary file (CSV or XLSX) with an attachment Content-Disposition header. Returns 404 if the file param is empty or the file no longer exists on the model-exports disk."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines/export/download?file=sales-order-financials-2026-05-22-13-00-00.xlsx","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines","export","download"],"query":[{"key":"file","value":"sales-order-financials-2026-05-22-13-00-00.xlsx","description":"Filename returned in the completed tracked job's results.file. The server basenames this value and serves from the model-exports disk; unknown filenames yield 404.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary file>"}]},{"name":"Daily Financial Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financials/daily-summary","host":["{{baseUrl}}"],"path":["api","v2","financials","daily-summary"]},"description":"Returns paginated daily financial summary rows. Each row is backed by a polymorphic reportable: a Product or a Financial Line Type.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters (Spatie QueryBuilder syntax, filter[name]=value):\n- filter[search] — searches product SKU/name and financial line type name/classification; numeric values also match row ID\n- filter[date_from] / filter[date_to] — date range on the summary date (YYYY-MM-DD)\n- filter[id] / filter[reportable_type] — exact match\n- filter[financial_line_type.{operator}] — financial line type NAME on FinancialLineType-backed rows. The financial_line_type filter value can be a plain name (\"Shipping\") or a classification-qualified value (\"Revenue: Shipping\" / \"Cost: Shipping\") — line type names are only unique per classification, so the qualified form (which the application UI now sends) constrains both classification and name. Plain names still match across all classifications for backward compatibility. Advanced text filter operators (append to the filter name): is, is_not, contains, does_not_contain, is_one_of (comma-separated), starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty. Bare filter[financial_line_type]=value acts as implicit 'is'. Positive operators return only financial-line-type rows that match; negative operators (is_not, does_not_*) exclude matching line-type rows while keeping all other rows (e.g. product-backed rows).\n- filter[classification.{operator}] — financial line type classification ('revenue' or 'cost'), same operators as above\n- Numeric advanced filters on: id, quantity, quantity_returned, num_orders, revenue, revenue_allocated, revenue_credits, total_revenue, cost, cost_allocated, cost_invoices, cost_returned, total_cost, profit, profit_margin (operators: equals, not_equals, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty)\n- Date advanced filters on: date, created_at, updated_at\n\nSorting: sort param, prefix with - for DESC. Allowed sorts: id, date, quantity, num_orders, total_revenue, total_cost, profit, profit_margin, created_at, updated_at. Default: -date.\n\nPagination: page, per_page (default 15).\n\nGrouped filters: this endpoint also accepts a filter_groups query param — a base64-encoded JSON tree with AND/OR conjunctions and nested groups (this is what the application UI advanced filters modal sends). Example JSON before encoding: {\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"financial_line_type\",\"operator\":\"is\",\"value\":\"Shipping Revenue\"}}]}. Conditions reference the same filter columns/operators listed above. When filter_groups is present, tree conditions are applied with proper parenthesization; flat filter[...] params still work for non-tree filters (search, date_from, date_to)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financials/daily-summary","host":["{{baseUrl}}"],"path":["api","v2","financials","daily-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 102,\n      \"date\": \"2024-03-01\",\n      \"reportable\": {\n        \"id\": 3,\n        \"type\": \"App\\\\Models\\\\FinancialLineType\",\n        \"financial_line_type\": {\n          \"id\": 3,\n          \"name\": \"Shipping Revenue\",\n          \"classification\": \"revenue\"\n        }\n      },\n      \"quantity\": 0,\n      \"quantity_returned\": 0,\n      \"num_orders\": 18,\n      \"revenue\": \"240.00\",\n      \"revenue_allocated\": \"0.00\",\n      \"revenue_credits\": \"0.00\",\n      \"revenue_discount\": \"0.00\",\n      \"total_revenue\": \"240.00\",\n      \"cost\": \"0.00\",\n      \"cost_allocated\": \"0.00\",\n      \"cost_invoices\": \"0.00\",\n      \"cost_returned\": \"0.00\",\n      \"cost_breakdown\": null,\n      \"total_cost\": \"0.00\",\n      \"profit\": \"240.00\",\n      \"profit_margin\": \"100.00\",\n      \"updated_at\": \"2024-03-02T04:10:11.000000Z\",\n      \"created_at\": \"2024-03-02T04:10:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"https://sku-alt2.test/api/v2/financials/daily-summary?page=1\",\n  \"last_page_url\": \"https://sku-alt2.test/api/v2/financials/daily-summary?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"https://sku-alt2.test/api/v2/financials/daily-summary\",\n  \"links\": []\n}"}]},{"name":"Sales Order Line Financials","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns paginated financial data at the sales order line level.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financials/sales-order-lines?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","financials","sales-order-lines"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sales_order_id\": 30,\n      \"product_id\": 15,\n      \"quantity\": 10,\n      \"unit_price\": \"9.99\",\n      \"unit_cost\": \"4.50\",\n      \"revenue\": \"99.90\",\n      \"cogs\": \"45.00\",\n      \"gross_profit\": \"54.90\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 100,\n  \"per_page\": 10,\n  \"total\": 998\n}"}]}]},{"name":"Bills","item":[{"name":"List Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/list?page=1&per_page=10&sort=-created_at","host":["{{baseUrl}}"],"path":["api","bills","list"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field; prefix with - for descending. Allowed: id, invoice_number, invoice_date, supplier_name, supplier_id, link_type, link_reference, proration_strategy, currency_code, currency_rate, line_count, subtotal, tax_total, grand_total, allocated_amount, unallocated_amount, allocation_status, documents_count, created_at, updated_at. Default: -created_at","disabled":true}]},"description":"Paginated landed cost bills listing for the list view (`/v2/purchases/bills`). Lists every bill across all three link types (Purchase Order, Warehouse Transfer, Inbound Shipment) with computed totals, allocation status, and source (OCR vs manual).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUses Spatie QueryBuilder with grouped-filter (tree) support.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).\n\n## Pagination\n- `page` — page number (default 1)\n- `per_page` — items per page (default 10)\n\n## Sorting\n`sort` — prefix with `-` for descending. Default: `-created_at`.\nAllowed sorts: `id`, `invoice_number`, `invoice_date`, `supplier_name`, `supplier_id`, `link_type`, `link_reference`, `proration_strategy`, `currency_code`, `currency_rate`, `line_count`, `subtotal`, `tax_total`, `grand_total`, `allocated_amount`, `unallocated_amount`, `allocation_status`, `created_at`, `updated_at`\n\n## Search\n`filter[search]` — searches Invoice Number (partial), Bill ID (exact), Supplier name, Bill line descriptions, and the linked document reference (PO number / transfer reference / shipment reference).\n\n## Advanced filters\nAdvanced filters use the `filter[{column}.{operator}]=value` syntax. A bare `filter[{column}]=value` acts as an implicit `is`.\n\n**Text columns** (operators: contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty):\n- `invoice_number`, `proration_strategy`, `link_reference`, `currency_code`\n- `link_type` — values: `purchase_order`, `warehouse_transfer`, `inbound_shipment`\n- `source` — values: `ocr`, `manual`\n- `allocation_status` — values: `empty`, `unallocated`, `partial`, `allocated`\n- `supplier_name`, `line_description`, `line_nominal_code`, `cost_category` (related-table text filters)\n- `supplier_id`, `cost_category_id` (ID-select filters, text-typed)\n\n**Numeric columns** (operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty):\n- `id`, `currency_rate`, `subtotal`, `tax_total`, `total`, `grand_total`, `allocated_amount`, `unallocated_amount`, `line_count`, `line_quantity`, `line_amount`\n- `between` takes two comma-separated values, e.g. `filter[grand_total.between]=100,500`\n\n**Date columns** (operators: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days):\n- `invoice_date`, `created_at`, `updated_at`\n- Dates use `YYYY-MM-DD`; `between` takes two comma-separated dates\n\n**Boolean filters:**\n- `filter[has_accounting_transaction]=true|false` — whether an accounting transaction has been generated for the bill\n\n## Grouped filters (filter_groups)\n`filter_groups` — base64-encoded JSON tree supporting AND/OR conjunctions and nested groups. Takes precedence over flat `filter[...]` params when present.\n\nJSON structure before encoding:\n```json\n{\n  \"conjunction\": \"and\",\n  \"children\": [\n    {\"type\": \"condition\", \"condition\": {\"column\": \"allocation_status.is\", \"operator\": \"is\", \"value\": \"partial\"}},\n    {\"type\": \"group\", \"group\": {\"conjunction\": \"or\", \"children\": [...]}}\n  ]\n}\n```\n\n## Response extras\nOn top of Laravel's standard paginator JSON, the response includes:\n- `unfiltered_total` — total bill count with all filters cleared (for the export modal's \"All records\" label)\n- `summary` — tenant-currency stat card totals across the **filtered** result set: `total_billed_tenant`, `total_allocated_tenant`, `total_unallocated_tenant`, `bill_count`\n\nEach bill includes `documents_count` (number of attached source documents) and `document_filenames` (their file names). Sortable by `documents_count`. Filter with `filter[documents_count]` (e.g. `filter[documents_count.is]=0` for bills with no source document) or `filter[document_filename]` to match a source document's file name."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/list?page=1&per_page=10&sort=-created_at","host":["{{baseUrl}}"],"path":["api","bills","list"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field; prefix with - for descending. Allowed: id, invoice_number, invoice_date, supplier_name, supplier_id, link_type, link_reference, proration_strategy, currency_code, currency_rate, line_count, subtotal, tax_total, grand_total, allocated_amount, unallocated_amount, allocation_status, documents_count, created_at, updated_at. Default: -created_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 12,\n      \"invoice_number\": \"INV-2026-0042\",\n      \"invoice_date\": \"2026-05-28\",\n      \"due_date\": \"2026-06-27\",\n      \"payment_status\": \"unpaid\",\n      \"payment_due_status\": \"not_due\",\n      \"days_until_due\": 30,\n      \"supplier_id\": 3,\n      \"supplier_name\": \"Global Freight Co\",\n      \"supplier_type\": \"service\",\n      \"link_type\": \"purchase_order\",\n      \"link_id\": 42,\n      \"link_reference\": \"PO-00042\",\n      \"link_url_path\": \"/orders/purchase-orders/42\",\n      \"proration_strategy\": \"cost_based\",\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"tenant_currency_code\": \"USD\",\n      \"line_count\": 2,\n      \"subtotal\": 750,\n      \"tax_total\": 0,\n      \"grand_total\": 750,\n      \"subtotal_tenant\": 750,\n      \"allocated_amount\": 500,\n      \"allocated_amount_tenant\": 500,\n      \"unallocated_amount\": 250,\n      \"allocation_status\": \"partial\",\n      \"cost_categories\": [\n        {\n          \"id\": 1,\n          \"name\": \"Freight\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"Duty\"\n        }\n      ],\n      \"has_accounting_transaction\": true,\n      \"source\": \"ocr\",\n      \"ocr_extraction_id\": 7,\n      \"settlement_reference_count\": 0,\n      \"documents_count\": 2,\n      \"document_filenames\": [\n        \"proforma.pdf\",\n        \"freight-invoice.pdf\"\n      ],\n      \"created_at\": \"2026-05-28T14:22:10.000000Z\",\n      \"updated_at\": \"2026-06-02T09:15:44.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/bills/list?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/bills/list?page=5\",\n  \"links\": [],\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/bills/list?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/bills/list\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 47,\n  \"unfiltered_total\": 143,\n  \"summary\": {\n    \"total_billed_tenant\": 38450.25,\n    \"total_allocated_tenant\": 31200.1,\n    \"total_unallocated_tenant\": 7250.15,\n    \"bill_count\": 47\n  }\n}"}]},{"name":"Export Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/list/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","bills","list","export"],"query":[{"key":"format","value":"xlsx","description":"File format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"summary (one row per bill, default) or line_items (one row per bill line)","disabled":true},{"key":"scope","value":"filtered","description":"all | filtered (default) | current_page | selected","disabled":true}]},"description":"Export landed cost bills as XLSX or CSV. The response is a binary file download, not JSON.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).\n\n## Parameters\n- `format` — `xlsx` (default) or `csv`\n- `content_mode` — `summary` (one row per bill, default) or `line_items` (one row per bill line; bill columns repeat per line, line-item columns are appended)\n- `scope` — which bills to export:\n  - `all` — every bill, ignoring active filters\n  - `filtered` — bills matching the current `filter[...]` / `filter_groups` params (default)\n  - `current_page` — only the current page (honors `page` / `per_page` / `sort`)\n  - `selected` — only the bills in `ids`\n- `columns` — comma-separated bill column keys to include (preserves order). Omit for all columns. Available keys: `id`, `invoice_number`, `invoice_date`, `supplier_name`, `link_type`, `link_reference`, `proration_strategy`, `currency_code`, `currency_rate`, `line_count`, `subtotal`, `tax_total`, `grand_total`, `allocated_amount`, `unallocated_amount`, `allocation_status`, `cost_categories`, `has_accounting_transaction`, `source`, `settlement_reference_count`, `created_at`, `updated_at`\n- `ids` — comma-separated bill IDs (required when `scope=selected`)\n\nAll `filter[...]`, `filter_groups`, and `sort` params from the List Bills endpoint also apply when `scope=filtered`.\n\nIn `line_items` mode these line columns are always appended: Line Description, Line Cost Category, Line Qty, Line Amount, Line Extended, Line Tax Rate.\n\n## Response\nBinary file download:\n- XLSX: `Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- CSV: `Content-Type: text/csv`\n- Filename: `landed-cost-bills-{timestamp}.{ext}` (summary) or `landed-cost-bills-detail-{timestamp}.{ext}` (line_items)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/list/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","bills","list","export"],"query":[{"key":"format","value":"xlsx","description":"File format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"summary (one row per bill, default) or line_items (one row per bill line)","disabled":true},{"key":"scope","value":"filtered","description":"all | filtered (default) | current_page | selected","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX/CSV file)"}]},{"name":"Get Bill","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a bill with its supplier, lines, allocations, and related purchase order / warehouse transfer data.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Acme Supplier Ltd\",\n    \"supplier_type\": \"service\",\n    \"invoice_number\": \"INV-2024-001\",\n    \"invoice_date\": \"2024-01-15\",\n    \"due_date\": \"2024-02-14\",\n    \"due_date_source\": \"derived\",\n    \"payment_due_status\": \"not_due\",\n    \"days_until_due\": 30,\n    \"link_type\": \"purchase_order\",\n    \"link_id\": 42,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"cost_based\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"description\": \"Product A - Qty 100\",\n        \"quantity\": 100,\n        \"amount\": 5.5,\n        \"extended_amount\": 550,\n        \"nominal_code_id\": 10,\n        \"tax_rate_id\": null,\n        \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n        \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n      }\n    ],\n    \"descriptions\": [\n      \"Product A - Qty 100\"\n    ],\n    \"total_amount\": 550,\n    \"totals\": {\n      \"line_count\": 1,\n      \"amount\": 550,\n      \"tax\": 0,\n      \"grand_total\": 550\n    },\n    \"allocations\": [\n      {\n        \"id\": 1,\n        \"allocation_amount\": 550,\n        \"allocation_percentage\": 100,\n        \"proration_strategy\": \"cost_based\",\n        \"purchase_order_line_id\": 55,\n        \"warehouse_transfer_line_id\": null,\n        \"purchase_order_line\": {\n          \"id\": 55,\n          \"description\": \"Product A\",\n          \"quantity\": 100,\n          \"product\": {\n            \"id\": 10,\n            \"name\": \"Product A\",\n            \"sku\": \"PROD-A-001\"\n          }\n        },\n        \"warehouse_transfer_line\": null\n      }\n    ],\n    \"ledger\": {\n      \"enabled\": true,\n      \"entries\": [\n        {\n          \"id\": 9954,\n          \"status\": \"draft\",\n          \"reference\": \"BILL-319\",\n          \"total\": 250,\n          \"posted_at\": null,\n          \"effective_at\": \"2026-03-30T00:00:00+00:00\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Update Bill","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing bill's header data and allocations.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- invoice_number (required): Updated invoice number\n- invoice_date (required): Updated invoice date (YYYY-MM-DD)\n- supplier_id (required): Supplier ID — must be a service-type supplier\n- currency_id (optional): Currency ID\n- currency_rate (optional): Exchange rate\n- proration_strategy (optional): One of cost_based, quantity_based, manual\n- allocations (optional): Updated allocations array (replaces existing)","body":{"mode":"raw","raw":"{\n  \"invoice_number\": \"INV-2024-001-REVISED\",\n  \"invoice_date\": \"2024-01-20\",\n  \"supplier_id\": 3,\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"cost_based\",\n  \"allocations\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"allocation_amount\": 550\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Acme Supplier Ltd\",\n    \"supplier_type\": \"service\",\n    \"invoice_number\": \"INV-2024-001-REVISED\",\n    \"invoice_date\": \"2024-01-20\",\n    \"link_type\": \"purchase_order\",\n    \"link_id\": 42,\n    \"total_amount\": 550\n  }\n}"}]},{"name":"Delete Bill","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a bill.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/bills/{id}","host":["{{baseUrl}}"],"path":["api","bills",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bill deleted successfully\"\n}"}]},{"name":"Get Bill Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/line-items","host":["{{baseUrl}}"],"path":["api","bills",":id","line-items"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Lean lines + allocations payload for the expandable row in the landed cost bills list view.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the bill's lines (with tax rate and cost category), its allocations (with the target PO/WT line, parent document ID, and product), and aggregate totals.\n\n`target_type` is `purchase_order_line` or `warehouse_transfer_line`; `target_document_id` is the parent purchase order / warehouse transfer ID.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/line-items","host":["{{baseUrl}}"],"path":["api","bills",":id","line-items"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"description\": \"Ocean freight — container MSKU1234567\",\n        \"quantity\": 1,\n        \"amount\": 500,\n        \"extended_amount\": 500,\n        \"tax_rate_id\": null,\n        \"tax_rate_name\": null,\n        \"tax_rate\": null,\n        \"cost_category\": {\n          \"id\": 1,\n          \"name\": \"Freight\"\n        }\n      },\n      {\n        \"id\": 32,\n        \"description\": \"Import duty\",\n        \"quantity\": 1,\n        \"amount\": 250,\n        \"extended_amount\": 250,\n        \"tax_rate_id\": 2,\n        \"tax_rate_name\": \"GST 10%\",\n        \"tax_rate\": 10,\n        \"cost_category\": {\n          \"id\": 2,\n          \"name\": \"Duty\"\n        }\n      }\n    ],\n    \"allocations\": [\n      {\n        \"id\": 55,\n        \"purchase_order_line_id\": 101,\n        \"warehouse_transfer_line_id\": null,\n        \"target_type\": \"purchase_order_line\",\n        \"target_document_id\": 42,\n        \"product_id\": 10,\n        \"product_sku\": \"PROD-A-001\",\n        \"product_name\": \"Product A\",\n        \"description\": \"Product A\",\n        \"allocation_amount\": 500,\n        \"allocation_amount_tenant\": 500,\n        \"proration_strategy\": \"cost_based\"\n      }\n    ],\n    \"totals\": {\n      \"subtotal\": 750,\n      \"allocated\": 500,\n      \"allocated_tenant\": 500\n    }\n  }\n}"}]},{"name":"Get Bill Payees","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/payees","host":["{{baseUrl}}"],"path":["api","bills","payees"]},"description":"Lists the distinct suppliers actually referenced by existing bills, ordered by name (may include grandfathered goods suppliers on migrated bills). Backs the Supplier filter on the bills list page.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFor the payee picker on landed-cost / cost-entry create/edit forms, use GET /api/bills/eligible-payees instead.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/payees","host":["{{baseUrl}}"],"path":["api","bills","payees"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Freight Co.\",\n      \"company_name\": \"Freight Co. LLC\",\n      \"email\": \"billing@freightco.test\",\n      \"type\": \"service\",\n      \"type_label\": \"Service Provider\"\n    },\n    {\n      \"id\": 8,\n      \"name\": \"DHL Express\",\n      \"company_name\": \"DHL\",\n      \"email\": \"ap@dhl.test\",\n      \"type\": \"service\",\n      \"type_label\": \"Service Provider\"\n    }\n  ]\n}"}]},{"name":"Get Eligible Bill Payees","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/eligible-payees","host":["{{baseUrl}}"],"path":["api","bills","eligible-payees"]},"description":"Lists all suppliers eligible to be billed: non-archived, service-type suppliers, ordered by name. Backs the payee picker on the landed-cost and cost-entry create/edit forms (where new bills are created).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nDistinct from GET /api/bills/payees, which backs the bills-list Supplier filter and returns only suppliers that already appear on a bill (and may include grandfathered goods suppliers).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/eligible-payees","host":["{{baseUrl}}"],"path":["api","bills","eligible-payees"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Freight Co.\",\n      \"company_name\": \"Freight Co. LLC\",\n      \"email\": \"billing@freightco.test\",\n      \"type\": \"service\",\n      \"type_label\": \"Service Provider\"\n    },\n    {\n      \"id\": 8,\n      \"name\": \"DHL Express\",\n      \"company_name\": \"DHL\",\n      \"email\": \"ap@dhl.test\",\n      \"type\": \"service\",\n      \"type_label\": \"Service Provider\"\n    }\n  ]\n}"}]},{"name":"Create Bill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills","host":["{{baseUrl}}"],"path":["api","bills"]},"description":"Creates a standalone bill. Note: This endpoint is currently not used in practice — bills are typically created via purchase order or warehouse transfer nested routes.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- supplier_id (required): Supplier ID — must be a service-type supplier\n- invoice_number (required, unique): Invoice reference number\n- invoice_date (required): Invoice date (YYYY-MM-DD)\n- link_type (required): Type of link — 'purchase_order' or 'warehouse_transfer'\n- link_id (required): ID of the linked record\n- currency_id (optional): Currency ID\n- currency_rate (optional): Exchange rate\n- proration_strategy (required): One of cost_based, quantity_based, manual\n- lines (required): Array of bill lines\n  - lines.*.description: Line description\n  - lines.*.quantity: Quantity\n  - lines.*.amount: Unit amount\n  - lines.*.nominal_code_id (optional, nullable): The line's debit (expense/clearing) account that faces Accounts Payable. Optional — omit it or send null and NO default is frozen onto the line at save; the GL debit is resolved at posting time from the bill's link_type (landed-cost bills linked to a purchase order / warehouse transfer / inbound shipment capitalize to the configured inventory_control account).\n  - lines.*.tax_rate_id: Tax rate ID (optional)\n- allocations (optional): Array of allocation objects\n  - allocations.*.purchase_order_line_id: PO line ID\n  - allocations.*.allocation_amount: Amount to allocate","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 3,\n  \"invoice_number\": \"INV-2024-001\",\n  \"invoice_date\": \"2024-01-15\",\n  \"link_type\": \"purchase_order\",\n  \"link_id\": 42,\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"cost_based\",\n  \"lines\": [\n    {\n      \"description\": \"Product A - 100 units\",\n      \"quantity\": 100,\n      \"amount\": 5.5,\n      \"nominal_code_id\": 10,\n      \"tax_rate_id\": null\n    }\n  ],\n  \"allocations\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"allocation_amount\": 550\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills","host":["{{baseUrl}}"],"path":["api","bills"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Acme Supplier Ltd\",\n    \"supplier_type\": \"service\",\n    \"invoice_number\": \"INV-2024-001\",\n    \"invoice_date\": \"2024-01-15\",\n    \"link_type\": \"purchase_order\",\n    \"link_id\": 42,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"cost_based\",\n    \"total_amount\": 550,\n    \"totals\": {\n      \"line_count\": 1,\n      \"amount\": 550,\n      \"tax\": 0,\n      \"grand_total\": 550\n    }\n  }\n}"}]},{"name":"Bulk Delete Bills","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/bills","host":["{{baseUrl}}"],"path":["api","bills"]},"description":"Bulk delete landed cost bills by explicit IDs or by list filters (\"all filtered\" scope).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide ONE of:\n- `ids` — array of bill IDs (each must exist)\n- `filters` — object of List Bills filter params (same keys as the `filter[...]` query params, plus optional `filter_groups`); the matching bill IDs are resolved server-side\n- `apply_to_all: true` — delete ALL bills (optionally narrowed by `filters`); without this flag an empty/missing `filters` object deletes nothing\n\nBehavior:\n- **25 bills or fewer** → deleted synchronously; response includes per-bill results\n- **More than 25 bills** → dispatched as a Tracked Job (`Delete Landed Cost Bills: N bill(s)`); response returns `tracked_job_log_id` for the tracked job log endpoints\n- Deleting a bill removes its lines/allocations and triggers FIFO landed-cost recalculation on affected layers\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/bills","host":["{{baseUrl}}"],"path":["api","bills"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": 3,\n    \"failed\": []\n  },\n  \"message\": \"Deleted 3 bill(s)\"\n}"}]},{"name":"Update Bill Lines","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}/lines","host":["{{baseUrl}}"],"path":["api","bills",":id","lines"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Batch updates the lines of a bill. Replaces existing lines with the provided collection.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- lines (required): Array of bill line objects\n  - lines.*.id (optional): Existing line ID (omit for new lines)\n  - lines.*.description: Line description\n  - lines.*.quantity: Quantity\n  - lines.*.amount: Unit amount\n  - lines.*.nominal_code_id (optional, nullable): The line's debit (expense/clearing) account. Send an explicit null to CLEAR the nominal code on the line (it persists as null). OMIT the field entirely to leave an existing line's code untouched. No inventory_control default is frozen onto the line — when the line carries no code, the GL debit is resolved at posting time from the bill's link_type (landed-cost bills linked to a purchase order / warehouse transfer / inbound shipment capitalize to the configured inventory_control account).\n  - lines.*.tax_rate_id: Tax rate ID (optional)","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"id\": 1,\n      \"description\": \"Product A - Updated\",\n      \"quantity\": 100,\n      \"amount\": 6,\n      \"nominal_code_id\": 10,\n      \"tax_rate_id\": null\n    },\n    {\n      \"description\": \"New Line Item\",\n      \"quantity\": 50,\n      \"amount\": 3,\n      \"nominal_code_id\": 10\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/bills/{id}/lines","host":["{{baseUrl}}"],"path":["api","bills",":id","lines"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Acme Supplier Ltd\",\n    \"supplier_type\": \"service\",\n    \"invoice_number\": \"INV-2024-001\",\n    \"invoice_date\": \"2024-01-15\",\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"description\": \"Product A - Updated\",\n        \"quantity\": 100,\n        \"amount\": 6,\n        \"extended_amount\": 600\n      },\n      {\n        \"id\": 2,\n        \"description\": \"New Line Item\",\n        \"quantity\": 50,\n        \"amount\": 3,\n        \"extended_amount\": 150\n      }\n    ],\n    \"total_amount\": 750,\n    \"totals\": {\n      \"line_count\": 2,\n      \"amount\": 750,\n      \"tax\": 0,\n      \"grand_total\": 750\n    }\n  }\n}"}]},{"name":"Get Available Lines for Manual Allocation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/available-lines","host":["{{baseUrl}}"],"path":["api","bills",":id","available-lines"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns purchase order and warehouse transfer lines that are available for manual cost allocation to this bill. Includes pre-calculated allocation amounts.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/available-lines","host":["{{baseUrl}}"],"path":["api","bills",":id","available-lines"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"type\": \"purchase_order_line\",\n      \"description\": \"Product A\",\n      \"quantity\": 100,\n      \"unit_cost\": 5.5,\n      \"total_cost\": 550,\n      \"suggested_allocation_amount\": 550,\n      \"product\": {\n        \"id\": 10,\n        \"name\": \"Product A\",\n        \"sku\": \"PROD-A-001\"\n      }\n    }\n  ]\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","bills",":id","generate-accounting-transaction"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Generates (or regenerates) the accounting posting for a landed-cost bill. On tenants using the v2 ledger, this synchronously rebuilds the bill's ledger journal entry; on legacy tenants it creates the accounting transaction. Safe to call repeatedly — an existing entry is superseded, not duplicated.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills/{id}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","bills",":id","generate-accounting-transaction"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ledger_entries\": [\n      {\n        \"id\": 9954,\n        \"status\": \"draft\",\n        \"reference\": \"BILL-319\",\n        \"total\": 250,\n        \"posted_at\": null,\n        \"effective_at\": \"2026-03-30T00:00:00+00:00\"\n      }\n    ]\n  },\n  \"message\": \"Ledger entry generated successfully.\"\n}"}]},{"name":"Create Cost Entries from Bill Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{bill}/cost-entries","host":["{{baseUrl}}"],"path":["api","bills",":bill","cost-entries"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]},"description":"Create one cost entry per selected bill line, each tracking a chosen amount of that line for profitability analysis. This is the `scope: \"lines\"` mode of the endpoint; to track the whole remaining bill as a single entry, see \"Create Cost Entry from Bill\" (same URL, `scope: \"entire\"`).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach allocation amount may be the full line total or a partial amount, but cannot exceed what is still untracked on that line (check with the lines-availability endpoints first). When more than one line is sent, each entry's description is the `name` with the line's description appended. Entries inherit the bill's supplier, currency, exchange rate, and invoice number, are dated with the bill's invoice date, and start in `pending_allocation` status.\n\nRequest fields:\n- `scope` (required) - `lines` for this mode.\n- `name` (required, max 255) - Base description for the cost entries.\n- `cost_entry_type_id` (optional) - ID of a cost entry type (see `GET /api/cost-entry-types`); applies to every entry created. Omit or send null to leave them untyped.\n- `notes` (optional, max 1000) - Free-form notes.\n- `line_allocations` (required in this mode, min 1) - Array of allocations:\n  - `line_allocations[].bill_line_id` (required, integer) - ID of a line on this bill.\n  - `line_allocations[].amount` (required, numeric, min 0.01) - Amount of that line to track.\n\nReturns 422 when a line does not belong to the bill or an amount exceeds the line's untracked remainder.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).","body":{"mode":"raw","raw":"{\n  \"scope\": \"lines\",\n  \"name\": \"June shipment landed costs\",\n  \"cost_entry_type_id\": 3,\n  \"notes\": \"Split by freight and duty lines\",\n  \"line_allocations\": [\n    {\n      \"bill_line_id\": 31,\n      \"amount\": 1850\n    },\n    {\n      \"bill_line_id\": 32,\n      \"amount\": 650\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills/{bill}/cost-entries","host":["{{baseUrl}}"],"path":["api","bills",":bill","cost-entries"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Created 2 cost entry(s) from bill\",\n    \"cost_entries\": [\n      {\n        \"id\": 89,\n        \"supplier_id\": 12,\n        \"supplier_name\": \"Pacific Freight Forwarding\",\n        \"reference_number\": \"INV-20441\",\n        \"description\": \"June shipment landed costs - Ocean freight (container MSKU1234567)\",\n        \"cost_date\": \"2026-06-15\",\n        \"amount\": 1850,\n        \"amount_in_tenant_currency\": 1850,\n        \"currency_id\": 1,\n        \"currency_code\": \"USD\",\n        \"currency_rate\": 1,\n        \"nominal_code_id\": null,\n        \"nominal_code_name\": null,\n        \"cost_entry_type_id\": 3,\n        \"cost_entry_type\": {\n          \"id\": 3,\n          \"name\": \"Freight\"\n        },\n        \"status\": \"pending_allocation\",\n        \"bill_id\": 15,\n        \"bill_line_id\": 31,\n        \"source_type\": \"bill_line\",\n        \"source_description\": \"Bill #INV-20441 - Line: Ocean freight (container MSKU1234567)\",\n        \"source_link_type\": null,\n        \"source_id\": null,\n        \"source_label\": null,\n        \"source_period\": null,\n        \"reconciliation\": null,\n        \"created_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"updated_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"totals\": {\n          \"allocated\": 0,\n          \"unallocated\": 1850,\n          \"is_fully_allocated\": false\n        }\n      },\n      {\n        \"id\": 90,\n        \"supplier_id\": 12,\n        \"supplier_name\": \"Pacific Freight Forwarding\",\n        \"reference_number\": \"INV-20441\",\n        \"description\": \"June shipment landed costs - Import duty (HS 8516.71)\",\n        \"cost_date\": \"2026-06-15\",\n        \"amount\": 650,\n        \"amount_in_tenant_currency\": 650,\n        \"currency_id\": 1,\n        \"currency_code\": \"USD\",\n        \"currency_rate\": 1,\n        \"nominal_code_id\": null,\n        \"nominal_code_name\": null,\n        \"cost_entry_type_id\": 3,\n        \"cost_entry_type\": {\n          \"id\": 3,\n          \"name\": \"Freight\"\n        },\n        \"status\": \"pending_allocation\",\n        \"bill_id\": 15,\n        \"bill_line_id\": 32,\n        \"source_type\": \"bill_line\",\n        \"source_description\": \"Bill #INV-20441 - Line: Import duty (HS 8516.71)\",\n        \"source_link_type\": null,\n        \"source_id\": null,\n        \"source_label\": null,\n        \"source_period\": null,\n        \"reconciliation\": null,\n        \"created_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"updated_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"totals\": {\n          \"allocated\": 0,\n          \"unallocated\": 650,\n          \"is_fully_allocated\": false\n        }\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Bill Profitability Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{bill}/profitability-summary","host":["{{baseUrl}}"],"path":["api","bills",":bill","profitability-summary"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]},"description":"Get a profitability-tracking summary for a bill: how much of the bill's total has been turned into cost entries, how much remains untracked, and the full list of cost entries created from the bill.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- `bill_total` - The bill's grand total.\n- `tracked_for_profitability` - Sum of the cost entries created from this bill, in the account's base currency.\n- `not_tracked` - Remainder of the bill total not yet tracked.\n- `tracking_percentage` - Tracked amount as a percentage of the bill total (rounded to 2 decimals).\n- `cost_entries` - Every cost entry created from this bill or its lines, including its allocation status and allocated/unallocated totals.\n\nUse this to decide whether more of the bill can still be tracked via `POST /api/bills/:bill/cost-entries`.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{bill}/profitability-summary","host":["{{baseUrl}}"],"path":["api","bills",":bill","profitability-summary"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"bill_id\": 15,\n    \"bill_total\": 2500,\n    \"tracked_for_profitability\": 1850,\n    \"not_tracked\": 650,\n    \"tracking_percentage\": 74,\n    \"cost_entries\": [\n      {\n        \"id\": 89,\n        \"supplier_id\": 12,\n        \"supplier_name\": \"Pacific Freight Forwarding\",\n        \"reference_number\": \"INV-20441\",\n        \"description\": \"June shipment landed costs - Ocean freight (container MSKU1234567)\",\n        \"cost_date\": \"2026-06-15\",\n        \"amount\": 1850,\n        \"amount_in_tenant_currency\": 1850,\n        \"currency_id\": 1,\n        \"currency_code\": \"USD\",\n        \"currency_rate\": 1,\n        \"nominal_code_id\": null,\n        \"nominal_code_name\": null,\n        \"cost_entry_type_id\": 3,\n        \"cost_entry_type\": {\n          \"id\": 3,\n          \"name\": \"Freight\"\n        },\n        \"status\": \"pending_allocation\",\n        \"bill_id\": 15,\n        \"bill_line_id\": 31,\n        \"source_type\": \"bill_line\",\n        \"source_description\": \"Bill #INV-20441 - Line: Ocean freight (container MSKU1234567)\",\n        \"source_link_type\": null,\n        \"source_id\": null,\n        \"source_label\": null,\n        \"source_period\": null,\n        \"reconciliation\": null,\n        \"created_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"updated_at\": \"2026-07-07T14:02:11.000000Z\",\n        \"totals\": {\n          \"allocated\": 0,\n          \"unallocated\": 1850,\n          \"is_fully_allocated\": false\n        }\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Bill Lines Availability","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{bill}/lines-availability","host":["{{baseUrl}}"],"path":["api","bills",":bill","lines-availability"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]},"description":"List every line on a bill with how much of each line has already been tracked as cost entries and how much is still available, plus bill-level totals.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- `bill_total`, `total_tracked`, `total_available` - Bill-level totals; `total_available` is the bill total minus the sum tracked across all lines.\n- `lines[]` - Per line: `line_total`, `already_tracked`, `available_for_tracking`, and `tracking_percentage` (0 for zero-total lines).\n\nUse this before calling `POST /api/bills/:bill/cost-entries` with `scope: \"lines\"` to choose valid allocation amounts.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{bill}/lines-availability","host":["{{baseUrl}}"],"path":["api","bills",":bill","lines-availability"],"variable":[{"key":"bill","value":"15","description":"Bill ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"bill_id\": 15,\n    \"bill_total\": 2500,\n    \"total_tracked\": 1850,\n    \"total_available\": 650,\n    \"lines\": [\n      {\n        \"bill_line_id\": 31,\n        \"description\": \"Ocean freight (container MSKU1234567)\",\n        \"line_total\": 1850,\n        \"already_tracked\": 1850,\n        \"available_for_tracking\": 0,\n        \"tracking_percentage\": 100\n      },\n      {\n        \"bill_line_id\": 32,\n        \"description\": \"Import duty (HS 8516.71)\",\n        \"line_total\": 650,\n        \"already_tracked\": 0,\n        \"available_for_tracking\": 650,\n        \"tracking_percentage\": 0\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Bill Line Availability","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{bill}/lines/{billLine}/availability","host":["{{baseUrl}}"],"path":["api","bills",":bill","lines",":billLine","availability"],"variable":[{"key":"bill","value":"15","description":"Bill ID"},{"key":"billLine","value":"32","description":"Bill line ID (must belong to the bill)"}]},"description":"Get the tracking availability for a single bill line: its total, how much has already been tracked as cost entries, and how much is still available.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- `line_total` - The line's extended total.\n- `already_tracked` - Amount of this line already covered by cost entries.\n- `available_for_tracking` - Remainder that can still be tracked.\n- `tracking_percentage` - Tracked amount as a percentage of the line total (0 for zero-total lines).\n\nReturns 404 when the line exists but does not belong to the given bill.\n\nUse this before calling `POST /api/bills/:bill/cost-entries` with `scope: \"lines\"` to validate a single allocation amount.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{bill}/lines/{billLine}/availability","host":["{{baseUrl}}"],"path":["api","bills",":bill","lines",":billLine","availability"],"variable":[{"key":"bill","value":"15","description":"Bill ID"},{"key":"billLine","value":"32","description":"Bill line ID (must belong to the bill)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"bill_line_id\": 32,\n    \"description\": \"Import duty (HS 8516.71)\",\n    \"line_total\": 650,\n    \"already_tracked\": 250,\n    \"available_for_tracking\": 400,\n    \"tracking_percentage\": 38.46\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Bill Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/payments","host":["{{baseUrl}}"],"path":["api","bills",":id","payments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Lists all payments recorded against a landed-cost bill (supplier payments applied to the bill). Payments two-way sync with the connected accounting provider.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/payments","host":["{{baseUrl}}"],"path":["api","bills",":id","payments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"amount\": 250,\n      \"cost\": 0,\n      \"payment_date\": \"2026-07-09T00:00:00.000000Z\",\n      \"payment_type\": {\n        \"id\": 3,\n        \"name\": \"Bank Transfer\"\n      },\n      \"external_reference\": \"WIRE-99182\",\n      \"type\": null,\n      \"currency_code\": \"USD\",\n      \"sales_credit_allocation\": null\n    }\n  ]\n}"}]},{"name":"Add Bill Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}/payments","host":["{{baseUrl}}"],"path":["api","bills",":id","payments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Records a payment against a landed-cost bill and recalculates the bill's paid status. The payment is pushed to the connected accounting provider (Xero / QuickBooks Online).\n\nFields:\n- payment_date (optional, date, defaults to today)\n- payment_type_id (required, an existing payment type)\n- amount (required, numeric, must be greater than 0)\n- external_reference (optional, string, max 255)\n- currency_id (optional; defaults to the bill's currency)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"payment_date\": \"2026-07-09\",\n  \"payment_type_id\": 3,\n  \"amount\": 250,\n  \"external_reference\": \"WIRE-99182\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills/{id}/payments","host":["{{baseUrl}}"],"path":["api","bills",":id","payments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"amount\": 250,\n    \"cost\": 0,\n    \"payment_date\": \"2026-07-09T00:00:00.000000Z\",\n    \"payment_type\": {\n      \"id\": 3,\n      \"name\": \"Bank Transfer\"\n    },\n    \"external_reference\": \"WIRE-99182\",\n    \"type\": null,\n    \"currency_code\": \"USD\",\n    \"sales_credit_allocation\": null\n  },\n  \"message\": \"Bill payment created successfully\"\n}"}]},{"name":"Update Bill Payment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}/payments/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","payments",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Updates an existing bill payment and recalculates the bill's paid status. The change is re-synced to the connected accounting provider.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"payment_date\": \"2026-07-09\",\n  \"amount\": 300,\n  \"external_reference\": \"WIRE-99182\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/bills/{id}/payments/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","payments",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"amount\": 300,\n    \"cost\": 0,\n    \"payment_date\": \"2026-07-09T00:00:00.000000Z\",\n    \"payment_type\": {\n      \"id\": 3,\n      \"name\": \"Bank Transfer\"\n    },\n    \"external_reference\": \"WIRE-99182\",\n    \"type\": null,\n    \"currency_code\": \"USD\",\n    \"sales_credit_allocation\": null\n  },\n  \"message\": \"Bill payment updated successfully\"\n}"}]},{"name":"Delete Bill Payment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/payments/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","payments",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Deletes a bill payment and recalculates the bill's paid status. The corresponding provider payment is voided/removed on the connected accounting provider.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/bills/{id}/payments/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","payments",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bill payment deleted successfully\"\n}"}]},{"name":"Get Bill Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","bills",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated audit history for a bill — who changed what and when, including field-level before/after values.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","bills",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 481,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Bill\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"source\": \"manual\",\n        \"old\": {\n          \"invoice_number\": \"INV-2024-000\"\n        },\n        \"attributes\": {\n          \"invoice_number\": \"INV-2024-001\"\n        }\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2026-07-09T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"List Bill Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/notes","host":["{{baseUrl}}"],"path":["api","bills",":id","notes"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated notes attached to a bill, newest first.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/notes","host":["{{baseUrl}}"],"path":["api","bills",":id","notes"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"note\": \"Awaiting supplier credit note.\",\n      \"is_pinned\": false,\n      \"link_type\": \"bill\",\n      \"link_id\": 1,\n      \"user\": {\n        \"id\": 2,\n        \"name\": \"Jane Doe\"\n      },\n      \"created_at\": \"2026-07-09T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Add Bill Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}/notes","host":["{{baseUrl}}"],"path":["api","bills",":id","notes"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Adds a note to a bill.\n\nFields:\n- note (required, string)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"note\": \"Awaiting supplier credit note.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills/{id}/notes","host":["{{baseUrl}}"],"path":["api","bills",":id","notes"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"note\": \"Awaiting supplier credit note.\",\n    \"is_pinned\": false,\n    \"link_type\": \"bill\",\n    \"link_id\": 1,\n    \"user\": {\n      \"id\": 2,\n      \"name\": \"Jane Doe\"\n    },\n    \"created_at\": \"2026-07-09T10:00:00.000000Z\"\n  },\n  \"message\": \"Note created successfully\"\n}"}]},{"name":"Toggle Bill Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/notes/{id2}/toggle-pin","host":["{{baseUrl}}"],"path":["api","bills",":id","notes",":id2","toggle-pin"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Pins or unpins a bill note (toggles its pinned state).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/bills/{id}/notes/{id2}/toggle-pin","host":["{{baseUrl}}"],"path":["api","bills",":id","notes",":id2","toggle-pin"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"note\": \"Awaiting supplier credit note.\",\n    \"is_pinned\": true,\n    \"link_type\": \"bill\",\n    \"link_id\": 1\n  },\n  \"message\": \"Note pinned\"\n}"}]},{"name":"Delete Bill Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/notes/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","notes",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Deletes a bill note.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/bills/{id}/notes/{id2}","host":["{{baseUrl}}"],"path":["api","bills",":id","notes",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Note deleted successfully\"\n}"}]},{"name":"Sync Bill Tags","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/bills/{id}/tags","host":["{{baseUrl}}"],"path":["api","bills",":id","tags"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Replaces the full set of tags on a bill with the provided list.\n\nFields:\n- tags (required, array of strings, each max 64 chars)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"tags\": [\n    \"freight\",\n    \"customs\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/bills/{id}/tags","host":["{{baseUrl}}"],"path":["api","bills",":id","tags"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tags\": [\n      \"freight\",\n      \"customs\"\n    ]\n  },\n  \"message\": \"Bill tags updated successfully\"\n}"}]},{"name":"List Bill Documents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{id}/documents","host":["{{baseUrl}}"],"path":["api","bills",":id","documents"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Lists the scanned source invoice documents linked to a bill.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/bills/{id}/documents","host":["{{baseUrl}}"],"path":["api","bills",":id","documents"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90,\n      \"file_name\": \"supplier-invoice-INV-2024-001.pdf\",\n      \"status\": \"confirmed\",\n      \"page_count\": 2,\n      \"created_at\": \"2026-07-09T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Reset Bill Due Date to Term","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/bills/{bill}/reset-due-date","host":["{{baseUrl}}"],"path":["api","bills",":bill","reset-due-date"],"variable":[{"key":"bill","value":"","description":"The bill ID."}]},"description":"Discards a manually-overridden due date on a landed-cost bill and re-derives it from the bill's effective payment term (its own term, else the linked purchase order's term, else the supplier default). The response's `due_date_source` returns to `derived` (or `none` when no term is resolvable).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/bills/{bill}/reset-due-date","host":["{{baseUrl}}"],"path":["api","bills",":bill","reset-due-date"],"variable":[{"key":"bill","value":"","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 321,\n    \"supplier_id\": 88,\n    \"supplier_name\": \"DHL Forwarding\",\n    \"invoice_number\": \"DHL-88213\",\n    \"invoice_date\": \"2026-07-13\",\n    \"due_date\": \"2026-07-28\",\n    \"due_date_source\": \"derived\",\n    \"payment_term_id\": 4,\n    \"payment_term_name\": \"Net 15\",\n    \"payment_term_snapshot\": {\n      \"payment_term_id\": 4,\n      \"name\": \"Net 15\",\n      \"net_days\": 15,\n      \"due_date_type\": \"from_invoice_date\",\n      \"discount_percentage\": 0,\n      \"discount_days\": null,\n      \"captured_at\": \"2026-07-13T12:00:00+00:00\"\n    },\n    \"term_diverges_from_po\": true,\n    \"discount_due_date\": null,\n    \"discount_amount\": null,\n    \"discount_available\": false,\n    \"payment_due_status\": \"not_due\",\n    \"days_until_due\": 15,\n    \"link_type\": \"purchase_order\",\n    \"link_id\": 707\n  }\n}"}]}]},{"name":"Amortization Schedules","item":[{"name":"Get Amortization Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]},"description":"Get a single amortization schedule, including its full list of periods and the allocation configuration that is applied when each period is processed.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAn amortization schedule spreads a cost entry's unallocated amount over a series of periods (for example, an annual customs bond premium spread over four quarterly periods). Schedules are created with `POST /api/cost-entries/:costEntry/amortization-schedule` (documented under Cost Entries).\n\nResponse fields:\n- `start_date` / `end_date` - The date range covered by the schedule; `end_date` is the last period's end date.\n- `total_periods`, `frequency` (`daily`, `weekly`, `monthly`, `quarterly`, `annually`) and `method` (`straight_line`, `front_loaded`, `back_loaded`) - How the amount is distributed over time.\n- `total_amount` / `amount_per_period` - The amount being amortized and the per-period amount (the final period absorbs any rounding difference).\n- `is_fully_processed`, `pending_periods_count`, `processed_periods_count` - Processing progress.\n- `allocation_config` - Where each period's amount is allocated when processed: `allocatable_type` is one of `product`, `brand`, `supplier`, `sales_channel`; `allocatable_id` is the target entity's ID; `proration_strategy` is one of `revenue_based`, `cost_based`, `weight_based`, `volume_based`, `quantity_based`, `specific_line`, `manual`. `allocatable_name` is null on this endpoint; use the status endpoint to resolve the target's display name.\n- `periods` - Every period with its number, date range, amount, and processed state.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"cost_entry_id\": 42,\n    \"start_date\": \"2026-01-01\",\n    \"end_date\": \"2026-12-31\",\n    \"total_periods\": 4,\n    \"frequency\": \"quarterly\",\n    \"method\": \"straight_line\",\n    \"total_amount\": 2400,\n    \"amount_per_period\": 600,\n    \"is_fully_processed\": false,\n    \"pending_periods_count\": 2,\n    \"processed_periods_count\": 2,\n    \"allocation_config\": {\n      \"allocatable_type\": \"product\",\n      \"allocatable_id\": 123,\n      \"allocatable_name\": null,\n      \"proration_strategy\": \"specific_line\"\n    },\n    \"created_at\": \"2026-01-05T09:30:00.000000Z\",\n    \"updated_at\": \"2026-07-01T02:15:03.000000Z\",\n    \"periods\": [\n      {\n        \"id\": 101,\n        \"amortization_schedule_id\": 7,\n        \"period_number\": 1,\n        \"period_start\": \"2026-01-01\",\n        \"period_end\": \"2026-03-31\",\n        \"amount\": 600,\n        \"is_processed\": true,\n        \"processed_at\": \"2026-04-01T02:15:07.000000Z\",\n        \"created_at\": \"2026-01-05T09:30:00.000000Z\",\n        \"updated_at\": \"2026-04-01T02:15:07.000000Z\"\n      },\n      {\n        \"id\": 102,\n        \"amortization_schedule_id\": 7,\n        \"period_number\": 2,\n        \"period_start\": \"2026-04-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 600,\n        \"is_processed\": true,\n        \"processed_at\": \"2026-07-01T02:15:03.000000Z\",\n        \"created_at\": \"2026-01-05T09:30:00.000000Z\",\n        \"updated_at\": \"2026-07-01T02:15:03.000000Z\"\n      },\n      {\n        \"id\": 103,\n        \"amortization_schedule_id\": 7,\n        \"period_number\": 3,\n        \"period_start\": \"2026-07-01\",\n        \"period_end\": \"2026-09-30\",\n        \"amount\": 600,\n        \"is_processed\": false,\n        \"processed_at\": null,\n        \"created_at\": \"2026-01-05T09:30:00.000000Z\",\n        \"updated_at\": \"2026-01-05T09:30:00.000000Z\"\n      },\n      {\n        \"id\": 104,\n        \"amortization_schedule_id\": 7,\n        \"period_number\": 4,\n        \"period_start\": \"2026-10-01\",\n        \"period_end\": \"2026-12-31\",\n        \"amount\": 600,\n        \"is_processed\": false,\n        \"processed_at\": null,\n        \"created_at\": \"2026-01-05T09:30:00.000000Z\",\n        \"updated_at\": \"2026-01-05T09:30:00.000000Z\"\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Amortization Schedule","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]},"description":"Delete an amortization schedule together with all of its periods.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThere is no guard against deleting a schedule that has already-processed periods: any cost allocations that were created by processing this schedule's periods are also deleted, effectively reversing those allocations. The whole operation runs in a single transaction, and the parent cost entry's allocation status is recalculated afterwards (for example back to `pending_allocation` if nothing else is allocated against it).\n\nThe cost entry itself is not deleted - a new schedule can be created for it afterwards with `POST /api/cost-entries/:costEntry/amortization-schedule`.\n\nReturns 200 with a confirmation message (not 204).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Amortization schedule deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Amortization Schedule Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}/status","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule","status"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]},"description":"Get a compact processing-progress summary for an amortization schedule - useful for dashboards and polling without fetching the full period list.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- `total_periods`, `processed_periods`, `pending_periods`, `is_fully_processed` - Progress counters.\n- `total_amount` / `amount_per_period` - The amount being amortized.\n- `next_period` - The next unprocessed period (`period_number`, `period_start`, `period_end`, `amount`, and `is_due`, which is true once the period's end date has passed). Null when every period has been processed.\n- `allocation_config` - The stored allocation target: `allocatable_type` (`product`, `brand`, `supplier`, `sales_channel`), `allocatable_id`, `allocatable_name` (the target's name or SKU), and `proration_strategy`.\n\nSchedules are created with `POST /api/cost-entries/:costEntry/amortization-schedule` (documented under Cost Entries).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}/status","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule","status"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"cost_entry_id\": 42,\n    \"total_periods\": 4,\n    \"processed_periods\": 2,\n    \"pending_periods\": 2,\n    \"is_fully_processed\": false,\n    \"total_amount\": 2400,\n    \"amount_per_period\": 600,\n    \"next_period\": {\n      \"period_number\": 3,\n      \"period_start\": \"2026-07-01\",\n      \"period_end\": \"2026-09-30\",\n      \"amount\": 600,\n      \"is_due\": false\n    },\n    \"allocation_config\": {\n      \"allocatable_type\": \"product\",\n      \"allocatable_id\": 123,\n      \"allocatable_name\": \"Espresso Machine E61 Group Head\",\n      \"proration_strategy\": \"specific_line\"\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Process Amortization Schedule Due Periods","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}/process","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule","process"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]},"description":"Process every due period on an amortization schedule. A period is due when it is unprocessed and its end date is on or before `as_of_date` (defaults to today). Processing each period creates the cost allocations defined by the schedule's stored allocation configuration and updates the parent cost entry's allocation status.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis endpoint runs synchronously - allocations are created before the response returns, and `processed_count` reports how many periods were processed (0 when nothing is due). A daily background task also processes due periods automatically for schedules that have a stored allocation configuration, so this endpoint is mainly for processing ahead of that run or applying a one-off target override.\n\nRequest fields (all optional):\n- `as_of_date` - Process periods due as of this date instead of today (date, e.g. `2026-07-07`).\n- `allocatable_type` + `allocatable_id` - Override the stored allocation target for this run only. `allocatable_type` is one of `product`, `brand`, `supplier`, `sales_channel`; `allocatable_id` is required whenever `allocatable_type` is sent. When omitted, the schedule's stored configuration is used (`used_stored_config: true` in the response).\n- `proration_strategy` - Only used with an override target; one of `revenue_based`, `cost_based`, `weight_based`, `volume_based`, `quantity_based`, `specific_line`, `manual` (defaults to `specific_line`).\n\nReturns 422 when an override target does not exist, or when no override is sent and the schedule has no stored allocation configuration.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).","body":{"mode":"raw","raw":"{\n  \"as_of_date\": \"2026-07-07\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amortization-schedules/{amortizationSchedule}/process","host":["{{baseUrl}}"],"path":["api","amortization-schedules",":amortizationSchedule","process"],"variable":[{"key":"amortizationSchedule","value":"7","description":"Amortization schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processed_count\": 2,\n    \"used_stored_config\": true\n  },\n  \"message\": \"Processed 2 periods\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Configuration","item":[{"name":"Create Financial Alert","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts","host":["{{baseUrl}}"],"path":["api","financial-alerts"]},"description":"Creates a new financial alert record. Typically, alerts are auto-generated by the process endpoint, but this allows manual creation.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"financial_alert_classification_id\": 2,\n  \"note\": \"Pricing error — needs review\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-alerts","host":["{{baseUrl}}"],"path":["api","financial-alerts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 16,\n    \"financial_alert_classification_id\": 2,\n    \"note\": \"Pricing error — needs review\"\n  },\n  \"message\": \"Financial alert updated successfully\"\n}"}]},{"name":"Update Financial Alert","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/{financial_alert}","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financial_alert"],"variable":[{"key":"financial_alert","value":"15","description":"The financial alert ID."}]},"description":"Updates a financial alert's classification and/or note.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"financial_alert_classification_id\": 3,\n  \"note\": \"Investigated — supplier overcharge confirmed\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/{financial_alert}","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financial_alert"],"variable":[{"key":"financial_alert","value":"15","description":"The financial alert ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"classification\": \"Supplier Issue\",\n    \"classification_id\": 3,\n    \"note\": \"Investigated — supplier overcharge confirmed\"\n  },\n  \"message\": \"Financial alert updated successfully\"\n}"}]},{"name":"Delete Financial Alert","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/{financial_alert}","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financial_alert"],"variable":[{"key":"financial_alert","value":"15","description":"The financial alert ID."}]},"description":"Deletes a financial alert record.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/financial-alerts/{financial_alert}","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financial_alert"],"variable":[{"key":"financial_alert","value":"15","description":"The financial alert ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"financial alerts deleted successfully\"\n}"}]},{"name":"Archive Alert","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/{financialAlert}/archive","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financialAlert","archive"],"variable":[{"key":"financialAlert","value":"15","description":"The financial alert ID."}]},"description":"Archives (resolves) a single financial alert, recording the archiving user and timestamp.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/{financialAlert}/archive","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financialAlert","archive"],"variable":[{"key":"financialAlert","value":"15","description":"The financial alert ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"archived_at\": \"2025-04-23T10:00:00.000000Z\",\n    \"archived_by_user\": \"Admin User\",\n    \"is_resolved\": \"true\"\n  },\n  \"message\": \"Financial alert archived successfully\"\n}"}]},{"name":"Unarchive Alert","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/{financialAlert}/unarchive","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financialAlert","unarchive"],"variable":[{"key":"financialAlert","value":"15","description":"The financial alert ID."}]},"description":"Unarchives (re-opens) a previously archived financial alert.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/{financialAlert}/unarchive","host":["{{baseUrl}}"],"path":["api","financial-alerts",":financialAlert","unarchive"],"variable":[{"key":"financialAlert","value":"15","description":"The financial alert ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"archived_at\": null,\n    \"archived_by_user\": null,\n    \"is_resolved\": \"false\"\n  },\n  \"message\": \"Financial alert unarchived successfully\"\n}"}]},{"name":"Bulk Archive Alerts","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/archive","host":["{{baseUrl}}"],"path":["api","financial-alerts","archive"]},"description":"Archives multiple financial alerts at once.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of financial alert IDs to archive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    15,\n    16,\n    17\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/archive","host":["{{baseUrl}}"],"path":["api","financial-alerts","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"financial alerts bulk archived successfully\"\n}"}]},{"name":"Bulk Unarchive Alerts","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/unarchive","host":["{{baseUrl}}"],"path":["api","financial-alerts","unarchive"]},"description":"Unarchives multiple financial alerts at once.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of financial alert IDs to unarchive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    15,\n    16,\n    17\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/unarchive","host":["{{baseUrl}}"],"path":["api","financial-alerts","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"financial alerts bulk unarchived successfully\"\n}"}]},{"name":"Bulk Update Alerts","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/update","host":["{{baseUrl}}"],"path":["api","financial-alerts","update"]},"description":"Bulk updates the classification and/or note for multiple financial alerts.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of financial alert IDs to update\n- classification (optional): Classification ID to assign\n- note (optional): Note to set on all specified alerts","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    15,\n    16,\n    17\n  ],\n  \"classification\": 2,\n  \"note\": \"Reviewed and classified\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/financial-alerts/update","host":["{{baseUrl}}"],"path":["api","financial-alerts","update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"financial alerts bulk updated successfully\"\n}"}]},{"name":"Preview Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/import/preview","host":["{{baseUrl}}"],"path":["api","financial-alerts","import","preview"]},"description":"Previews an import file for financial alerts before committing. Returns a summary of what will be imported and any errors.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\nFields:\n- file (required): The CSV/Excel file to preview","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-alerts/import/preview","host":["{{baseUrl}}"],"path":["api","financial-alerts","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_rows\": 50,\n    \"valid_rows\": 48,\n    \"errors\": [\n      {\n        \"row\": 12,\n        \"message\": \"Invalid SKU: SKU-999\"\n      }\n    ],\n    \"preview\": [\n      {\n        \"sku\": \"WIDGET-A\",\n        \"alert_type\": \"LOSS\",\n        \"profit\": -35\n      }\n    ]\n  }\n}"}]},{"name":"Import Alerts","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/import","host":["{{baseUrl}}"],"path":["api","financial-alerts","import"]},"description":"Imports financial alerts from a CSV/Excel file.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\nFields:\n- file (required): The CSV/Excel file to import","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-alerts/import","host":["{{baseUrl}}"],"path":["api","financial-alerts","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import completed successfully\",\n  \"data\": {\n    \"imported\": 48,\n    \"skipped\": 2\n  }\n}"}]},{"name":"Get Dashboard Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/dashboard","host":["{{baseUrl}}"],"path":["api","financial-alerts","dashboard"]},"description":"Returns a summary of archived (resolved) financial alerts grouped by alert type. Used for the financial alerts dashboard overview.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-alerts/dashboard","host":["{{baseUrl}}"],"path":["api","financial-alerts","dashboard"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"alert_type\": \"LOSS\",\n      \"count\": 24\n    },\n    {\n      \"alert_type\": \"LOW_MARGIN\",\n      \"count\": 37\n    }\n  ]\n}"}]},{"name":"Get Report Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/reports","host":["{{baseUrl}}"],"path":["api","financial-alerts","reports"]},"description":"Returns reporting data for financial alerts including classification breakdown and resolution breakdown. Used for the reports page.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-alerts/reports","host":["{{baseUrl}}"],"path":["api","financial-alerts","reports"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"classification_breakdown\": [\n      {\n        \"count\": 15,\n        \"classification\": \"Pricing Error\"\n      },\n      {\n        \"count\": 9,\n        \"classification\": \"Supplier Issue\"\n      },\n      {\n        \"count\": 3,\n        \"classification\": null\n      }\n    ],\n    \"resolution_breakdown\": [\n      {\n        \"count\": 42,\n        \"resolution\": \"Resolved\"\n      },\n      {\n        \"count\": 18,\n        \"resolution\": \"Unresolved\"\n      }\n    ]\n  }\n}"}]},{"name":"Process Alerts","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/process","host":["{{baseUrl}}"],"path":["api","financial-alerts","process"]},"description":"Triggers the financial alert processing job, which scans all sales order lines for low margin or loss conditions and creates/deletes alerts accordingly.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-alerts/process","host":["{{baseUrl}}"],"path":["api","financial-alerts","process"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Financial alerts processed successfully\"\n}"}]},{"name":"List Classifications","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications"]},"description":"Returns all financial alert classification categories. Classifications are used to tag alerts with a reason or resolution type (e.g., Pricing Error, Supplier Issue).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Pricing Error\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Supplier Issue\"\n    },\n    {\n      \"id\": 3,\n      \"name\": \"One-off Promotion\"\n    },\n    {\n      \"id\": 4,\n      \"name\": \"Expected Loss\"\n    }\n  ]\n}"}]},{"name":"Create Classification","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications"]},"description":"Creates a new financial alert classification category.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Name of the classification","body":{"mode":"raw","raw":"{\n  \"name\": \"Competitor Pricing\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Competitor Pricing\"\n  },\n  \"message\": \"financial alert classification created successfully\"\n}"}]},{"name":"Get Classification","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]},"description":"Returns a single financial alert classification by ID.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Pricing Error\"\n  }\n}"}]},{"name":"Update Classification","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]},"description":"Updates a financial alert classification name.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Pricing / Margin Error\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Pricing / Margin Error\"\n  }\n}"}]},{"name":"Delete Classification","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]},"description":"Deletes a financial alert classification.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/financial-alerts/classifications/{classification}","host":["{{baseUrl}}"],"path":["api","financial-alerts","classifications",":classification"],"variable":[{"key":"classification","value":"1","description":"The classification ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"financial alert classification deleted successfully\"\n}"}]},{"name":"List Nominal Codes (Dropdown)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/list","host":["{{baseUrl}}"],"path":["api","nominal-codes","list"]},"description":"Returns a lightweight list of all nominal codes (id, code, name, type), ordered by code. Intended for dropdown/combo-box lookups.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nEvery nominal code record is returned independently — no deduplication. Integration re-syncs (e.g. QuickBooks Online) can legitimately create multiple rows sharing the same code + name; each appears as its own entry with its own id.\n\nPass used_by_transactions=1 to restrict the list to nominal codes referenced by at least one accounting transaction line — used by the Accounting Transactions filter dropdown so unused codes don't appear as dead filter options.\n\nArchived nominal codes are excluded automatically.\n\nThe type field is the account type (Revenue, Expense, Asset, Liability, Equity, Bank, Current) and can be used for client-side filtering (e.g. asset-only dropdowns).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/nominal-codes/list","host":["{{baseUrl}}"],"path":["api","nominal-codes","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"1200\",\n      \"name\": \"Inventory Asset\",\n      \"type\": \"Current\"\n    },\n    {\n      \"id\": 4,\n      \"code\": \"4000\",\n      \"name\": \"Sales Revenue\",\n      \"type\": \"Revenue\"\n    },\n    {\n      \"id\": 2,\n      \"code\": \"5000\",\n      \"name\": \"Cost of Goods Sold\",\n      \"type\": \"Expense\"\n    },\n    {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\",\n      \"type\": \"Expense\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Show Nominal Code","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"1","description":"Nominal code ID"}]},"description":"Show a single nominal code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"1","description":"Nominal code ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"code\": \"4000\",\n    \"name\": \"Sales Revenue\",\n    \"type\": \"Revenue\",\n    \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2024-02-01T11:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Nominal Code","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"10","description":"Nominal code ID"}]},"description":"Update an existing nominal code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional on update):\n- `code` (string) — unique code; must not conflict with other records\n- `name` (string, max:255)\n- `type` — Allowed values: Revenue, Expense, Asset, Liability, Equity, Bank, Current, Inventory, Fixed, Directcosts, Currliab, Termliab, Sales\n\n**Requires permission:** `nominal_codes.update`","body":{"mode":"raw","raw":"{\n  \"code\": \"7001\",\n  \"name\": \"Digital Marketing Expense\",\n  \"type\": \"Expense\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"10","description":"Nominal code ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"code\": \"7001\",\n    \"name\": \"Digital Marketing Expense\",\n    \"type\": \"Expense\",\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"nominal code 7001 was updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Nominal Code","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"10","description":"Nominal code ID"}]},"description":"Delete a nominal code. Fails if the code is used in mapping settings or linked to sales order lines.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `nominal_codes.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominal_code}","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominal_code"],"variable":[{"key":"nominal_code","value":"10","description":"Nominal code ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"nominal code Digital Marketing Expense was deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Create Nominal Code","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes","host":["{{baseUrl}}"],"path":["api","nominal-codes"]},"description":"Create a new nominal code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `code` (required, string) — unique identifier code for the nominal code\n- `name` (required, string, max:255) — display name\n- `type` (required) — account type. Allowed values: Revenue, Expense, Asset, Liability, Equity, Bank, Current, Inventory, Fixed, Directcosts, Currliab, Termliab, Sales\n\n**Requires permission:** `nominal_codes.create`","body":{"mode":"raw","raw":"{\n  \"code\": \"7000\",\n  \"name\": \"Marketing Expense\",\n  \"type\": \"Expense\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/nominal-codes","host":["{{baseUrl}}"],"path":["api","nominal-codes"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"code\": \"7000\",\n    \"name\": \"Marketing Expense\",\n    \"type\": \"Expense\",\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"nominal code was created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Nominal Codes","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes","host":["{{baseUrl}}"],"path":["api","nominal-codes"]},"description":"Bulk delete multiple nominal codes by ID.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of nominal code IDs to delete\n\n**Requires permission:** `nominal_codes.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/nominal-codes","host":["{{baseUrl}}"],"path":["api","nominal-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 nominal codes deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Archive Nominal Code","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominalCode}/archive","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominalCode","archive"],"variable":[{"key":"nominalCode","value":"10","description":"Nominal code ID"}]},"description":"Archive a single nominal code.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `nominal_codes.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominalCode}/archive","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominalCode","archive"],"variable":[{"key":"nominalCode","value":"10","description":"Nominal code ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"code\": \"7001\",\n    \"name\": \"Digital Marketing Expense\",\n    \"type\": \"Expense\",\n    \"archived_at\": \"2024-03-10T11:00:00.000000Z\"\n  },\n  \"message\": \"nominal code 7001 was archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Nominal Code","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominalCode}/unarchived","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominalCode","unarchived"],"variable":[{"key":"nominalCode","value":"10","description":"Nominal code ID"}]},"description":"Unarchive a single nominal code.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `nominal_codes.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/nominal-codes/{nominalCode}/unarchived","host":["{{baseUrl}}"],"path":["api","nominal-codes",":nominalCode","unarchived"],"variable":[{"key":"nominalCode","value":"10","description":"Nominal code ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"code\": \"7001\",\n    \"name\": \"Digital Marketing Expense\",\n    \"type\": \"Expense\",\n    \"archived_at\": null\n  },\n  \"message\": \"nominal code 7001 was unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Nominal Codes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes/archive","host":["{{baseUrl}}"],"path":["api","nominal-codes","archive"]},"description":"Bulk archive multiple nominal codes by ID.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of nominal code IDs to archive\n\n**Requires permission:** `nominal_codes.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8,\n    9,\n    10\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/nominal-codes/archive","host":["{{baseUrl}}"],"path":["api","nominal-codes","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 nominal codes archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive Nominal Codes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes/unarchive","host":["{{baseUrl}}"],"path":["api","nominal-codes","unarchive"]},"description":"Bulk unarchive multiple nominal codes by ID.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of nominal code IDs to unarchive\n\n**Requires permission:** `nominal_codes.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8,\n    9,\n    10\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/nominal-codes/unarchive","host":["{{baseUrl}}"],"path":["api","nominal-codes","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 nominal codes unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Check Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes/deletable","host":["{{baseUrl}}"],"path":["api","nominal-codes","deletable"]},"description":"Check which nominal codes can be deleted. A code cannot be deleted if it is linked to sales order lines or used in nominal code mapping settings.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required, array) — nominal code IDs to check; must exist in nominal_codes table\n\n**Requires permission:** `nominal_codes.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    10\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/nominal-codes/deletable","host":["{{baseUrl}}"],"path":["api","nominal-codes","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"4000\",\n      \"name\": \"Sales Revenue\",\n      \"deletable\": false,\n      \"reason\": {\n        \"mappingNominalCodes\": \"Nominal code 'Sales Revenue' is used in accounting mapping settings.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"code\": \"5000\",\n      \"name\": \"Cost of Goods Sold\",\n      \"deletable\": false,\n      \"reason\": {\n        \"salesOrderLines\": \"1 sales order line is currently using nominal code(Cost of Goods Sold).\"\n      }\n    },\n    {\n      \"id\": 10,\n      \"code\": \"7001\",\n      \"name\": \"Digital Marketing Expense\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Check Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/nominal-codes/archivable","host":["{{baseUrl}}"],"path":["api","nominal-codes","archivable"]},"description":"Check which nominal codes can be archived. A code cannot be archived if it is currently used in the nominal code mapping settings.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required, array) — nominal code IDs to check; must exist in nominal_codes table\n\n**Requires permission:** `nominal_codes.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    10\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/nominal-codes/archivable","host":["{{baseUrl}}"],"path":["api","nominal-codes","archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"4000\",\n      \"name\": \"Sales Revenue\",\n      \"archivable\": false,\n      \"reason\": {\n        \"mappingNominalCodes\": \"Nominal code 'Sales Revenue' is currently used in a mapping.\"\n      }\n    },\n    {\n      \"id\": 10,\n      \"code\": \"7001\",\n      \"name\": \"Digital Marketing Expense\",\n      \"archivable\": true,\n      \"reason\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Preview Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/import/preview","host":["{{baseUrl}}"],"path":["api","nominal-codes","import","preview"]},"description":"Preview a nominal code import file before committing. Returns parsed rows and any validation errors.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `nominal_codes.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/nominal-codes/import/preview","host":["{{baseUrl}}"],"path":["api","nominal-codes","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"code\": \"8000\",\n        \"name\": \"Other Income\",\n        \"type\": \"Revenue\",\n        \"valid\": true,\n        \"errors\": []\n      }\n    ],\n    \"total\": 1,\n    \"valid\": 1,\n    \"invalid\": 0\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Import Nominal Codes","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/nominal-codes/import","host":["{{baseUrl}}"],"path":["api","nominal-codes","import"]},"description":"Import nominal codes from a CSV or Excel file.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `nominal_codes.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/nominal-codes/import","host":["{{baseUrl}}"],"path":["api","nominal-codes","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 3,\n    \"skipped\": 0,\n    \"errors\": []\n  },\n  \"message\": \"Import completed successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"List Payment Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types?archived=0","host":["{{baseUrl}}"],"path":["api","payment-types"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true}]},"description":"List all payment types. Returns a flat collection (not paginated).\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- archived: 0 for active types, 1 for archived types. Default: 0\n\nNote: The Amazon and Shopify payment types are system-managed and cannot be deleted."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/payment-types?archived=0","host":["{{baseUrl}}"],"path":["api","payment-types"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Credit Card\",\n      \"accounting_integration_id\": null,\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Amazon\",\n      \"accounting_integration_id\": null,\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Shopify\",\n      \"accounting_integration_id\": null,\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    }\n  ]\n}"}]},{"name":"Create Payment Type","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types","host":["{{baseUrl}}"],"path":["api","payment-types"]},"description":"Create a new payment type.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Unique payment type name, max 255 characters\n\n**Requires permission:** `payment_types.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Wire Transfer\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/payment-types","host":["{{baseUrl}}"],"path":["api","payment-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"payment type has been successfully created\",\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Wire Transfer\",\n    \"accounting_integration_id\": null,\n    \"created_at\": \"2024-03-15T14:30:00Z\",\n    \"updated_at\": \"2024-03-15T14:30:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Delete Payment Types","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types","host":["{{baseUrl}}"],"path":["api","payment-types"]},"description":"Bulk delete multiple payment types by ID.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/payment-types","host":["{{baseUrl}}"],"path":["api","payment-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 payment types deleted successfully\"\n}"}]},{"name":"Get Payment Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"1","description":"Payment type ID"}]},"description":"Retrieve a single payment type by ID.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"1","description":"Payment type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Credit Card\",\n    \"accounting_integration_id\": null,\n    \"created_at\": \"2024-01-01T00:00:00Z\",\n    \"updated_at\": \"2024-01-01T00:00:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Payment Type","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"10","description":"Payment type ID"}]},"description":"Update an existing payment type.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (optional): New payment type name, must be unique, max 255 characters\n\n**Requires permission:** `payment_types.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Bank Wire Transfer\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"10","description":"Payment type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"payment type Bank Wire Transfer has been successfully updated\",\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Bank Wire Transfer\",\n    \"accounting_integration_id\": null,\n    \"created_at\": \"2024-03-15T14:30:00Z\",\n    \"updated_at\": \"2024-03-15T15:00:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Delete Payment Type","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"10","description":"Payment type ID"}]},"description":"Delete a payment type. Amazon and Shopify payment types cannot be deleted (system-managed).\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/payment-types/{payment_type}","host":["{{baseUrl}}"],"path":["api","payment-types",":payment_type"],"variable":[{"key":"payment_type","value":"10","description":"Payment type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"payment type Bank Wire Transfer has been successfully deleted\"\n}"}]},{"name":"Check Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types/deletable","host":["{{baseUrl}}"],"path":["api","payment-types","deletable"]},"description":"Check which payment types can be deleted. Returns deletability status per ID.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of integer payment type IDs to check\n\n**Requires permission:** `payment_types.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    10\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/payment-types/deletable","host":["{{baseUrl}}"],"path":["api","payment-types","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Credit Card\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Amazon\",\n      \"deletable\": false,\n      \"reason\": \"In use by 150 payments\"\n    },\n    {\n      \"id\": 10,\n      \"name\": \"Wire Transfer\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Update Accounting Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types/accounting-mapping","host":["{{baseUrl}}"],"path":["api","payment-types","accounting-mapping"]},"description":"Bulk update accounting integration mappings for payment types. Maps each payment type to an external accounting system account.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- payment_types (required): Array of payment type mapping objects\n- payment_types[].id (required): Payment type ID\n- payment_types[].accounting_integration_id (required): External accounting account ID\n- payment_types[].accounting_integration_type (required): Accounting integration type (e.g., QuickBooks)\n\n**Requires permission:** `payment_types.update`","body":{"mode":"raw","raw":"{\n  \"payment_types\": [\n    {\n      \"id\": 1,\n      \"accounting_integration_id\": \"acc_123\",\n      \"accounting_integration_type\": \"QuickBooks\"\n    },\n    {\n      \"id\": 2,\n      \"accounting_integration_id\": \"acc_456\",\n      \"accounting_integration_type\": \"QuickBooks\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/payment-types/accounting-mapping","host":["{{baseUrl}}"],"path":["api","payment-types","accounting-mapping"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true\n}"}]},{"name":"Archive Payment Type","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types/{paymentType}/archive","host":["{{baseUrl}}"],"path":["api","payment-types",":paymentType","archive"],"variable":[{"key":"paymentType","value":"10","description":"Payment type ID"}]},"description":"Archive a single payment type.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-types/{paymentType}/archive","host":["{{baseUrl}}"],"path":["api","payment-types",":paymentType","archive"],"variable":[{"key":"paymentType","value":"10","description":"Payment type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"payment type Wire Transfer has been archived\",\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Wire Transfer\",\n    \"archived_at\": \"2024-03-16T10:00:00Z\"\n  }\n}"}]},{"name":"Unarchive Payment Type","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/payment-types/{paymentType}/unarchived","host":["{{baseUrl}}"],"path":["api","payment-types",":paymentType","unarchived"],"variable":[{"key":"paymentType","value":"10","description":"Payment type ID"}]},"description":"Unarchive a single payment type.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-types/{paymentType}/unarchived","host":["{{baseUrl}}"],"path":["api","payment-types",":paymentType","unarchived"],"variable":[{"key":"paymentType","value":"10","description":"Payment type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"payment type Wire Transfer has been unarchived\",\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Wire Transfer\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Payment Types","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types/archive","host":["{{baseUrl}}"],"path":["api","payment-types","archive"]},"description":"Bulk archive multiple payment types.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-types/archive","host":["{{baseUrl}}"],"path":["api","payment-types","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 payment types archived successfully\"\n}"}]},{"name":"Bulk Unarchive Payment Types","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-types/unarchive","host":["{{baseUrl}}"],"path":["api","payment-types","unarchive"]},"description":"Bulk unarchive multiple payment types.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_types.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-types/unarchive","host":["{{baseUrl}}"],"path":["api","payment-types","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 payment types unarchived successfully\"\n}"}]},{"name":"Create Incoterm","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/incoterms","host":["{{baseUrl}}"],"path":["api","incoterms"]},"description":"Manage the Incoterms 2020 reference table. Standard ICC rows carry structured trade-term metadata used to drive buyer/seller responsibility panels on purchase and sales orders.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nFields:\n- `code` (required, string, max 10, unique) — e.g. `DAP`, `FOB`. Locked for standard ICC rows.\n- `name` (string) — human label, e.g. `Delivered at Place`.\n- `description` (string)\n- `transport_mode` (enum) — `any` | `sea_inland`.\n- `family` (enum) — `E` | `F` | `C` | `D` (ICC term family).\n- `seller_pays_main_carriage` (boolean)\n- `export_cleared_by` (enum) — `seller` | `buyer`.\n- `import_cleared_by` (enum) — `seller` | `buyer`.\n- `seller_insurance` (enum) — `none` | `clause_a` | `clause_c`.\n- `risk_transfer_point` (string) — plain-English point where risk passes.\n- `sort_order` (integer)\n- `is_deprecated` (boolean) — flags retired rules (e.g. DAT).\n\n`is_standard` is server-maintained and NOT accepted in the request body.\n\nAuthentication: Requires Bearer token. Permission: `incoterms.create` / `incoterms.update`.","body":{"mode":"raw","raw":"{\n  \"code\": \"DAP\",\n  \"name\": \"Delivered at Place\",\n  \"description\": \"Seller delivers goods to the named destination. Buyer handles import customs clearance and duties.\",\n  \"transport_mode\": \"any\",\n  \"family\": \"D\",\n  \"seller_pays_main_carriage\": true,\n  \"export_cleared_by\": \"seller\",\n  \"import_cleared_by\": \"buyer\",\n  \"seller_insurance\": \"none\",\n  \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n  \"sort_order\": 12,\n  \"is_deprecated\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/incoterms","host":["{{baseUrl}}"],"path":["api","incoterms"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"incoterm created successfully.\",\n  \"data\": {\n    \"code\": \"DAP\",\n    \"id\": 12,\n    \"name\": \"Delivered at Place\",\n    \"description\": \"Seller delivers goods to the named destination. Buyer handles import customs clearance and duties.\",\n    \"transport_mode\": \"any\",\n    \"family\": \"D\",\n    \"seller_pays_main_carriage\": true,\n    \"export_cleared_by\": \"seller\",\n    \"import_cleared_by\": \"buyer\",\n    \"seller_insurance\": \"none\",\n    \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n    \"is_standard\": true,\n    \"is_deprecated\": false,\n    \"created_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"updated_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"archived_at\": null,\n    \"sort_order\": 4\n  }\n}"}]},{"name":"Bulk Delete Incoterms","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/incoterms","host":["{{baseUrl}}"],"path":["api","incoterms"]},"description":"Deletes multiple incoterms in a single request.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of incoterm IDs to delete\n\n**Requires permission:** `incoterms.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/incoterms","host":["{{baseUrl}}"],"path":["api","incoterms"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 incoterms deleted successfully.\"\n}"}]},{"name":"Get Incoterm","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]},"description":"Returns the details of a single incoterm.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"code\": \"EXW\",\n    \"id\": 1,\n    \"name\": \"Ex Works\",\n    \"description\": \"Ex Works — seller makes goods available at their premises.\",\n    \"transport_mode\": \"any\",\n    \"family\": \"E\",\n    \"seller_pays_main_carriage\": true,\n    \"export_cleared_by\": \"seller\",\n    \"import_cleared_by\": \"buyer\",\n    \"seller_insurance\": \"none\",\n    \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n    \"is_standard\": true,\n    \"is_deprecated\": false,\n    \"created_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"updated_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"archived_at\": null,\n    \"sort_order\": 4\n  }\n}"}]},{"name":"Update Incoterm","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]},"description":"Manage the Incoterms 2020 reference table. Standard ICC rows carry structured trade-term metadata used to drive buyer/seller responsibility panels on purchase and sales orders.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nFields:\n- `code` (required, string, max 10, unique) — e.g. `DAP`, `FOB`. Locked for standard ICC rows.\n- `name` (string) — human label, e.g. `Delivered at Place`.\n- `description` (string)\n- `transport_mode` (enum) — `any` | `sea_inland`.\n- `family` (enum) — `E` | `F` | `C` | `D` (ICC term family).\n- `seller_pays_main_carriage` (boolean)\n- `export_cleared_by` (enum) — `seller` | `buyer`.\n- `import_cleared_by` (enum) — `seller` | `buyer`.\n- `seller_insurance` (enum) — `none` | `clause_a` | `clause_c`.\n- `risk_transfer_point` (string) — plain-English point where risk passes.\n- `sort_order` (integer)\n- `is_deprecated` (boolean) — flags retired rules (e.g. DAT).\n\n`is_standard` is server-maintained and NOT accepted in the request body.\n\nAuthentication: Requires Bearer token. Permission: `incoterms.create` / `incoterms.update`.","body":{"mode":"raw","raw":"{\n  \"code\": \"EXW\",\n  \"name\": \"Ex Works\",\n  \"description\": \"Ex Works — seller makes goods available at their premises.\",\n  \"transport_mode\": \"any\",\n  \"family\": \"E\",\n  \"seller_pays_main_carriage\": false,\n  \"export_cleared_by\": \"buyer\",\n  \"import_cleared_by\": \"buyer\",\n  \"seller_insurance\": \"none\",\n  \"risk_transfer_point\": \"At the seller's premises, once goods are placed at the buyer's disposal.\",\n  \"sort_order\": 1,\n  \"is_deprecated\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"incoterm EXW updated successfully.\",\n  \"data\": {\n    \"code\": \"EXW\",\n    \"id\": 1,\n    \"name\": \"Ex Works\",\n    \"description\": \"Ex Works — seller makes goods available at their premises.\",\n    \"transport_mode\": \"any\",\n    \"family\": \"E\",\n    \"seller_pays_main_carriage\": true,\n    \"export_cleared_by\": \"seller\",\n    \"import_cleared_by\": \"buyer\",\n    \"seller_insurance\": \"none\",\n    \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n    \"is_standard\": true,\n    \"is_deprecated\": false,\n    \"created_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"updated_at\": \"2026-07-13T10:30:00.000000Z\",\n    \"archived_at\": null,\n    \"sort_order\": 4\n  }\n}"}]},{"name":"Delete Incoterm","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]},"description":"Deletes the specified incoterm. Will fail if the incoterm is linked to existing purchase orders or other records.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token\n\n**Requires permission:** `incoterms.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"incoterm EXW deleted successfully.\"\n}"}]},{"name":"Archive Incoterm","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}/archive","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm","archive"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]},"description":"Archives the specified incoterm by setting its archived_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\n**Requires permission:** `incoterms.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}/archive","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm","archive"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"incoterm EXW archived successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"code\": \"EXW\",\n    \"archived_at\": \"2024-01-15T10:30:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive Incoterm","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}/unarchived","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm","unarchived"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]},"description":"Restores (unarchives) the specified incoterm by clearing its archived_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\n**Requires permission:** `incoterms.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/incoterms/{incoterm}/unarchived","host":["{{baseUrl}}"],"path":["api","incoterms",":incoterm","unarchived"],"variable":[{"key":"incoterm","value":"1","description":"Incoterm ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"incoterm EXW unarchived successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"code\": \"EXW\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Check Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/incoterms/deletable","host":["{{baseUrl}}"],"path":["api","incoterms","deletable"]},"description":"Checks whether the specified incoterms can be deleted. Returns deletability status and reason if an incoterm is in use.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required, min:1): Array of incoterm IDs to check\n\n**Requires permission:** `incoterms.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/incoterms/deletable","host":["{{baseUrl}}"],"path":["api","incoterms","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"EXW\",\n      \"deletable\": false,\n      \"reason\": \"Linked to existing purchase orders\"\n    },\n    {\n      \"id\": 2,\n      \"code\": \"FOB\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 3,\n      \"code\": \"CIF\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Bulk Archive Incoterms","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/incoterms/archive","host":["{{baseUrl}}"],"path":["api","incoterms","archive"]},"description":"Archives multiple incoterms.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of incoterm IDs to archive\n\n**Requires permission:** `incoterms.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/incoterms/archive","host":["{{baseUrl}}"],"path":["api","incoterms","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 incoterms archived successfully.\"\n}"}]},{"name":"Bulk Unarchive Incoterms","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/incoterms/unarchive","host":["{{baseUrl}}"],"path":["api","incoterms","unarchive"]},"description":"Restores (unarchives) multiple incoterms.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of incoterm IDs to unarchive\n\n**Requires permission:** `incoterms.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/incoterms/unarchive","host":["{{baseUrl}}"],"path":["api","incoterms","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 incoterms unarchived successfully.\"\n}"}]}]},{"name":"Financial Line Types","item":[{"name":"List Financial Line Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]},"description":"Returns all financial line types for the organization.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 1,\n    \"name\": \"Freight\",\n    \"classification\": \"cost\",\n    \"allocate_to_products\": true,\n    \"proration_strategy\": \"weight_based\",\n    \"nominal_code_id\": null,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-01T00:00:00.000000Z\"\n  },\n  {\n    \"id\": 2,\n    \"name\": \"Product Sales\",\n    \"classification\": \"revenue\",\n    \"allocate_to_products\": false,\n    \"proration_strategy\": \"revenue_based\",\n    \"nominal_code_id\": 5,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-02-15T10:00:00.000000Z\"\n  }\n]"}]},{"name":"Create Financial Line Type","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]},"description":"Creates a new financial line type.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string) — Name of the financial line type\n- classification (required, string) — One of: revenue, cost\n- allocate_to_products (optional, boolean) — Whether to allocate costs/revenue to products\n- proration_strategy (optional, string) — One of: revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual\n- nominal_code_id (optional, integer|null) — ID of associated nominal code\n\n**Requires permission:** `financial_line_types.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Freight\",\n  \"classification\": \"cost\",\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"weight_based\",\n  \"nominal_code_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 3,\n  \"name\": \"Freight\",\n  \"classification\": \"cost\",\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"weight_based\",\n  \"nominal_code_id\": null,\n  \"created_at\": \"2024-06-01T09:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T09:00:00.000000Z\"\n}"}]},{"name":"Bulk Delete Financial Line Types","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]},"description":"Bulk deletes multiple financial line types by their IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array) — Array of financial line type IDs to delete\n\n**Requires permission:** `financial_line_types.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/financial-line-types","host":["{{baseUrl}}"],"path":["api","financial-line-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Records deleted successfully.\"\n}"}]},{"name":"Get Financial Line Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]},"description":"Returns a single financial line type by ID.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"name\": \"Freight\",\n  \"classification\": \"cost\",\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"weight_based\",\n  \"nominal_code_id\": null,\n  \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n  \"updated_at\": \"2024-01-01T00:00:00.000000Z\"\n}"}]},{"name":"Update Financial Line Type","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]},"description":"Updates an existing financial line type. All fields are optional on update.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields (all optional on update):\n- name (optional, string) — Name of the financial line type\n- classification (optional, string) — One of: revenue, cost\n- allocate_to_products (optional, boolean) — Whether to allocate costs/revenue to products\n- proration_strategy (optional, string) — One of: revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual\n- nominal_code_id (optional, integer|null) — ID of associated nominal code\n\n**Requires permission:** `financial_line_types.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"International Freight\",\n  \"classification\": \"cost\",\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"volume_based\",\n  \"nominal_code_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"name\": \"International Freight\",\n  \"classification\": \"cost\",\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"volume_based\",\n  \"nominal_code_id\": 12,\n  \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T10:00:00.000000Z\"\n}"}]},{"name":"Delete Financial Line Type","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]},"description":"Deletes a financial line type. Returns 400 if the type has associated financial lines.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `financial_line_types.delete`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/financial-line-types/{financial_line_type}","host":["{{baseUrl}}"],"path":["api","financial-line-types",":financial_line_type"],"variable":[{"key":"financial_line_type","value":"1","description":"Financial line type ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]}]},{"name":"Cost Categories","item":[{"name":"List Cost Categories","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories","host":["{{baseUrl}}"],"path":["api","cost-categories"]},"description":"List all cost categories, ordered by name.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nEach category includes its `default_nominal_code_id` and, when set, an embedded `default_nominal_code` object ({id, code, name}). The default nominal code is the account a landed-cost bill line assigned to this category posts its debit to by default (an explicit nominal code on the line still wins; if the category has no default, posting falls back to the nominal code mapping settings).\n\nQuery parameters:\n- `selectable` (boolean) — exclude system categories\n- `is_active` (boolean) — filter by active/archived\n- `with_usage_counts` (boolean) — include usage counts\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-categories","host":["{{baseUrl}}"],"path":["api","cost-categories"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Accrued Purchases\",\n      \"is_system\": true,\n      \"is_active\": true,\n      \"default_nominal_code_id\": null,\n      \"default_nominal_code\": null,\n      \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Freight\",\n      \"is_system\": false,\n      \"is_active\": true,\n      \"default_nominal_code_id\": 3,\n      \"default_nominal_code\": {\n        \"id\": 3,\n        \"code\": \"6000\",\n        \"name\": \"Shipping Expense\"\n      },\n      \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n      \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Create Cost Category","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-categories","host":["{{baseUrl}}"],"path":["api","cost-categories"]},"description":"Create a new cost category.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (required, string, max:255) — unique category name\n- `default_nominal_code_id` (optional, integer, nullable) — the nominal code a landed-cost bill line assigned to this category posts its debit to by default. Must exist in `nominal_codes`. Leave null to fall back to the nominal code mapping settings at posting time.","body":{"mode":"raw","raw":"{\n  \"name\": \"Freight\",\n  \"default_nominal_code_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-categories","host":["{{baseUrl}}"],"path":["api","cost-categories"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"message\": \"cost category was created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"List Cost Categories (Paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/list","host":["{{baseUrl}}"],"path":["api","cost-categories","list"]},"description":"Paginated, server-side-filtered list of cost categories. Supports search (name / id / keyword aliases), active/system/selectable filters, and sorting, returning a standard paginated envelope. Each item includes usage counts and, when set, the embedded default nominal code.\n\nUse this endpoint when building a browsable, filterable table of cost categories. For a full unpaginated list (e.g. to populate a dropdown) use `GET /api/cost-categories` instead.\n\nQuery parameters:\n- `filter[search]` — search term (partial match on name; scope with search_columns)\n- `search_columns` — restrict search to: name, id, keyword\n- `filter[is_active]` — 1 active / 0 archived\n- `filter[is_system]` — 1 system / 0 user-defined\n- `filter[selectable]` — 1 to exclude system categories\n- `sort` — id, name, is_system, is_active, created_at, updated_at (prefix - for DESC)\n- `page`, `per_page` — pagination (per_page default 10)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-categories/list","host":["{{baseUrl}}"],"path":["api","cost-categories","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Freight\",\n      \"is_system\": true,\n      \"is_active\": true,\n      \"default_nominal_code_id\": 5,\n      \"default_nominal_code\": {\n        \"id\": 5,\n        \"code\": \"5000\",\n        \"name\": \"Cost of Goods Sold\"\n      },\n      \"usage_counts\": {\n        \"bill_lines\": 8,\n        \"breakdown_items\": 2,\n        \"financial_line_types\": 1,\n        \"total\": 11\n      },\n      \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n      \"updated_at\": \"2024-03-02T14:20:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 8,\n  \"from\": 1,\n  \"to\": 8,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/cost-categories/list?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/cost-categories/list?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/cost-categories/list\"\n}"}]},{"name":"Get Cost Category","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]},"description":"Show a single cost category with usage counts and its embedded `default_nominal_code` (when set).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"usage_counts\": {\n      \"bill_lines\": 12,\n      \"breakdown_items\": 3,\n      \"financial_line_types\": 1,\n      \"total\": 16\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Cost Category","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]},"description":"Update an existing cost category.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (required, string, max:255) — unique category name (ignores this record for the uniqueness check)\n- `default_nominal_code_id` (optional, integer, nullable) — default posting nominal code; must exist in `nominal_codes`. Send null to clear it and fall back to the nominal code mapping settings.\n\nNote: the name of a **system** cost category cannot be changed (returns 422).","body":{"mode":"raw","raw":"{\n  \"name\": \"Freight & Handling\",\n  \"default_nominal_code_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"message\": \"cost category was updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Cost Category","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]},"description":"Delete a cost category. Fails if the category is a system category, or if it is in use (bill lines / breakdown items / financial line types) unless `?force=true` is passed.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost category deleted.\",\n  \"status\": \"success\"\n}"}]},{"name":"Archive Cost Category","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/archive","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","archive"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]},"description":"Archive a cost category (soft-archive via is_active=false). System categories cannot be archived (returns 422).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/archive","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","archive"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": false,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Cost Category","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/unarchive","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","unarchive"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]},"description":"Unarchive a cost category (is_active=true).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/unarchive","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","unarchive"],"variable":[{"key":"cost_category","value":"5","description":"Cost category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Merge Cost Category","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/merge","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","merge"],"variable":[{"key":"cost_category","value":"5","description":"Source cost category ID (merged away and deleted)"}]},"description":"Merge a cost category into a target. Re-points all references (bill lines, breakdown items, financial line types) from the source to the target, then deletes the source. Returns the target category.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `target_id` (required, integer) — the cost category to merge into; must exist and differ from the source.","body":{"mode":"raw","raw":"{\n  \"target_id\": 6\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-categories/{cost_category}/merge","host":["{{baseUrl}}"],"path":["api","cost-categories",":cost_category","merge"],"variable":[{"key":"cost_category","value":"5","description":"Source cost category ID (merged away and deleted)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Fuzzy Match Cost Category","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-categories/fuzzy-match?name=Freght","host":["{{baseUrl}}"],"path":["api","cost-categories","fuzzy-match"],"query":[{"key":"name","value":"Freght","description":"Required. The name to fuzzy-match against existing categories. Returns the closest match, or null if none is close enough.","disabled":true}]},"description":"Suggest a fuzzy-matched category for the given name — used by the create form to warn \"Did you mean Freight?\" before a near-duplicate is created. Returns null in `data` when no close match is found.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-categories/fuzzy-match?name=Freght","host":["{{baseUrl}}"],"path":["api","cost-categories","fuzzy-match"],"query":[{"key":"name","value":"Freght","description":"Required. The name to fuzzy-match against existing categories. Returns the closest match, or null if none is close enough.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Freight\",\n    \"is_system\": false,\n    \"is_active\": true,\n    \"default_nominal_code_id\": 3,\n    \"default_nominal_code\": {\n      \"id\": 3,\n      \"code\": \"6000\",\n      \"name\": \"Shipping Expense\"\n    },\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]}]},{"name":"Payment Terms","item":[{"name":"List Payment Terms","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms?page=1&per_page=10&sort=name&filter[due_date_type]=from_invoice_date&filter[is_default]=false&filter[archived]=all&filter[search]=net30","host":["{{baseUrl}}"],"path":["api","payment-terms"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, net_days, discount_percentage, discount_days, due_date_type, is_default, created_at, updated_at","disabled":true},{"key":"filter[due_date_type]","value":"from_invoice_date","description":"Exact match. Values: immediate, from_invoice_date, end_of_month, end_of_next_month, day_of_month","disabled":true},{"key":"filter[is_default]","value":"false","description":"Exact match. Filter by default payment term flag (true/false)","disabled":true},{"key":"filter[archived]","value":"all","description":"Archive filter. Values: only (archived only), all (include archived), omit for active only","disabled":true},{"key":"filter[search]","value":"net30","description":"Search across id, name, description fields","disabled":true}]},"description":"Returns a paginated list of payment terms.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort fields: id, name, net_days, discount_percentage, discount_days, due_date_type, is_default, created_at, updated_at (default: name).\n\nBy default only active (non-archived) terms are returned. Use filter[archived]=all or filter[archived]=only to include archived records."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/payment-terms?page=1&per_page=10&sort=name&filter[due_date_type]=from_invoice_date&filter[is_default]=false&filter[archived]=all&filter[search]=net30","host":["{{baseUrl}}"],"path":["api","payment-terms"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, net_days, discount_percentage, discount_days, due_date_type, is_default, created_at, updated_at","disabled":true},{"key":"filter[due_date_type]","value":"from_invoice_date","description":"Exact match. Values: immediate, from_invoice_date, end_of_month, end_of_next_month, day_of_month","disabled":true},{"key":"filter[is_default]","value":"false","description":"Exact match. Filter by default payment term flag (true/false)","disabled":true},{"key":"filter[archived]","value":"all","description":"Archive filter. Values: only (archived only), all (include archived), omit for active only","disabled":true},{"key":"filter[search]","value":"net30","description":"Search across id, name, description fields","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Net 30\",\n      \"net_days\": 30,\n      \"discount_percentage\": 2,\n      \"discount_days\": 10,\n      \"due_date_type\": \"from_invoice_date\",\n      \"due_date_type_label\": \"Days After Invoice Date\",\n      \"description\": \"2% discount if paid within 10 days, net due in 30 days\",\n      \"is_default\": true,\n      \"is_consignment\": false,\n      \"consignment_settlement_frequency\": null,\n      \"treat_as_purchase\": false,\n      \"has_discount\": true,\n      \"generated_description\": \"2/10 Net 30\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Net 60\",\n      \"net_days\": 60,\n      \"discount_percentage\": 0,\n      \"discount_days\": null,\n      \"due_date_type\": \"from_invoice_date\",\n      \"due_date_type_label\": \"Days After Invoice Date\",\n      \"description\": null,\n      \"is_default\": false,\n      \"is_consignment\": false,\n      \"consignment_settlement_frequency\": null,\n      \"treat_as_purchase\": false,\n      \"has_discount\": false,\n      \"generated_description\": \"Net 60\",\n      \"created_at\": \"2024-01-16T09:30:00.000000Z\",\n      \"updated_at\": \"2024-01-16T09:30:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"first_page_url\": \"https://sku2.test/api/payment-terms?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku2.test/api/payment-terms?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku2.test/api/payment-terms\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Create Payment Term","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-terms","host":["{{baseUrl}}"],"path":["api","payment-terms"]},"description":"Creates a new payment term.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, max:255, unique)\n- net_days (required, integer, 0-365)\n- discount_percentage (optional, numeric, 0-100)\n- discount_days (optional, integer >= 0; must be less than net_days for types: from_invoice_date, end_of_month, day_of_month)\n- due_date_type (required): immediate | from_invoice_date | end_of_month | end_of_next_month | day_of_month\n- description (optional, string, max:500)\n- is_default (optional, boolean)\n\nVendor Deposit Schedule (optional, array):\n- vendor_deposit_schedule.*.label (optional, string)\n- vendor_deposit_schedule.*.amount_mode (optional): percent | fixed\n- vendor_deposit_schedule.*.percentage (numeric, 0-100)\n- vendor_deposit_schedule.*.fixed_amount (optional, numeric)\n- vendor_deposit_schedule.*.settlement_type (optional): vendor_deposit | final_invoice_balance\n- vendor_deposit_schedule.*.trigger_event (required): one of the supported trigger events including logistics_tracking_field\n- vendor_deposit_schedule.*.offset_days (optional, integer, nullable)\n- vendor_deposit_schedule.*.per_shipment (optional, boolean)\n- vendor_deposit_schedule.*.shipment_date_basis (optional): dispatched | planned_etd | actual_dispatched | received_at\n- vendor_deposit_schedule.*.is_ownership_transfer (optional, boolean) — only one line per schedule may be true\n- vendor_deposit_schedule.*.logistics_tracking_field_id (optional, integer, exists:logistics_tracking_fields,id) — REQUIRED when trigger_event is logistics_tracking_field\n\n**Requires permission:** `payment_terms.create`\n\nConsignment fields: set is_consignment to true to mark the term as consignment (supplier-owned stock billed as it sells). consignment_settlement_frequency controls how often consigned sales are settled (on_demand, weekly, biweekly, monthly, quarterly). treat_as_purchase overrides consignment so goods received on this term are capitalized as owned inventory immediately at receipt (substance-over-form).","body":{"mode":"raw","raw":"{\n  \"name\": \"Net 45\",\n  \"net_days\": 45,\n  \"discount_percentage\": 1.5,\n  \"discount_days\": 10,\n  \"due_date_type\": \"from_invoice_date\",\n  \"description\": \"1.5% discount if paid within 10 days, net due in 45 days\",\n  \"is_default\": false,\n  \"is_consignment\": false,\n  \"consignment_settlement_frequency\": null,\n  \"treat_as_purchase\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/payment-terms","host":["{{baseUrl}}"],"path":["api","payment-terms"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Net 45\",\n    \"net_days\": 45,\n    \"discount_percentage\": 1.5,\n    \"discount_days\": 10,\n    \"due_date_type\": \"from_invoice_date\",\n    \"due_date_type_label\": \"Days After Invoice Date\",\n    \"description\": \"1.5% discount if paid within 10 days, net due in 45 days\",\n    \"is_default\": false,\n    \"is_consignment\": false,\n    \"consignment_settlement_frequency\": null,\n    \"treat_as_purchase\": false,\n    \"has_discount\": true,\n    \"generated_description\": \"1.5/10 Net 45\",\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"payment term created successfully\"\n}"}]},{"name":"Bulk Delete Payment Terms","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms","host":["{{baseUrl}}"],"path":["api","payment-terms"]},"description":"Bulk deletes multiple payment terms by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_terms.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/payment-terms","host":["{{baseUrl}}"],"path":["api","payment-terms"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 payment terms deleted successfully\"\n}"}]},{"name":"Get Payment Term","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single payment term by ID. Includes due_date_type_options in the response for form use.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Net 30\",\n    \"net_days\": 30,\n    \"discount_percentage\": 2,\n    \"discount_days\": 10,\n    \"due_date_type\": \"from_invoice_date\",\n    \"due_date_type_label\": \"Days After Invoice Date\",\n    \"description\": \"2% discount if paid within 10 days, net due in 30 days\",\n    \"is_default\": true,\n    \"is_consignment\": false,\n    \"consignment_settlement_frequency\": null,\n    \"treat_as_purchase\": false,\n    \"has_discount\": true,\n    \"generated_description\": \"2/10 Net 30\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"archived_at\": null,\n    \"due_date_type_options\": [\n      {\n        \"value\": \"immediate\",\n        \"label\": \"Due Immediately\",\n        \"description\": \"Payment is due immediately upon receipt of invoice.\",\n        \"netDaysLabel\": \"Net Days (not used)\",\n        \"usesNetDays\": false\n      },\n      {\n        \"value\": \"from_invoice_date\",\n        \"label\": \"Days After Invoice Date\",\n        \"description\": \"Due date = Invoice Date + Net Days.\",\n        \"netDaysLabel\": \"Net Days\",\n        \"usesNetDays\": true\n      },\n      {\n        \"value\": \"end_of_month\",\n        \"label\": \"End of Invoice Month + Days\",\n        \"description\": \"Due date = End of invoice month + Net Days.\",\n        \"netDaysLabel\": \"Additional Days After Month End\",\n        \"usesNetDays\": true\n      },\n      {\n        \"value\": \"end_of_next_month\",\n        \"label\": \"End of Next Month\",\n        \"description\": \"Due at the end of the month following the invoice date.\",\n        \"netDaysLabel\": \"Net Days (not used)\",\n        \"usesNetDays\": false\n      },\n      {\n        \"value\": \"day_of_month\",\n        \"label\": \"Specific Day of Month\",\n        \"description\": \"Due on a specific day of the next month.\",\n        \"netDaysLabel\": \"Day of Month (1-31)\",\n        \"usesNetDays\": true\n      }\n    ]\n  }\n}"}]},{"name":"Update Payment Term","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing payment term by ID.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields same as Create, including the optional vendor_deposit_schedule array (with per-line logistics_tracking_field_id required when trigger_event is logistics_tracking_field). Name uniqueness ignores the current record.\n\nConsignment fields: set is_consignment to true to mark the term as consignment (supplier-owned stock billed as it sells). consignment_settlement_frequency controls how often consigned sales are settled (on_demand, weekly, biweekly, monthly, quarterly). treat_as_purchase overrides consignment so goods received on this term are capitalized as owned inventory immediately at receipt (substance-over-form).","body":{"mode":"raw","raw":"{\n  \"name\": \"Net 45 Updated\",\n  \"net_days\": 45,\n  \"discount_percentage\": 2,\n  \"discount_days\": 15,\n  \"due_date_type\": \"from_invoice_date\",\n  \"description\": \"Updated payment terms\",\n  \"is_default\": false,\n  \"is_consignment\": false,\n  \"consignment_settlement_frequency\": null,\n  \"treat_as_purchase\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Net 45 Updated\",\n    \"net_days\": 45,\n    \"discount_percentage\": 2,\n    \"discount_days\": 15,\n    \"due_date_type\": \"from_invoice_date\",\n    \"due_date_type_label\": \"Days After Invoice Date\",\n    \"description\": \"Updated payment terms\",\n    \"is_default\": false,\n    \"is_consignment\": false,\n    \"consignment_settlement_frequency\": null,\n    \"treat_as_purchase\": false,\n    \"has_discount\": true,\n    \"generated_description\": \"2/15 Net 45\",\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T14:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"payment term Net 45 Updated updated successfully\"\n}"}]},{"name":"Delete Payment Term","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a payment term by ID. Returns an error if the term is linked to purchase orders or suppliers.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/payment-terms/{id}","host":["{{baseUrl}}"],"path":["api","payment-terms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Net 45 Updated deleted successfully\"\n}"}]},{"name":"Archive Payment Term","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms/{id}/archive","host":["{{baseUrl}}"],"path":["api","payment-terms",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a payment term. Returns a warning if already archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-terms/{id}/archive","host":["{{baseUrl}}"],"path":["api","payment-terms",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Net 30\",\n    \"archived_at\": \"2024-03-01T15:00:00.000000Z\"\n  },\n  \"message\": \"payment term Net 30 archived successfully\"\n}"}]},{"name":"Unarchive Payment Term","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/payment-terms/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","payment-terms",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a payment term. Returns a warning if not currently archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-terms/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","payment-terms",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Net 30\",\n    \"archived_at\": null\n  },\n  \"message\": \"payment term Net 30 unarchived successfully\"\n}"}]},{"name":"Bulk Archive Payment Terms","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-terms/archive","host":["{{baseUrl}}"],"path":["api","payment-terms","archive"]},"description":"Bulk archives multiple payment terms by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_terms.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-terms/archive","host":["{{baseUrl}}"],"path":["api","payment-terms","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 payment terms archived successfully\"\n}"}]},{"name":"Bulk Unarchive Payment Terms","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-terms/unarchive","host":["{{baseUrl}}"],"path":["api","payment-terms","unarchive"]},"description":"Bulk unarchives multiple payment terms by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_terms.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/payment-terms/unarchive","host":["{{baseUrl}}"],"path":["api","payment-terms","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 payment terms unarchived successfully\"\n}"}]},{"name":"Check Payment Terms Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/payment-terms/deletable","host":["{{baseUrl}}"],"path":["api","payment-terms","deletable"]},"description":"Checks which payment terms can be deleted (not linked to any purchase orders or suppliers).\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `payment_terms.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/payment-terms/deletable","host":["{{baseUrl}}"],"path":["api","payment-terms","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Net 30\",\n      \"deletable\": false,\n      \"reason\": {\n        \"purchase_orders\": \"This payment term is currently used by 5 purchase orders.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Net 60\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Net 45\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]}]},{"name":"Ledger (Accounting v2)","item":[{"name":"Get Dashboard Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/dashboard","host":["{{baseUrl}}"],"path":["api","ledger","dashboard"]},"description":"The Accounting v2 section landing summary — the whole dashboard in one call. Composed from the existing managers/repositories so it never diverges from the tab it summarizes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Sections:**\n- `generation_health` — the derived backlog signal (`state`: healthy | behind | failing | paused) with its label + Vuetify color, plus the raw inputs: kill-switch `enabled`, `environment_override`, outbox `pending`/`failed`, the drain `last_processed_at` heartbeat, `stale_after_minutes` (5), and the next scheduled runs. `behind` requires BOTH queued work AND a stale heartbeat — a large-but-draining queue stays healthy.\n- `kpis` — four headline counts: `pending_sync` (pending_sync + update_pending + syncing + retrying), `needs_attention` (needs_attention + failed + conflict + removed_in_provider), `synced`, and `outbox_backlog` (outbox pending + failed source documents not yet turned into entries).\n- `status_breakdown` — per-display-status counts in enum order, each with label + color (click a segment to open the All tab filtered on that `display_status`). Statuses with no entries are included with count 0.\n- `needs_attention` — the parked `total`, the `group_count`, and the top 5 error-cause `groups`.\n- `connections` — the accounting connections view-model (provider, health, lock date, rate budget, last inbound, open ops).\n- `reconciliation` — `balance_mismatches`: current entries whose line sums disagree with their header totals.\n- `recent_entries` — the 5 most recent entries (same shape as the entries table)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/dashboard","host":["{{baseUrl}}"],"path":["api","ledger","dashboard"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dashboard\": {\n      \"generation_health\": {\n        \"state\": \"behind\",\n        \"label\": \"Behind\",\n        \"color\": \"warning\",\n        \"enabled\": true,\n        \"environment_override\": false,\n        \"pending\": 42,\n        \"failed\": 0,\n        \"last_processed_at\": \"2026-06-12T02:21:00+00:00\",\n        \"stale_after_minutes\": 5,\n        \"schedule\": {\n          \"next_generation_run_at\": \"2026-06-12T20:21:00+00:00\",\n          \"next_reconcile_run_at\": \"2026-06-13T00:00:00+00:00\"\n        }\n      },\n      \"kpis\": {\n        \"pending_sync\": 38,\n        \"needs_attention\": 14,\n        \"synced\": 1240,\n        \"outbox_backlog\": 42\n      },\n      \"status_breakdown\": [\n        {\n          \"key\": \"excluded\",\n          \"label\": \"Excluded\",\n          \"color\": \"grey\",\n          \"count\": 12\n        },\n        {\n          \"key\": \"pending_sync\",\n          \"label\": \"Pending sync\",\n          \"color\": \"info\",\n          \"count\": 28\n        },\n        {\n          \"key\": \"syncing\",\n          \"label\": \"Syncing\",\n          \"color\": \"info\",\n          \"count\": 4\n        },\n        {\n          \"key\": \"synced\",\n          \"label\": \"Synced\",\n          \"color\": \"success\",\n          \"count\": 1240\n        },\n        {\n          \"key\": \"update_pending\",\n          \"label\": \"Update pending\",\n          \"color\": \"warning\",\n          \"count\": 5\n        },\n        {\n          \"key\": \"retrying\",\n          \"label\": \"Retrying\",\n          \"color\": \"warning\",\n          \"count\": 1\n        },\n        {\n          \"key\": \"needs_attention\",\n          \"label\": \"Needs attention\",\n          \"color\": \"error\",\n          \"count\": 9\n        },\n        {\n          \"key\": \"failed\",\n          \"label\": \"Failed\",\n          \"color\": \"error\",\n          \"count\": 3\n        },\n        {\n          \"key\": \"removed_in_provider\",\n          \"label\": \"Removed in provider\",\n          \"color\": \"error\",\n          \"count\": 1\n        },\n        {\n          \"key\": \"conflict\",\n          \"label\": \"Conflict\",\n          \"color\": \"error\",\n          \"count\": 1\n        },\n        {\n          \"key\": \"voided\",\n          \"label\": \"Synced, Voided\",\n          \"color\": \"warning\",\n          \"count\": 2\n        }\n      ],\n      \"needs_attention\": {\n        \"total\": 14,\n        \"group_count\": 2,\n        \"groups\": [\n          {\n            \"cause_key\": \"user_action_required:d2b5c3a1e4f6a7b8c9d0e1f2a3b4c5d6\",\n            \"label\": \"Account # Sales Revenue is inactive in QuickBooks Online.\",\n            \"error_class\": \"user_action_required\",\n            \"count\": 11\n          },\n          {\n            \"cause_key\": \"auth_connection:9f1c0b2a3d4e5f60718293a4b5c6d7e8\",\n            \"label\": \"The Xero connection needs to be re-authorized.\",\n            \"error_class\": \"auth_connection\",\n            \"count\": 3\n          }\n        ]\n      },\n      \"connections\": [\n        {\n          \"id\": 3,\n          \"provider\": \"qbo\",\n          \"name\": \"QuickBooks Online\",\n          \"health\": {\n            \"sync_status\": \"active\",\n            \"paused\": false\n          },\n          \"lock_date\": \"2026-04-30\",\n          \"rate_budget_remaining\": null,\n          \"last_inbound_event_at\": \"2026-06-10T18:42:11+00:00\",\n          \"open_operations\": {\n            \"pending\": 4,\n            \"queued\": 2,\n            \"in_flight\": 1\n          }\n        }\n      ],\n      \"reconciliation\": {\n        \"balance_mismatches\": 0\n      },\n      \"recent_entries\": [\n        {\n          \"id\": 1842,\n          \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n          \"type\": {\n            \"value\": \"sales_order_invoice\",\n            \"label\": \"Sales Order Invoice\"\n          },\n          \"status\": \"posted\",\n          \"display_status\": {\n            \"key\": \"synced\",\n            \"label\": \"Synced\",\n            \"color\": \"success\",\n            \"reason\": null\n          },\n          \"effective_at\": \"2026-06-05T14:30:00+00:00\",\n          \"posted_at\": \"2026-06-05T14:35:12+00:00\",\n          \"currency_code\": \"USD\",\n          \"total_debit\": \"249.9900\",\n          \"total_credit\": \"249.9900\",\n          \"reference\": \"SO-10293\",\n          \"reference_suffix\": null,\n          \"description\": \"Sales order invoice for SO-10293\",\n          \"source\": {\n            \"type\": \"App\\\\Models\\\\SalesOrder\",\n            \"id\": 10293,\n            \"label\": \"SO-10293\",\n            \"link_type_label\": \"Sales Order\",\n            \"link_route\": \"/orders/sales-orders/10293\",\n            \"link_legacy_url\": null,\n            \"url\": \"/orders/sales-orders/10293\"\n          },\n          \"batch_id\": null,\n          \"sync_override\": null,\n          \"integrity_flag\": null,\n          \"reversal_of_id\": null,\n          \"replaced_by_id\": null,\n          \"created_at\": \"2026-06-05T14:30:02+00:00\",\n          \"provider_link\": null\n        }\n      ]\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Outbox Failures","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/outbox/failures","host":["{{baseUrl}}"],"path":["api","ledger","outbox","failures"]},"description":"Paginated terminally-failed `ledger_outbox` rows for the dashboard failures drill-down, newest failure first (`processed_at` carries the failure timestamp for failed rows).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Pagination:** `per_page` (default 10, clamped to 100), `page`. Standard Laravel pagination envelope.\n\n**Each row:**\n- `source` — the source-document cross-link resolved from source_type/source_id (NOT hydrated — failed rows often point at since-deleted documents, so `label`/`link_route` may be null; `link_type_label` always renders).\n- `event` — the failed source event (created | updated | deleted) with a headline label.\n- `attempts` — how many drain attempts were exhausted before the row terminated.\n- `last_error` — the preserved error text (capped at 60 KB).\n- `failed_at` / `available_at` / `created_at` — ISO-8601 timestamps."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/outbox/failures","host":["{{baseUrl}}"],"path":["api","ledger","outbox","failures"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9182,\n      \"source\": {\n        \"type\": \"App\\\\Models\\\\Bill\",\n        \"id\": 4412,\n        \"label\": null,\n        \"link_type_label\": \"Bill\",\n        \"link_route\": null,\n        \"link_legacy_url\": null,\n        \"url\": null\n      },\n      \"event\": {\n        \"value\": \"updated\",\n        \"label\": \"Updated\"\n      },\n      \"attempts\": 5,\n      \"last_error\": \"QuickBooks Online rejected the request: Account 'Sales Revenue' is inactive.\",\n      \"available_at\": \"2026-06-12T02:18:00+00:00\",\n      \"failed_at\": \"2026-06-12T02:21:00+00:00\",\n      \"created_at\": \"2026-06-12T01:40:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/ledger/outbox/failures?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/ledger/outbox/failures?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/ledger/outbox/failures\",\n  \"links\": []\n}"}]},{"name":"Retry Outbox Failures","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/outbox/failures/retry","host":["{{baseUrl}}"],"path":["api","ledger","outbox","failures","retry"]},"description":"Re-queue terminally-failed outbox rows for another drain pass: reset them to pending, clear the attempt counter (a fresh max-attempts budget — otherwise the next failure would immediately re-terminate them), make them claimable now, and kick the drain.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token. Requires the `accounting.sync` permission.\n\n**Body:** `{ \"ids\": [9182, 9183] }` retries the given failed rows; omit `ids` or pass `[]` to retry EVERY terminally-failed row.\n\n**Response:** `data.requeued` — the number of rows re-queued (0 if there were no failures to retry).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    9182,\n    9183\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/outbox/failures/retry","host":["{{baseUrl}}"],"path":["api","ledger","outbox","failures","retry"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requeued\": 2\n  },\n  \"message\": \"2 failed rows re-queued — generation will reprocess them shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"List Journal Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries","host":["{{baseUrl}}"],"path":["api","ledger","entries"]},"description":"Paginated journal entries listing. Discarded regeneration drafts are excluded; reversed entries stay visible so the reversal chain is browsable.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token (Personal Access Token).\n\n**Filters (Spatie QueryBuilder):**\n- `filter[type]` — exact entry type (AccountingTransactionTypeEnum, ~30 values, e.g. sales_order_invoice, fba_shipments, bill)\n- `filter[status]` — exact lifecycle status: draft, posted, reversed\n- `filter[display_status]` — exact, comma-multi supported. Values: excluded, pending_sync, syncing, synced, update_pending, retrying, needs_attention, failed, removed_in_provider, conflict, voided\n- `filter[sync_routing]` — Routing/cadence axis (individual | daily | monthly)\n- `filter[source_type]` — exact source morph class\n- `filter[batch_id]` — exact batch ID\n- `filter[date_from]` / `filter[date_to]` — m/d/Y on effective_at (invalid dates silently ignored)\n- `filter[connection]` — connection ID; entries holding a sync link on that connection\n- `filter[search]` — partial match on reference, description, amount (total_debit), id, the resolved counterparty name and the synced provider document id (remote_id — e.g. a Xero invoice ID); scope with `search_columns` (e.g. `search_columns=remote_id`) and force exact match with `search_strict_columns`\n\n**Sorts:** id, effective_at, reference, total_debit, created_at, type, counterparty, due_date, display_status, sync_routing (default: -effective_at). `type` sorts the stored entry-type enum; `counterparty` sorts the resolved supplier/customer/marketplace/provider name across polymorphic sources; `due_date` sorts the source purchase invoice's due date (other sources sort NULL).\n\n**Pagination:** per_page default 10, clamped to max 100.\n\nEach row carries a `display_status` object (key/label/color/reason). A batch member has no standalone status — its `display_status` mirrors its batch aggregate's live status at read time (Pending Sync / Syncing / Synced / Failed …); there is deliberately no `batched` status value. `reason` is the chip-tooltip hint: `batch_member` for batch members, comma-joined eligibility exclusion reasons (or `no_accounting_connection`) for excluded entries, null otherwise. Detail-only sections (lines, sync_links, operations, reversal_chain) are NOT included on the index — use the show endpoint.\n\n**Status is null for historical entries:** the `display_status` and `routing` objects each report null key/label/color when an entry has left the live books — it is discarded (superseded by a regenerated replacement: `replaced_by_id` set + `discarded_at`) or a reversed original (`status = reversed`). Such rows can never sync (the batch rollup, reports and live lists all exclude them), so a frozen `synced` status would mislead; the supersession marker carries the why instead. A live reversal contra entry (`reversal_of_id` set, still posted) is NOT historical and keeps its status.\n\n**Advanced filters (`filter_groups`):** base64-encoded JSON tree of AND/OR groups, applied via GroupedFilterSupport (same stack as Purchase Orders). Decoded shape:\n```\n{\n  \"conjunction\": \"and\",\n  \"children\": [\n    {\"type\": \"condition\", \"condition\": {\"column\": \"reference\", \"operator\": \"contains\", \"value\": \"INV\"}},\n    {\"type\": \"group\", \"group\": {\"conjunction\": \"or\", \"children\": [...]}}\n  ]\n}\n```\n**Filterable columns:** `reference`, `description`, `entry_type`, `entry_status`, `entry_display_status`, `currency_code`, `counterparty` (text: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of); `id`, `total_debit`, `total_credit`, `entry_batch_id` (numeric: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty); `nominal_code_id` (text, relationship — matches entries posting to the nominal code on any line); `effective_at` (date), `posted_at`, `created_at` (datetime: is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, …). `counterparty` has no stored column — it filters on the resolved supplier/customer/marketplace name via the same correlated subquery used for search and sort.\n\nUnregistered columns in the tree are rejected with HTTP 400 (InvalidFilterQuery).\n\nEach entry includes `provider_link` — the accounting-provider document it is synced to (the Xero/QBO column): { provider, remote_type, remote_id, link_type_label, label, link_route (internal detail page, or null when none exists yet), remote_url (provider deep link) }. It is null for entries not yet synced to a provider.\n\n**Per-lens columns (`lens` query param):** the scoped Transactions tabs (Invoices / Journals / Purchase Orders) are thin wrappers over this one endpoint and request extra columns via `?lens=`. The All tab, dashboard, detail and export paths send no lens, so the response keeps the shared columns only with zero extra queries. When a lens is present each row gains a derive-on-read block:\n- `lens=invoices` adds `counterparty` ({ name, id, link_type_label, link_route }; a CRM party has `link_type_label` \"Supplier\"/\"Customer\" + numeric `id` + `link_route`; an AR source (sales order / sales credit) with no CRM customer falls back to a marketplace customer — `name` \"{Integration} Customer\" e.g. \"Amazon Customer\", `link_type_label` \"Customer\", `id` + `link_route` null; a settlement source (Amazon financial-event group) falls back to a bare marketplace label — `name` the integration name e.g. \"Amazon\", `link_type_label` \"Marketplace\", `id` + `link_route` null; a ShipMyOrders provider invoice (a 3PL fulfilment-provider bill, no CRM party) falls back to a fixed provider label — `name` \"SMO\", `link_type_label` \"Provider\", `id` + `link_route` null; null/absent when the source resolves no party or was deleted), `due_date` (YYYY-MM-DD date-only, no timezone conversion; null unless the source carries one — only purchase invoices do), and `tax_total` (scale-4 string summed across the entry's lines, or null when no line carries tax).\n- `lens=journals` adds `debit_account` and `credit_account` — each is either { split: false, nominal_code_id, code, name, link_route } for a side posting to one account, or { split: true, count } when the side fans out across several codes, or null when the side has no lines — plus `batch` ({ id, label, status, period_start, period_end, link_route } or null for unbatched entries).\n- `lens=purchase-orders` adds `counterparty` (the supplier, same shape as above) and `stage` ({ ordered: true, received: none|partial|full, invoiced: none|partial|full }) derived from the source purchase order's receipt_status / invoice_status.\n\nEach row carries `line_count` — the number of GL-impact journal lines on the entry (cheap `withCount` subquery) — powering the entries table's inline expandable \"Lines\" column. Fetch the lines themselves via **Get Journal Entry Lines** (`/api/ledger/entries/{entry}/lines`).\n\n**`can_sync_now`** (boolean) — whether a manual \"Sync Now\" can push this entry right now. The per-transaction-type Sync toggle, granularity opt-out and the per-type start date only gate *automatic/scheduled* sync; a manual push bypasses them, so `can_sync_now` stays `true` for a benign \"Auto-off\" entry. It is `false` only when a *structural* blocker applies (connection inactive, entry is a batch member / open batch, internal-only, or before the accounting provider's conversion/start date) — those block even a manual push. Drives the UI split between a grey \"Auto-off · push anytime\" chip (`display_status=excluded` + `can_sync_now=true`) and an amber \"Blocked\" chip (`display_status=excluded` + `can_sync_now=false`).\n\n**provider_status** (response field) — the provider's own transaction status on the synced document (primary sync link remote_status); null for unsynced entries. Backs the Provider Status column + filter."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries","host":["{{baseUrl}}"],"path":["api","ledger","entries"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1842,\n      \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n      \"type\": {\n        \"value\": \"sales_order_invoice\",\n        \"label\": \"Sales Order Invoice\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"color\": \"success\",\n        \"reason\": null\n      },\n      \"can_sync_now\": true,\n      \"locked_update_pending\": false,\n      \"locked_amend_blocked\": false,\n      \"routing\": {\n        \"key\": \"individual\",\n        \"label\": \"Individual\",\n        \"color\": \"grey\",\n        \"batch_id\": null,\n        \"batch_route\": null\n      },\n      \"effective_at\": \"2026-06-05T14:30:00+00:00\",\n      \"posted_at\": \"2026-06-05T14:35:12+00:00\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"249.9900\",\n      \"total_credit\": \"249.9900\",\n      \"document_total\": \"249.9900\",\n      \"document_number\": \"INV-1842\",\n      \"reference\": \"SO-10293\",\n      \"reference_suffix\": null,\n      \"description\": \"Sales order invoice for SO-10293\",\n      \"source\": {\n        \"type\": \"App\\\\Models\\\\SalesOrder\",\n        \"id\": 10293,\n        \"label\": \"SO-10293\",\n        \"link_type_label\": \"Sales Order\",\n        \"link_route\": \"/orders/sales-orders/10293\",\n        \"link_legacy_url\": null,\n        \"url\": \"/orders/sales-orders/10293\"\n      },\n      \"batch_id\": null,\n      \"sync_override\": null,\n      \"integrity_flag\": null,\n      \"reversal_of_id\": null,\n      \"replaced_by_id\": null,\n      \"created_at\": \"2026-06-05T14:30:02+00:00\",\n      \"provider_link\": {\n        \"provider\": \"Xero\",\n        \"remote_type\": \"xero_invoice\",\n        \"remote_id\": \"a1b2c3d4-0000-0000-0000-000000000000\",\n        \"link_type_label\": \"Invoice\",\n        \"label\": \"INV-1042\",\n        \"link_route\": \"/integrations/xero/invoices/55\",\n        \"remote_url\": \"https://go.xero.com/AccountsReceivable/View.aspx?InvoiceID=a1b2c3d4-0000-0000-0000-000000000000\"\n      },\n      \"provider_status\": \"AUTHORISED\"\n    },\n    {\n      \"id\": 1841,\n      \"uuid\": \"5e8d2c1a-9f3b-4e7d-8a60-1b4c6d9e2f55\",\n      \"type\": {\n        \"value\": \"fba_shipments\",\n        \"label\": \"FBA Shipments\"\n      },\n      \"status\": \"draft\",\n      \"display_status\": {\n        \"key\": \"pending_sync\",\n        \"label\": \"Pending Sync\",\n        \"color\": \"info\",\n        \"reason\": \"batch_member\"\n      },\n      \"can_sync_now\": false,\n      \"locked_update_pending\": false,\n      \"locked_amend_blocked\": false,\n      \"routing\": {\n        \"key\": \"daily\",\n        \"label\": \"Daily\",\n        \"color\": \"purple\",\n        \"batch_id\": 57,\n        \"batch_route\": \"/ledger/batches/57\"\n      },\n      \"effective_at\": \"2026-06-04T09:00:00+00:00\",\n      \"posted_at\": null,\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"1240.5000\",\n      \"total_credit\": \"1240.5000\",\n      \"document_total\": \"1240.5000\",\n      \"document_number\": \"JE-1841\",\n      \"reference\": \"FBA-SHIP-2026-06-04\",\n      \"reference_suffix\": null,\n      \"description\": \"FBA shipments for 06/04/2026\",\n      \"source\": {\n        \"type\": \"Modules\\\\Amazon\\\\Entities\\\\AmazonLedger\",\n        \"id\": 88451,\n        \"label\": \"#88451\",\n        \"link_type_label\": \"Amazon Ledger\",\n        \"link_route\": null,\n        \"link_legacy_url\": null,\n        \"url\": null\n      },\n      \"batch_id\": 57,\n      \"sync_override\": null,\n      \"integrity_flag\": null,\n      \"reversal_of_id\": null,\n      \"replaced_by_id\": null,\n      \"created_at\": \"2026-06-04T09:02:41+00:00\",\n      \"provider_link\": null,\n      \"provider_status\": \"AUTHORISED\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-alt.test/api/ledger/entries?page=1\",\n  \"from\": 1,\n  \"last_page\": 93,\n  \"last_page_url\": \"https://sku-alt.test/api/ledger/entries?page=93\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/entries?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/entries?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-alt.test/api/ledger/entries?page=2\",\n  \"path\": \"https://sku-alt.test/api/ledger/entries\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 924\n}"}]},{"name":"List Needs-Attention Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/needs-attention","host":["{{baseUrl}}"],"path":["api","ledger","entries","needs-attention"]},"description":"The needs-attention inbox feed: non-discarded entries whose display status needs a human (needs_attention, failed, conflict, removed_in_provider — capped at the latest 1000), grouped server-side by error cause so the UI can offer fix-once-retry-all.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Grouping:** each group keys on the latest sync operation's `error_class` plus a normalized cause message (numeric IDs masked to `#` so per-record noise collapses into one cause, truncated to 160 chars). Entries with no operation error group under `status:<display_status>`. Groups are sorted by count descending.\n\n**Response shape (per group):**\n- `cause_key` — stable grouping key (error_class[:md5-of-message] or status:&lt;display_status>)\n- `label` — human-readable cause (normalized message, headline-cased error class, or display-status label)\n- `error_class` — retryable_transient | auth_connection | auto_remediable | user_action_required | terminal_internal | conflict, or null\n- `count` — total entries in the group\n- `entry_ids` — up to 25 sample entry IDs\n- `latest_error_payload` — the raw error payload of the group's latest operation, or null"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/needs-attention","host":["{{baseUrl}}"],"path":["api","ledger","entries","needs-attention"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"groups\": [\n      {\n        \"cause_key\": \"user_action_required:d2b5c3a1e4f6a7b8c9d0e1f2a3b4c5d6\",\n        \"label\": \"Account # Sales Revenue is inactive in QuickBooks Online.\",\n        \"error_class\": \"user_action_required\",\n        \"count\": 14,\n        \"entry_ids\": [\n          1842,\n          1836,\n          1831,\n          1828,\n          1815,\n          1809,\n          1804,\n          1799,\n          1795,\n          1788,\n          1781,\n          1774,\n          1769,\n          1762\n        ],\n        \"latest_error_payload\": {\n          \"message\": \"Account 4000 Sales Revenue is inactive in QuickBooks Online.\",\n          \"provider_code\": \"6240\"\n        }\n      },\n      {\n        \"cause_key\": \"auth_connection\",\n        \"label\": \"Auth Connection\",\n        \"error_class\": \"auth_connection\",\n        \"count\": 3,\n        \"entry_ids\": [\n          1822,\n          1817,\n          1801\n        ],\n        \"latest_error_payload\": {\n          \"error\": \"Token refresh failed: invalid_grant\"\n        }\n      },\n      {\n        \"cause_key\": \"status:removed_in_provider\",\n        \"label\": \"Removed in provider\",\n        \"error_class\": null,\n        \"count\": 1,\n        \"entry_ids\": [\n          1755\n        ],\n        \"latest_error_payload\": null\n      }\n    ]\n  }\n}"}]},{"name":"List Stale Pre-Cutover Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/stale-precutover","host":["{{baseUrl}}"],"path":["api","ledger","entries","stale-precutover"]},"description":"Imported pre-cutover journal entries whose SOURCE document was edited after the entry was imported. Automatic generation deliberately never rewrites frozen pre-cutover history, so these entries' figures no longer match their documents — this feed makes that drift visible so it can be fixed deliberately with Rebuild Journal Entry (single) or Bulk Entry Action with action `rebuild`.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:**\n- `count` — total stale entries across all source types\n- `capped` — true when `entries` holds only the first 200 rows. To rebuild everything in one call, use Bulk Entry Action with `action: \"rebuild\"` and `scope: \"all_stale\"` — it targets the full stale set, not just this preview.\n- `entries` — up to 200 rows, most-recently-drifted first. Each row carries the entry identity (`id`, `document_number`, `reference`, `type`, `display_status`), its amounts (`total_debit`, `total_credit`, `currency_code`), its accounting date (`effective_at`), the source document link (`source`), and the drift facts: `source_updated_at` (when the document last changed) vs `imported_at` (when the entry was imported).\n\nReturns `count: 0` with an empty list for tenants without an accounting cutover (no frozen history exists)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/stale-precutover","host":["{{baseUrl}}"],"path":["api","ledger","entries","stale-precutover"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"count\": 3,\n    \"capped\": false,\n    \"entries\": [\n      {\n        \"id\": 8114,\n        \"reference\": \"BILL-1042\",\n        \"reference_suffix\": 0,\n        \"document_number\": \"BILL-8114\",\n        \"type\": {\n          \"value\": \"bill\",\n          \"label\": \"Bill\"\n        },\n        \"display_status\": {\n          \"key\": \"not_synced\",\n          \"label\": \"Not Synced\",\n          \"color\": \"grey\"\n        },\n        \"currency_code\": \"USD\",\n        \"total_debit\": \"1250.0000\",\n        \"total_credit\": \"1250.0000\",\n        \"effective_at\": \"2025-11-14T00:00:00+00:00\",\n        \"source\": {\n          \"type\": \"App\\\\Models\\\\Bill\",\n          \"id\": 1042,\n          \"label\": \"BILL-1042\",\n          \"link_type_label\": \"Bill\",\n          \"link_route\": \"/purchases/bills/1042\",\n          \"link_legacy_url\": null,\n          \"url\": \"/purchases/bills/1042\"\n        },\n        \"source_updated_at\": \"2026-07-08T15:21:44+00:00\",\n        \"imported_at\": \"2026-06-11T03:12:09+00:00\"\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Source Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/source-types","host":["{{baseUrl}}"],"path":["api","ledger","entries","source-types"]},"description":"Distinct source-document origins present on live (non-discarded, non-batch-aggregate) journal entries — powers the entries-list \"Source\" quick filter so it offers only origins the tenant actually has (e.g. \"Amazon Settlement\", \"Sales Order\", \"Bill\"). Lets users isolate settlement-derived bills/invoices that have no batch.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Usage:** each `value` is the backend morph class to pass back as `filter[source_type]=<value>` on `GET /api/ledger/entries`; `label` is the friendly name to display. Options are sorted by label.\n\n**No query parameters.**"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/source-types","host":["{{baseUrl}}"],"path":["api","ledger","entries","source-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"source_types\": [\n      {\n        \"value\": \"Modules\\\\Amazon\\\\Entities\\\\AmazonFinancialEventGroup\",\n        \"label\": \"Amazon Settlement\"\n      },\n      {\n        \"value\": \"App\\\\Models\\\\Bill\",\n        \"label\": \"Bill\"\n      },\n      {\n        \"value\": \"App\\\\Models\\\\PurchaseOrder\",\n        \"label\": \"Purchase Order\"\n      },\n      {\n        \"value\": \"App\\\\Models\\\\SalesOrder\",\n        \"label\": \"Sales Order\"\n      },\n      {\n        \"value\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n        \"label\": \"Sales Order Fulfillment\"\n      }\n    ]\n  }\n}"}]},{"name":"List Provider Statuses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/provider-statuses","host":["{{baseUrl}}"],"path":["api","ledger","entries","provider-statuses"]},"description":"Distinct provider transaction statuses (sync link remote_status — Xero DRAFT/AUTHORISED/PAID/VOIDED, QBO Paid/Open, …) present for the tenant, as {value, label} options for the entries table's Provider Status filter (filter[provider_status]=...). Values are provider-native raw statuses; labels are Title Case.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/provider-statuses","host":["{{baseUrl}}"],"path":["api","ledger","entries","provider-statuses"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"provider_statuses\": [\n      {\n        \"value\": \"AUTHORISED\",\n        \"label\": \"Authorised\"\n      },\n      {\n        \"value\": \"DRAFT\",\n        \"label\": \"Draft\"\n      },\n      {\n        \"value\": \"PAID\",\n        \"label\": \"Paid\"\n      },\n      {\n        \"value\": \"VOIDED\",\n        \"label\": \"Voided\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Journal Entry","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Journal entry detail: everything from the index row plus the detail-only sections —\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `lines` — the GL impact rows (direction, amount, quantity, tax_amount, nominal_code, tax_rate, source_line, role)\n- `invoice_view` — Xero-style invoice document view, present only for invoice-style entry types (sales_order_invoice, batch_sales_order_invoice, purchase_order_invoice, sales_credit, vendor_credit, bill) that resolve at least one product line; `null` for manual journals and quantity-free entries. One row per source line (`item`, `description`, `quantity`, `unit_price`, `discount_amount`, `account`, `tax_rate`, `tax_amount`, `amount`) with a `subtotal` / `discount_total` / `tax_total` / `total` / `currency_code` footer. Money + quantity fields are 4dp strings; `total` = `subtotal` + `tax_total`. Tax and quantity are read from the primary (revenue / COGS / expense) leg only, so they are never double-counted against the auto-booked control leg.\n\n- `sync_links` — provider links with connection identity, remote document type/ID, the provider deep link (`remote_url`, Xero go.xero.com / QBO web-app URL patterns), link_state (unlinked, linked_current, linked_stale, linked_conflict, remote_gone), remote_status and last_remote_seen_at\n- `operations` — the latest 20 sync operations (state, operation create|update|void|delete|link, direction push|pull, error_class, error_payload, attempts, connection) each with its append-only `transitions` audit trail\n- `reversal_chain` — summaries of the linked reversal_of / reversed_by / replaced_by / replaces entries\n\n**counterparty** — the supplier (AP) or customer (AR) the source document is against, as a cross-linkable reference: `{ name, id, link_type_label, link_route }`. Present on the detail path (and the Invoices / Purchase Orders list lenses) whenever the eager-loaded source resolves a party. Four shapes: (1) a linked CRM party — `name` + numeric `id` + `link_type_label` \"Supplier\"/\"Customer\" + `link_route` `/crm/suppliers/{id}` or `/crm/customers/{id}`; (2) a **marketplace-customer fallback** for AR sources (sales order / sales credit) with no CRM customer — `name` is \"{Integration} Customer\" (e.g. \"Amazon Customer\", \"Shopify Customer\"), `link_type_label` \"Customer\", with `id` and `link_route` `null` (no detail page to link to); (3) a **marketplace fallback** for a settlement source (Amazon financial-event group, whose sale + fee legs all net against the marketplace) — `name` is the bare integration name (e.g. \"Amazon\"), `link_type_label` \"Marketplace\", with `id` and `link_route` `null`; (4) a **provider fallback** for a ShipMyOrders provider invoice (a 3PL fulfilment-provider bill carrying no CRM party and no integration instance) — `name` is the fixed label \"SMO\", `link_type_label` \"Provider\", with `id` and `link_route` `null`; (5) the field is **absent entirely** only for sources that resolve none of the above (a manual journal with no source, a native SKU.io order missing its customer, a deleted source) — match it with `if (entry.counterparty)`.\n\n**Sync axes are null for historical entries:** the `sync`, `progress` and `routing` objects each report null key/label/color when an entry has left the live books — it is discarded (superseded by a regenerated replacement: `replaced_by_id` set + `discarded_at`) or a reversed original (`status = reversed`). Such rows can never sync (the batch rollup, reports and live lists all exclude them), so a frozen `enabled`/`synced` axis would mislead; the supersession marker carries the why instead. A live reversal contra entry (`reversal_of_id` set, still posted) is NOT historical and keeps its axes.\n\n**Authentication:** Requires Bearer token.\n\nReturns 404 when the entry does not exist (route is numeric-constrained).\n\nEach line also carries `role` — its economic role within a document-style entry (`primary` product leg, `control` A/R or A/P leg, `tax` leg, or `discount` leg), recovered from the mapped nominal code. The GL Impact table shows the invoiced quantity (and copied line description) on `primary` legs only: v2 copies the quantity onto the control leg too, so a role-blind column would repeat it on Accounts Payable / Receivable and read as a double-count. `role` is `null` on paths that don't load lines.\n\nEach line also carries `pushed_to_provider`: `false` marks the control line (A/R on an Invoice/Credit Note, A/P on a Bill) that the connected provider auto-books itself — SKU omits it from the push, so the GL Impact table dims it. `true` = the line is pushed. `null` when no accounting provider is connected. The entry's `sync_provider` ('Xero' / 'QuickBooks', or `null`) names that provider for the hint.\n\n**`can_sync_now`** (boolean) — whether a manual \"Sync Now\" can push this entry right now. The per-transaction-type Sync toggle, granularity opt-out and the per-type start date only gate *automatic/scheduled* sync; a manual push bypasses them, so `can_sync_now` stays `true` for a benign \"Auto-off\" entry. It is `false` only when a *structural* blocker applies (connection inactive, entry is a batch member / open batch, internal-only, or before the accounting provider's conversion/start date) — those block even a manual push. Drives the UI split between a grey \"Auto-off · push anytime\" chip (`display_status=excluded` + `can_sync_now=true`) and an amber \"Blocked\" chip (`display_status=excluded` + `can_sync_now=false`).\n\n**provider_payment** — for invoice-style entries (sales/purchase invoices, bills) linked to an accounting provider, the paid status + payment metadata: normalized `payment_state` (paid / partially_paid / unpaid / voided), the provider invoice lifecycle `provider_status` (Xero DRAFT/AUTHORISED/PAID/VOIDED), amounts (total/paid/due/credited), the `payments` applied, and provider-dependent `metadata`. Xero is fully populated; QBO is header-only and flagged `data_availability: limited`. `null` for non-invoice or unlinked entries.\n\n**`chain`** — the full reverse+replace lineage for the source document (every version, its reversal contras and the current head), oldest→newest, for a chain-of-events view. Each step: { id, document_number, reference, reference_suffix, status (draft|posted|reversed), role (original|reversal|replacement), is_current, is_viewed, reversal_of_id, replaced_by_id, effective_at, provider_link ({ remote_type, remote_id, remote_url, link_state, remote_status, badge } or null) }. `[]` when the entry has never been reversed or replaced.\n\nAlso returns `sync_override_provenance` (who/what/when set the sync override: `source` = `user` | `legacy_cutover` | `system`, `set_at`, `set_by`; null when no override) and `is_settlement_sourced` (boolean — a marketplace settlement posting, exempt from per-channel sync toggles).\n\n`provider_payment.unreflected_credit_notes` — credit notes the accounting provider has applied to this bill that are not yet reflected in SKU as vendor-credit allocations. Empty when everything reconciles. Each item carries `credit_note_id`, `credit_note_number`, `applied_amount` (applied at the provider), `reflected_amount` (covered by SKU allocations) and `shortfall` (the remaining unreflected amount)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1842,\n    \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n    \"type\": {\n      \"value\": \"sales_order_invoice\",\n      \"label\": \"Sales Order Invoice\"\n    },\n    \"status\": \"posted\",\n    \"display_status\": {\n      \"key\": \"needs_attention\",\n      \"label\": \"Needs attention\",\n      \"color\": \"error\",\n      \"reason\": null\n    },\n    \"can_sync_now\": true,\n    \"locked_update_pending\": false,\n    \"locked_amend_blocked\": false,\n    \"sync\": {\n      \"key\": \"enabled\",\n      \"label\": \"Enabled\",\n      \"color\": \"success\",\n      \"reason\": null\n    },\n    \"progress\": {\n      \"key\": \"needs_attention\",\n      \"label\": \"Needs attention\",\n      \"color\": \"error\",\n      \"via_batch\": false\n    },\n    \"routing\": {\n      \"key\": \"individual\",\n      \"label\": \"Individual\",\n      \"color\": \"grey\",\n      \"batch_id\": null,\n      \"batch_route\": null\n    },\n    \"effective_at\": \"2026-06-05T14:30:00+00:00\",\n    \"posted_at\": \"2026-06-05T14:35:12+00:00\",\n    \"currency_code\": \"USD\",\n    \"total_debit\": \"249.9900\",\n    \"total_credit\": \"249.9900\",\n    \"document_total\": \"249.9900\",\n    \"document_number\": \"INV-1842\",\n    \"reference\": \"SO-10293\",\n    \"reference_suffix\": null,\n    \"description\": \"Sales order invoice for SO-10293\",\n    \"source\": {\n      \"type\": \"App\\\\Models\\\\SalesOrder\",\n      \"id\": 10293,\n      \"label\": \"SO-10293\",\n      \"link_type_label\": \"Sales Order\",\n      \"link_route\": \"/orders/sales-orders/10293\",\n      \"link_legacy_url\": null,\n      \"url\": \"/orders/sales-orders/10293\"\n    },\n    \"counterparty\": {\n      \"name\": \"Acme Retail LLC\",\n      \"id\": 5821,\n      \"link_type_label\": \"Customer\",\n      \"link_route\": \"/crm/customers/5821\"\n    },\n    \"batch_id\": null,\n    \"sync_override\": null,\n    \"sync_override_provenance\": {\n      \"source\": \"user\",\n      \"set_at\": \"2026-07-16T14:00:00+00:00\",\n      \"set_by\": {\n        \"id\": 12,\n        \"name\": \"Julia T\"\n      }\n    },\n    \"is_settlement_sourced\": false,\n    \"sync_provider\": \"Xero\",\n    \"integrity_flag\": null,\n    \"reversal_of_id\": null,\n    \"replaced_by_id\": null,\n    \"created_at\": \"2026-06-05T14:30:02+00:00\",\n    \"invoice_view\": {\n      \"lines\": [\n        {\n          \"item\": \"WIDGET-BLU\",\n          \"description\": \"Blue Widget\",\n          \"quantity\": \"3.0000\",\n          \"unit_price\": \"76.5133\",\n          \"discount_amount\": null,\n          \"account\": {\n            \"nominal_code_id\": 40,\n            \"code\": \"4000\",\n            \"name\": \"Sales Revenue\",\n            \"link_route\": \"/ledger/accounts/40\"\n          },\n          \"tax_rate\": {\n            \"id\": 2,\n            \"name\": \"Tax on Sales (8.875%)\",\n            \"rate\": 8.875\n          },\n          \"tax_amount\": \"20.4500\",\n          \"amount\": \"229.5400\",\n          \"source_line\": {\n            \"type\": \"App\\\\Models\\\\SalesOrderLine\",\n            \"id\": 30412\n          }\n        }\n      ],\n      \"subtotal\": \"229.5400\",\n      \"discount_total\": \"0.0000\",\n      \"tax_total\": \"20.4500\",\n      \"total\": \"249.9900\",\n      \"currency_code\": \"USD\"\n    },\n    \"provider_payment\": {\n      \"provider\": \"xero\",\n      \"provider_label\": \"Xero\",\n      \"document_type\": \"invoice\",\n      \"provider_status\": \"PAID\",\n      \"provider_status_label\": \"Paid\",\n      \"provider_status_color\": \"success\",\n      \"payment_state\": \"paid\",\n      \"currency_code\": \"USD\",\n      \"total\": \"100.0000\",\n      \"amount_paid\": \"100.0000\",\n      \"amount_due\": \"0.0000\",\n      \"amount_credited\": \"0.0000\",\n      \"sub_total\": \"90.0000\",\n      \"tax_total\": \"10.0000\",\n      \"due_date\": \"2026-01-31T00:00:00+00:00\",\n      \"fully_paid_on\": \"2026-12-02T00:00:00+00:00\",\n      \"document_date\": \"2026-12-01T00:00:00+00:00\",\n      \"provider_url\": \"https://go.xero.com/AccountsReceivable/View.aspx?InvoiceID=6b1e...INV\",\n      \"payments\": [\n        {\n          \"date\": \"2026-12-02T00:00:00+00:00\",\n          \"amount\": \"100.0000\",\n          \"reference\": \"CHK-1042\",\n          \"type\": \"ACCRECPAYMENT\",\n          \"status\": \"AUTHORISED\",\n          \"is_reconciled\": true,\n          \"bank_account\": \"Business Bank Account\",\n          \"provider_payment_id\": \"b1c2d3e4-5678-90ab-cdef-1234567890ab\",\n          \"provider_url\": \"https://go.xero.com/Bank/ViewTransaction.aspx?bankTransactionID=b1c2d3e4-5678-90ab-cdef-1234567890ab\",\n          \"link_route\": \"/integrations/xero/payments/42\",\n          \"link_type_label\": \"Xero Payment\",\n          \"link_id\": 42\n        }\n      ],\n      \"metadata\": [\n        {\n          \"label\": \"Currency Rate\",\n          \"value\": \"1.000000\"\n        },\n        {\n          \"label\": \"Sent To Contact\",\n          \"value\": \"Yes\"\n        }\n      ],\n      \"data_availability\": \"full\",\n      \"availability_message\": null,\n      \"last_synced_at\": \"2026-12-02T04:15:00+00:00\",\n      \"unreflected_credit_notes\": []\n    },\n    \"lines\": [\n      {\n        \"id\": 5210,\n        \"direction\": \"debit\",\n        \"amount\": \"249.9900\",\n        \"quantity\": null,\n        \"tax_amount\": \"20.4500\",\n        \"description\": \"Accounts receivable\",\n        \"nominal_code\": {\n          \"id\": 12,\n          \"code\": \"1100\",\n          \"name\": \"Accounts Receivable\"\n        },\n        \"tax_rate\": null,\n        \"source_line\": null,\n        \"role\": \"control\",\n        \"pushed_to_provider\": false\n      },\n      {\n        \"id\": 5211,\n        \"direction\": \"credit\",\n        \"amount\": \"229.5400\",\n        \"quantity\": \"3.0000\",\n        \"tax_amount\": null,\n        \"description\": \"Product sales\",\n        \"nominal_code\": {\n          \"id\": 40,\n          \"code\": \"4000\",\n          \"name\": \"Sales Revenue\"\n        },\n        \"tax_rate\": {\n          \"id\": 2,\n          \"name\": \"Tax on Sales (8.875%)\"\n        },\n        \"source_line\": {\n          \"type\": \"App\\\\Models\\\\SalesOrderLine\",\n          \"id\": 30412\n        },\n        \"role\": \"primary\",\n        \"pushed_to_provider\": true\n      },\n      {\n        \"id\": 5212,\n        \"direction\": \"credit\",\n        \"amount\": \"20.4500\",\n        \"quantity\": null,\n        \"tax_amount\": null,\n        \"description\": \"Sales tax payable\",\n        \"nominal_code\": {\n          \"id\": 45,\n          \"code\": \"2200\",\n          \"name\": \"Sales Tax Payable\"\n        },\n        \"tax_rate\": {\n          \"id\": 2,\n          \"name\": \"Tax on Sales (8.875%)\"\n        },\n        \"source_line\": null,\n        \"role\": \"tax\",\n        \"pushed_to_provider\": true\n      }\n    ],\n    \"sync_links\": [\n      {\n        \"id\": 311,\n        \"provider\": \"qbo\",\n        \"connection\": {\n          \"id\": 3,\n          \"name\": \"QuickBooks Online\"\n        },\n        \"remote_type\": \"Invoice\",\n        \"remote_id\": \"4412\",\n        \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=4412\",\n        \"link_state\": \"linked_stale\",\n        \"remote_status\": \"Open\",\n        \"last_remote_seen_at\": \"2026-06-08T03:12:00+00:00\"\n      }\n    ],\n    \"operations\": [\n      {\n        \"id\": 9907,\n        \"state\": \"needs_action\",\n        \"operation\": \"update\",\n        \"direction\": \"push\",\n        \"error_class\": \"user_action_required\",\n        \"retry_disposition\": \"needs_action\",\n        \"error_payload\": {\n          \"message\": \"Duplicate Document Number Error : You must specify a different number. This number has already been used.\",\n          \"user_title\": \"A document with this reference already exists in QuickBooks\",\n          \"user_message\": \"QuickBooks rejected this as a duplicate of a document that already exists. Review whether it is the same document before re-syncing.\",\n          \"provider_code\": \"6240\",\n          \"retry_disposition\": \"needs_action\"\n        },\n        \"attempts\": 1,\n        \"connection\": {\n          \"id\": 3,\n          \"name\": \"QuickBooks Online\"\n        },\n        \"created_at\": \"2026-06-08T03:10:00+00:00\",\n        \"started_at\": \"2026-06-08T03:10:05+00:00\",\n        \"finished_at\": \"2026-06-08T03:10:06+00:00\",\n        \"transitions\": [\n          {\n            \"from\": null,\n            \"to\": \"pending\",\n            \"reason\": \"enqueued\",\n            \"created_at\": \"2026-06-08T03:10:00+00:00\"\n          },\n          {\n            \"from\": \"pending\",\n            \"to\": \"in_flight\",\n            \"reason\": \"dispatched\",\n            \"created_at\": \"2026-06-08T03:10:05+00:00\"\n          },\n          {\n            \"from\": \"in_flight\",\n            \"to\": \"needs_action\",\n            \"reason\": \"provider_validation: Account 4000 Sales Revenue is inactive\",\n            \"created_at\": \"2026-06-08T03:10:06+00:00\"\n          }\n        ]\n      }\n    ],\n    \"reversal_chain\": {\n      \"reversal_of\": null,\n      \"reversed_by\": null,\n      \"replaced_by\": null,\n      \"replaces\": {\n        \"id\": 1790,\n        \"document_number\": \"JE-1790\",\n        \"reference\": \"SO-10293\",\n        \"status\": \"reversed\"\n      }\n    },\n    \"provider_link\": null,\n    \"chain\": [\n      {\n        \"id\": 1839,\n        \"document_number\": \"VC-1839\",\n        \"reference\": 1668,\n        \"reference_suffix\": 0,\n        \"status\": \"reversed\",\n        \"role\": \"original\",\n        \"is_current\": false,\n        \"is_viewed\": true,\n        \"reversal_of_id\": null,\n        \"replaced_by_id\": 1842,\n        \"effective_at\": \"2026-02-28T08:00:00+00:00\",\n        \"provider_link\": {\n          \"remote_type\": \"xero_credit_note\",\n          \"remote_id\": \"2643cbf7-ea33-460d-9d30-301fac99f609\",\n          \"remote_url\": \"https://go.xero.com/AccountsPayable/ViewCreditNote.aspx?creditNoteID=2643cbf7-ea33-460d-9d30-301fac99f609\",\n          \"link_state\": \"remote_gone\",\n          \"remote_status\": \"VOIDED\",\n          \"badge\": \"Voided\"\n        }\n      },\n      {\n        \"id\": 1841,\n        \"document_number\": \"VC-1841\",\n        \"reference\": 1668,\n        \"reference_suffix\": 0,\n        \"status\": \"posted\",\n        \"role\": \"reversal\",\n        \"is_current\": false,\n        \"is_viewed\": false,\n        \"reversal_of_id\": 1839,\n        \"replaced_by_id\": null,\n        \"effective_at\": \"2026-02-28T08:00:00+00:00\",\n        \"provider_link\": null\n      },\n      {\n        \"id\": 1842,\n        \"document_number\": \"VC-1842\",\n        \"reference\": \"0001668/R1\",\n        \"reference_suffix\": 1,\n        \"status\": \"draft\",\n        \"role\": \"replacement\",\n        \"is_current\": true,\n        \"is_viewed\": false,\n        \"reversal_of_id\": null,\n        \"replaced_by_id\": null,\n        \"effective_at\": \"2026-02-28T08:00:00+00:00\",\n        \"provider_link\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Journal Entry Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/lines","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","lines"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"The entry's GL-impact journal lines — a lightweight cousin of **Get Journal Entry** that returns only the `lines` array (no sync_links, operations or reversal_chain). Drives the entries table's inline \"Lines\" row expansion.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nLines are ordered GL-impact-first: debits before credits, each ordered by nominal code.\n\nEach line includes:\n- `direction` — `debit` or `credit`\n- `amount` — the extended (line total) amount as a string\n- `quantity`, `tax_amount` — strings, or null\n- `nominal_code` — `{ id, code, name }` of the account the line posts to\n- `is_overridden` — true when a durable override remapped this line's account\n- `nominal_code_original` — the account it WOULD have derived to (non-null only when overridden), drives the `<derived> → <override>` display\n- `tax_rate` — `{ id, name }` or null\n- `source_line` — `{ type, id }` of the originating document line, or null\n- `role` — economic role within a document-style entry: `primary` (product leg), `control` (A/R or A/P leg), `tax`, or `discount`, recovered from the mapped nominal code. The GL Impact table shows the invoiced quantity on `primary` legs only (v2 copies the quantity onto the control leg, so a role-blind column would double-count it); `null` on paths that don't load lines\n- `pushed_to_provider` — `false` marks the control line (A/R on an Invoice/Credit Note, A/P on a Bill) that the connected provider auto-books itself, so SKU omits it from the push and the GL Impact table dims it; `true` = pushed; `null` when no accounting provider is connected\n\n**Authentication:** Requires Bearer token.\n\nReturns 404 when the entry does not exist (route is numeric-constrained)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/lines","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","lines"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5501,\n      \"direction\": \"debit\",\n      \"amount\": \"1200.00\",\n      \"quantity\": \"10\",\n      \"tax_amount\": \"0.00\",\n      \"description\": \"Inventory received — Widget A\",\n      \"nominal_code\": {\n        \"id\": 31,\n        \"code\": \"500\",\n        \"name\": \"Cost of Goods Sold\"\n      },\n      \"is_overridden\": false,\n      \"nominal_code_original\": null,\n      \"tax_rate\": {\n        \"id\": 4,\n        \"name\": \"No VAT\"\n      },\n      \"source_line\": {\n        \"type\": \"App\\\\Models\\\\PurchaseInvoiceLine\",\n        \"id\": 8842\n      },\n      \"role\": \"primary\",\n      \"pushed_to_provider\": true\n    },\n    {\n      \"id\": 5502,\n      \"direction\": \"credit\",\n      \"amount\": \"1200.00\",\n      \"quantity\": null,\n      \"tax_amount\": \"0.00\",\n      \"description\": \"Accounts Payable — Acme Supplies\",\n      \"nominal_code\": {\n        \"id\": 80,\n        \"code\": \"800\",\n        \"name\": \"Accounts Payable\"\n      },\n      \"is_overridden\": false,\n      \"nominal_code_original\": null,\n      \"tax_rate\": null,\n      \"source_line\": null,\n      \"role\": \"control\",\n      \"pushed_to_provider\": false\n    }\n  ]\n}"}]},{"name":"Get Journal Entry Attachment Sync","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/attachment-sync","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","attachment-sync"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"The sync state of each source-document file attachment across every connection. When the entry's source document (purchase invoice, vendor credit, or vendor deposit) has attachments, this returns one row per (attachment × connection) describing whether the file was uploaded to the matching Xero/QBO document.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns an empty `data` array when the source has no attachments, no attachment concept, or nothing has been attempted yet.\n\nEach row includes:\n- `source_attachment_id` — the SKU attachment row id\n- `file_name` — the source file's display name\n- `connection_id`, `provider` — the accounting connection and its integration name (e.g. `Xero`, `QuickBooks Online`)\n- `remote_type`, `remote_id` — the provider document the file is attached to (e.g. `qbo_vendor_credit`)\n- `remote_attachment_id` — the Xero AttachmentID / QBO Attachable.Id (null while failed/pending)\n- `status` — `synced`, `failed`, or `pending`\n- `last_error` — failure reason (null on success)\n- `synced_at` — ISO-8601 UTC timestamp of the last successful upload (null otherwise)\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/attachment-sync","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","attachment-sync"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"source_attachment_id\": 8841,\n      \"file_name\": \"supplier-invoice.pdf\",\n      \"connection_id\": 12,\n      \"provider\": \"Xero\",\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"b1f0e2c4-6fce-4330-bb3b-8306278c6fd8\",\n      \"remote_attachment_id\": \"a77c1e90-2b1f-4d0a-9d1e-9a2b3c4d5e6f\",\n      \"status\": \"synced\",\n      \"last_error\": null,\n      \"synced_at\": \"2026-07-02T14:12:05+00:00\"\n    },\n    {\n      \"id\": 5013,\n      \"source_attachment_id\": 8842,\n      \"file_name\": \"delivery-note.pdf\",\n      \"connection_id\": 12,\n      \"provider\": \"Xero\",\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"b1f0e2c4-6fce-4330-bb3b-8306278c6fd8\",\n      \"remote_attachment_id\": null,\n      \"status\": \"failed\",\n      \"last_error\": \"Skipped: file exceeds the provider attachment size limit of 25MB.\",\n      \"synced_at\": null\n    }\n  ]\n}"}]},{"name":"Rebuild Journal Entry","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","rebuild"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Rebuild the entry's SOURCE document INLINE (single-entry action): the user clicked Rebuild on the entry detail page and expects the regenerated entry to be current the instant the request returns, not after the async drain catches up. The rebuild writes the same `updated` outbox row a real source mutation rides, then processes JUST that row synchronously through the shared outbox processor (build → persistSet → batch-assign → sync-select) — so posted-immutability (reversal + replacement) holds exactly as on the async path.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nTwo cases fall back to the queue instead of running inline (the message says which):\n- **Batch-aggregate entries** (source = a LedgerBatch) ride the batch state machine (markDirty + a background job) — identical effect to POST /api/ledger/batches/{batch}/rebuild.\n- **Generation disabled** (the `ledger.generation_enabled` kill-switch is off): the `updated` row is parked for whenever the drain next runs.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Response:** 200 with a `message`. When the rebuild ran inline the message is \"Entry rebuilt from its source document.\"; on the queued fallback it is \"Rebuild queued — the entry will regenerate from its source document shortly.\" (App\\Response normalizes every 2xx to 200.) Returns 404 when the entry does not exist.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","rebuild"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Entry rebuilt from its source document.\"\n}"}]},{"name":"Refresh Journal Entry","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/refresh","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","refresh"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Refresh this entry's amounts from its SOURCE document IN PLACE — the light counterpart to Rebuild. Where Rebuild corrects a posted entry by writing a reversal + a replacement, Refresh re-derives the entry's lines and totals and writes them onto the SAME entry: its id, status and accounting-provider link are all kept, so a posted, already-synced entry whose local figure drifted is corrected WITHOUT creating a new entry and WITHOUT touching the linked Xero / QuickBooks document. After the rewrite the sync state is re-graded — a still-editable remote is offered an update, while a settled/locked or voided remote is left as-is (nothing is pushed).\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Response:** 200 with `data.refresh` ({ refreshed, reason, period_locked }) and `data.entry` (the refreshed entry object). `refreshed` is false with a `reason` when there is nothing to do: `already_current` (the entry already matches its source), `batched` (the entry rolls into a batch aggregate — rebuild the batch instead), `generation_disabled`, or `source_no_longer_produces_entry` (the source stopped producing this entry — use Rebuild to reverse it). `period_locked` is reported (never enforced): true when the entry is dated in a locked accounting period, so the caller can warn that an in-place edit changes a closed period. `message` summarises the outcome.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it; 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/refresh","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","refresh"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"refresh\": {\n      \"refreshed\": true,\n      \"reason\": null,\n      \"period_locked\": false\n    },\n    \"entry\": {\n      \"id\": 1842,\n      \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n      \"type\": {\n        \"value\": \"purchase_order_invoice\",\n        \"label\": \"Purchase Order Invoice\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"locked\",\n        \"label\": \"Synced, Locked\",\n        \"color\": \"info\",\n        \"reason\": null\n      },\n      \"can_sync_now\": false,\n      \"effective_at\": \"2026-06-05T14:30:00+00:00\",\n      \"posted_at\": \"2026-06-05T14:35:12+00:00\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"4631.0400\",\n      \"total_credit\": \"4631.0400\",\n      \"reference\": \"BILL-10293\",\n      \"sync_links\": [\n        {\n          \"id\": 55,\n          \"provider\": \"xero\",\n          \"remote_type\": \"xero_bill\",\n          \"remote_id\": \"54bccb09-ffa1-4309-8caf-4f78a09b493a\",\n          \"link_state\": \"remote_locked\",\n          \"remote_status\": \"PAID\"\n        }\n      ],\n      \"operations\": []\n    }\n  },\n  \"message\": \"Refreshed from its source document — the provider link was kept.\"\n}"}]},{"name":"Resync Entry to Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync"],"variable":[{"key":"entry","value":"8114","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Push this SINGLE entry to the connected accounting provider SYNCHRONOUSLY (InlineLedgerSyncRunner): the provider round-trip runs inline within the request, so the response already reflects the real Synced / Failed outcome — there is no interim \"queued\" state to poll. This powers the entry detail page's \"Resync Now\" button and its live \"talking to the provider\" animation. The bulk equivalent — `POST /api/ledger/entries/bulk` with action `sync_now` — stays an async tracked job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Locked documents:** when the provider document is paid/settled (locked), amounts and dates cannot be pushed. Resync instead pushes only the fields the provider still allows editing on a locked document (the reference/number) and reports `amended: true`. The entry keeps its \"Synced, Locked\" status; if the reference change covered all the local drift, the pending-update flag clears. To push amount or date changes, remove the payment or credit note on the provider document first, then Resync. **Fully-locked documents:** some provider document types (for example a credit note with a payment or allocation applied) are locked so hard that even the reference cannot be pushed. For those, Resync mints no operation and reports `locked_blocked: true`, and the entry carries a `locked_amend_blocked` flag; nothing changes on the provider until the payment or allocation is removed there.\n\n**Behaviour:** mints the entry's manual push op (manual eligibility bypasses the soft per-type Sync toggle but NOT structural blockers — connection inactive, batch member / open batch, internal-only, or before the provider start date) and drives it to the provider in-process. A no-op (still reports `synced` when already linked-current) when the entry's content hash matches the last sync, or `eligible: false` when nothing can be pushed.\n\n**First-push regeneration:** when the entry is imported pre-cutover history that has NEVER been synced (no link on any connection), it is first rebuilt with the current posting rules so the provider's first copy reflects current logic rather than the migrated import. The rebuild may replace the entry with a successor — `data.sync.entry_id` is the entry the push actually ran against and `data.entry` is that (possibly new) entry.\n\n**Response:** 200 with `data.sync` ({ eligible, synced, failed, amended, locked_blocked, error, regenerated, entry_id }) and `data.entry` (the refreshed ledger entry object, which includes a `locked_amend_blocked` flag). `error` carries the provider rejection message when `failed` is true. `locked_blocked` is true when the provider document is fully locked and not even the reference could be pushed. `message` summarises the outcome.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it; 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync"],"variable":[{"key":"entry","value":"8114","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sync\": {\n      \"eligible\": true,\n      \"synced\": true,\n      \"failed\": false,\n      \"amended\": false,\n      \"error\": null,\n      \"regenerated\": false,\n      \"entry_id\": 8114\n    },\n    \"entry\": {\n      \"id\": 8114,\n      \"type\": {\n        \"value\": \"bill\",\n        \"label\": \"Bill\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"color\": \"success\",\n        \"reason\": null\n      },\n      \"can_sync_now\": true,\n      \"locked_update_pending\": false,\n      \"locked_amend_blocked\": false,\n      \"counterparty_name\": \"Amazon\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"842.6700\",\n      \"total_credit\": \"842.6700\",\n      \"document_number\": \"BILL-8114\",\n      \"reference\": \"5cKTkaXNDpXqmNv0MzaOHAMppp6CsZOYXrgMbDv4UDg\",\n      \"sync_provider\": \"Xero\",\n      \"sync_links\": [\n        {\n          \"id\": 5521,\n          \"provider\": \"Xero\",\n          \"remote_type\": \"bill\",\n          \"remote_id\": \"57406763-6b49-4be8-98b5-16750c106f6e\",\n          \"link_state\": \"linked_current\",\n          \"remote_status\": \"AUTHORISED\",\n          \"last_remote_seen_at\": \"2026-06-30T01:41:05+00:00\"\n        }\n      ],\n      \"operations\": [\n        {\n          \"id\": 90211,\n          \"state\": \"succeeded\",\n          \"operation\": \"create\",\n          \"direction\": \"push\",\n          \"error_class\": null,\n          \"error_payload\": null,\n          \"attempts\": 1,\n          \"finished_at\": \"2026-06-30T01:41:05+00:00\"\n        }\n      ]\n    }\n  },\n  \"message\": \"Pushed to the provider — this entry is up to date.\"\n}"}]},{"name":"Preview Bill Settlement With Vendor Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/settlement-preview","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","settlement-preview"],"variable":[{"key":"entry","value":"9609","description":"Ledger journal entry ID (numeric) — must be a bill (purchase invoice) entry. Route-model bound — returns 404 if the entry does not exist."}]},"description":"Preview the plan to settle a bill (a purchase-invoice entry) using the vendor credits already allocated against it — the read side of the \"sync & mark paid\" flow. Reports whether the entry is a settleable bill, whether the bill itself is synced to the accounting provider, and the state of each applied vendor credit: `missing_transaction` (its accounting transaction has not been generated yet), `unsynced` (generated but not pushed to the provider), or `synced` (its credit note is pushed and its allocation applied). Use it to show exactly what will happen before committing.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Response:** 200 with `data.settlement`: `is_settleable_bill`, `bill_synced`, `already_settled`, `needs_action`, `credit_count`, `allocated_total`, `outstanding_balance`, `currency_code`, and `credits[]` (each carries `vendor_credit_id`, `allocation_id`, `vendor_credit_number`, `vendor_credit_route`, `allocation_amount`, `state`, `ledger_entry_id`, `ledger_entry_route`). When the entry is not a bill with allocated vendor credits, `is_settleable_bill` is false and `credits` is empty. Returns 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/settlement-preview","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","settlement-preview"],"variable":[{"key":"entry","value":"9609","description":"Ledger journal entry ID (numeric) — must be a bill (purchase invoice) entry. Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"settlement\": {\n      \"is_settleable_bill\": true,\n      \"bill_synced\": true,\n      \"already_settled\": false,\n      \"needs_action\": true,\n      \"credit_count\": 4,\n      \"allocated_total\": \"2084.52\",\n      \"outstanding_balance\": \"2084.52\",\n      \"currency_code\": \"USD\",\n      \"credits\": [\n        {\n          \"vendor_credit_id\": 312,\n          \"allocation_id\": 907,\n          \"vendor_credit_number\": \"VC-000312\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/312\",\n          \"allocation_amount\": \"500.00\",\n          \"state\": \"unsynced\",\n          \"ledger_entry_id\": 9720,\n          \"ledger_entry_route\": \"/ledger/entries/9720\"\n        },\n        {\n          \"vendor_credit_id\": 313,\n          \"allocation_id\": 908,\n          \"vendor_credit_number\": \"VC-000313\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/313\",\n          \"allocation_amount\": \"600.00\",\n          \"state\": \"missing_transaction\",\n          \"ledger_entry_id\": null,\n          \"ledger_entry_route\": null\n        },\n        {\n          \"vendor_credit_id\": 314,\n          \"allocation_id\": 909,\n          \"vendor_credit_number\": \"VC-000314\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/314\",\n          \"allocation_amount\": \"484.52\",\n          \"state\": \"unsynced\",\n          \"ledger_entry_id\": 9721,\n          \"ledger_entry_route\": \"/ledger/entries/9721\"\n        },\n        {\n          \"vendor_credit_id\": 315,\n          \"allocation_id\": 910,\n          \"vendor_credit_number\": \"VC-000315\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/315\",\n          \"allocation_amount\": \"500.00\",\n          \"state\": \"synced\",\n          \"ledger_entry_id\": 9722,\n          \"ledger_entry_route\": \"/ledger/entries/9722\"\n        }\n      ]\n    }\n  },\n  \"message\": \"This bill has 4 vendor credits allocated — 3 still need to be applied on the provider to mark it paid.\"\n}"}]},{"name":"Settle Bill With Vendor Credits","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-and-settle","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-and-settle"],"variable":[{"key":"entry","value":"9609","description":"Ledger journal entry ID (numeric) — must be a bill (purchase invoice) entry. Route-model bound — returns 404 if the entry does not exist."}]},"description":"Settle a bill (a purchase-invoice entry) using the vendor credits allocated against it so the connected accounting provider marks the bill PAID — the missing half of two-way sync when the allocations exist here but were never pushed. Dispatches a tracked background job that (1) syncs the bill so its remote document exists, (2) for each applied vendor credit generates its accounting transactions if missing, syncs its credit note, then pushes the allocation (Xero credit-note allocation / QuickBooks zero-dollar bill payment), and (3) re-reads the bill so its link re-grades to Synced, Locked (paid). Idempotent — re-running skips work already done, so a partial failure is safe to retry.\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission (403 without it).\n\n**Request body:** none.\n\n**Response:** 200 with `data.tracked_job_log_id` (poll for progress) and `data.settlement` (the pre-run snapshot, same shape as Preview Bill Settlement). When the bill is already settled by its credits, returns 200 with just `data.settlement` and no job. Returns 422 when the entry is not a bill with vendor credits allocated. Returns 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-and-settle","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-and-settle"],"variable":[{"key":"entry","value":"9609","description":"Ledger journal entry ID (numeric) — must be a bill (purchase invoice) entry. Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 44821,\n    \"settlement\": {\n      \"is_settleable_bill\": true,\n      \"bill_synced\": true,\n      \"already_settled\": false,\n      \"needs_action\": true,\n      \"credit_count\": 4,\n      \"allocated_total\": \"2084.52\",\n      \"outstanding_balance\": \"2084.52\",\n      \"currency_code\": \"USD\",\n      \"credits\": [\n        {\n          \"vendor_credit_id\": 312,\n          \"allocation_id\": 907,\n          \"vendor_credit_number\": \"VC-000312\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/312\",\n          \"allocation_amount\": \"500.00\",\n          \"state\": \"unsynced\",\n          \"ledger_entry_id\": 9720,\n          \"ledger_entry_route\": \"/ledger/entries/9720\"\n        },\n        {\n          \"vendor_credit_id\": 313,\n          \"allocation_id\": 908,\n          \"vendor_credit_number\": \"VC-000313\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/313\",\n          \"allocation_amount\": \"600.00\",\n          \"state\": \"missing_transaction\",\n          \"ledger_entry_id\": null,\n          \"ledger_entry_route\": null\n        },\n        {\n          \"vendor_credit_id\": 314,\n          \"allocation_id\": 909,\n          \"vendor_credit_number\": \"VC-000314\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/314\",\n          \"allocation_amount\": \"484.52\",\n          \"state\": \"unsynced\",\n          \"ledger_entry_id\": 9721,\n          \"ledger_entry_route\": \"/ledger/entries/9721\"\n        },\n        {\n          \"vendor_credit_id\": 315,\n          \"allocation_id\": 910,\n          \"vendor_credit_number\": \"VC-000315\",\n          \"vendor_credit_route\": \"/v2/vendor-credits/315\",\n          \"allocation_amount\": \"500.00\",\n          \"state\": \"synced\",\n          \"ledger_entry_id\": 9722,\n          \"ledger_entry_route\": \"/ledger/entries/9722\"\n        }\n      ]\n    }\n  },\n  \"message\": \"Settling the bill with its vendor credits — track progress in the job tracker.\"\n}"}]},{"name":"Clear Sync Errors","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/clear-errors","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","clear-errors"],"variable":[{"key":"entry","value":"8114","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Dismiss THIS single entry's parked sync errors (needs_action / failed_retryable) SYNCHRONOUSLY by superseding its open sync operations across every connection, then return the refreshed entry so the detail page drops the error banner without a page refresh. This powers the entry detail page's \"Clear errors\" button.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIt clears the error WITHOUT auto-retrying — the user runs Resync Now afterwards to re-attempt the push. The bulk equivalent — `POST /api/ledger/entries/bulk` with action `clear_errors` — stays an async tracked job for multi-entry selections.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Behaviour:** transitions the entry's open operations (except InFlight) to `Superseded` per connection, then recomputes and refreshes the entry's display status. A no-op (`cleared: false`) when the entry has no open sync errors.\n\n**Response:** 200 with `data.cleared` (bool — whether any open ops were superseded) and `data.entry` (the refreshed ledger entry object, whose `display_status` no longer reports needs_attention). `message` summarises the outcome.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it; 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/clear-errors","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","clear-errors"],"variable":[{"key":"entry","value":"8114","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"cleared\": true,\n    \"entry\": {\n      \"id\": 8114,\n      \"type\": {\n        \"value\": \"bill\",\n        \"label\": \"Bill\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"not_synced\",\n        \"label\": \"Not Synced\",\n        \"color\": \"grey\",\n        \"reason\": null\n      },\n      \"can_sync_now\": true,\n      \"locked_update_pending\": false,\n      \"locked_amend_blocked\": false,\n      \"counterparty_name\": \"Amazon\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"842.6700\",\n      \"total_credit\": \"842.6700\",\n      \"document_number\": \"BILL-8114\",\n      \"reference\": \"5cKTkaXNDpXqmNv0MzaOHAMppp6CsZOYXrgMbDv4UDg\",\n      \"sync_provider\": \"Xero\",\n      \"operations\": [\n        {\n          \"id\": 90244,\n          \"state\": \"superseded\",\n          \"operation\": \"create\",\n          \"direction\": \"push\",\n          \"error_class\": null,\n          \"error_payload\": null,\n          \"attempts\": 2,\n          \"finished_at\": \"2026-06-30T01:41:05+00:00\"\n        }\n      ]\n    }\n  },\n  \"message\": \"Sync errors cleared — run Sync now to re-attempt.\"\n}"}]},{"name":"Recreate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/recreate","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","recreate"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"\"Recreate document\" for an entry whose remote document was VOIDED or DELETED in the accounting provider (display_status `voided` — \"Synced, Voided\" — or `removed_in_provider` — \"Synced, Deleted\"). Once a provider document is voided/deleted there is nothing left to update on it, so this reverse+replaces the entry into a fresh UNLINKED draft replacement and mints it from the same source, even though the source itself never changed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe dead provider link is RETAINED on the reversed original as the historical record; the replacement starts with NO provider link and is chained via replaced_by_id, so the detail view shows a \"Replaces …\" link. This action does NOT push and does NOT touch the dead document — the user syncs the fresh draft to push a brand-new document on demand.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Response:** 200 with `data.recreate` ({ recreated, status, reason, replacement_id }) and `data.entry` (the now-reversed original). `replacement_id` is the id of the fresh unlinked draft. `recreated` is false with reason `not_voided` (nothing voided to replace), `generation_disabled`, or `source_not_accounting_ready` (the source no longer produces an entry). Returns 404 when the entry does not exist.\n\nPermission: requires `accounting.sync`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/recreate","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","recreate"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"recreate\": {\n      \"recreated\": true,\n      \"status\": \"voided\",\n      \"reason\": null,\n      \"replacement_id\": 1843\n    },\n    \"entry\": {\n      \"id\": 1842,\n      \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n      \"type\": {\n        \"value\": \"vendor_credit\",\n        \"label\": \"Vendor Credit\"\n      },\n      \"status\": \"reversed\",\n      \"display_status\": {\n        \"key\": \"voided\",\n        \"label\": \"Synced, Voided\",\n        \"color\": \"warning\",\n        \"reason\": null\n      },\n      \"can_sync_now\": false,\n      \"locked_update_pending\": false,\n      \"locked_amend_blocked\": false,\n      \"effective_at\": \"2026-02-28T08:00:00+00:00\",\n      \"posted_at\": \"2026-02-28T08:05:00+00:00\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"600.0000\",\n      \"total_credit\": \"600.0000\",\n      \"document_number\": \"VC-11036\",\n      \"reference\": \"0001668/R1\",\n      \"replaced_by_id\": 1843,\n      \"sync_links\": [\n        {\n          \"id\": 819,\n          \"provider\": \"xero\",\n          \"connection\": {\n            \"id\": 30,\n            \"name\": \"Xero\"\n          },\n          \"remote_type\": \"xero_credit_note\",\n          \"remote_id\": \"2643cbf7-ea33-460d-9d30-301fac99f609\",\n          \"remote_url\": \"https://go.xero.com/AccountsPayable/ViewCreditNote.aspx?creditNoteID=2643cbf7-ea33-460d-9d30-301fac99f609\",\n          \"link_state\": \"remote_gone\",\n          \"remote_status\": \"VOIDED\",\n          \"last_remote_seen_at\": \"2026-07-13T22:40:00+00:00\"\n        }\n      ],\n      \"operations\": []\n    }\n  },\n  \"message\": \"Created a fresh draft that replaces this entry — the voided document stays on the original for the record. Sync the new draft when you are ready to push a brand-new document.\"\n}"}]},{"name":"List Relink Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/relink-candidates","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","relink-candidates"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Provider documents this voided or deleted entry could be linked to INSTEAD of recreating one — the confidence-ranked \"link to an existing document\" picker. Use this when the accounting document was voided in the provider and a replacement already exists there (e.g. a bill was voided and re-raised): rather than minting a duplicate, adopt the document that is already in the provider.\n\nReads the provider-document cache for the connection of the entry's voided link and returns the unlinked documents of the same kind, ranked best-first. Each candidate carries per-signal match flags — `amount_match`, `date_match`, `reference_match`, and `confident` (amount AND date within tolerance) — so the top result is usually the correct replacement. Documents already linked to another entry, or themselves voided/deleted, are excluded. Documents dismissed on the reconcile screen are still offered — flagged `dismissed: true` and ranked below equally-confident undismissed candidates; linking one clears its dismissal. Returns an empty list when the entry has no voided/deleted link to recover.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `search` (optional) — free-text narrowing.\n\n**Response:** 200 with `data` as an array of candidate documents ordered most-confident first."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/relink-candidates","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","relink-candidates"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"connection_id\": 30,\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"54f0b7b3-9537-447a-bda2-897f7da26e9f\",\n      \"reference\": \"PO-0327: INVCBUSA-2000001.1\",\n      \"total\": \"49063.4000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2025-09-22\",\n      \"status\": \"AUTHORISED\",\n      \"amount_match\": true,\n      \"date_match\": true,\n      \"reference_match\": true,\n      \"confident\": true,\n      \"dismissed\": false\n    },\n    {\n      \"connection_id\": 30,\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"11c2a7d0-882e-4a19-9f6b-73c0d9a1e2ff\",\n      \"reference\": \"PO-0299\",\n      \"total\": \"1204.0000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2025-09-03\",\n      \"status\": \"AUTHORISED\",\n      \"amount_match\": false,\n      \"date_match\": false,\n      \"reference_match\": false,\n      \"confident\": false,\n      \"dismissed\": true\n    }\n  ]\n}"}]},{"name":"List Document Link Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/link-candidates","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","link-candidates"],"variable":[{"key":"entry","value":"10927","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Provider documents an unmatched ledger entry could be linked to for the first time — the confidence-ranked picker for pointing a never-linked SKU entry at the document it already corresponds to in the provider (e.g. a bill that was imported into the provider some other way), instead of syncing a duplicate. This is the sibling of List Relink Candidates, which recovers a voided/deleted link; this one is for an entry that has never been linked.\n\nReads the provider-document cache for the tenant's accounting connection and returns the unlinked documents ranked best-first. Each candidate carries per-signal match flags — `amount_match`, `date_match`, `reference_match`, and `confident` (amount AND date within tolerance). Documents already linked to another entry are excluded. Documents dismissed on the reconcile screen are still offered — flagged `dismissed: true` and ranked below equally-confident undismissed candidates; linking one clears its dismissal. Returns an empty list when the entry is already linked. Link the chosen document with POST /api/ledger/reconciliation/link.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `search` (optional) — free-text narrowing.\n\n**Response:** 200 with `data` as an array of candidate documents ordered most-confident first."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/link-candidates","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","link-candidates"],"variable":[{"key":"entry","value":"10927","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"connection_id\": 30,\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"85414bb6-6f88-4c0f-8c53-53e7c1f7128c\",\n      \"reference\": \"FBA181D492B4: 55641\",\n      \"total\": \"3950.0000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2024-05-23\",\n      \"status\": \"PAID\",\n      \"amount_match\": true,\n      \"date_match\": true,\n      \"reference_match\": true,\n      \"confident\": true,\n      \"dismissed\": false\n    },\n    {\n      \"connection_id\": 30,\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"11c2a7d0-882e-4a19-9f6b-73c0d9a1e2ff\",\n      \"reference\": \"PO-0299\",\n      \"total\": \"1204.0000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2025-09-03\",\n      \"status\": \"AUTHORISED\",\n      \"amount_match\": false,\n      \"date_match\": false,\n      \"reference_match\": false,\n      \"confident\": false,\n      \"dismissed\": true\n    }\n  ]\n}"}]},{"name":"Link Entry to Existing Document","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/relink","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","relink"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Re-link a voided or deleted entry to an EXISTING provider document — the replacement already re-created in the accounting provider — instead of minting a fresh one. Repoints the entry's voided link onto the chosen document in place and records it so the NEXT sync pushes an update to that existing document, never a duplicate create.\n\nUse the candidate returned by `List Relink Candidates` to supply `remote_type` and `remote_id`. The action is guarded: the entry must still be voided/deleted, it must have a voided link on the given connection, and the target document must not already be linked to another entry.\n\nLinking a document also clears any reconcile-screen dismissal recorded against it.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:**\n- `connection_id` (integer, required) — the accounting connection the document belongs to.\n- `remote_type` (string, required) — the document kind, e.g. `xero_bill`, `xero_invoice`, `qbo_bill`.\n- `remote_id` (string, required) — the provider document identifier to adopt.\n- `remote_status` (string, optional) — the document's current provider status (e.g. `AUTHORISED`), recorded on the link.\n\n**Response:** 200 with `data.relink` ({ relinked, status, reason }) and `data.entry` (the refreshed entry). When `relinked` is false, `reason` is one of `not_voided`, `no_parked_link`, or `already_linked_elsewhere`. Returns 404 when the entry does not exist, 422 when the body is invalid.\n\nRequires the `accounting.sync` permission.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 30,\n  \"remote_type\": \"xero_bill\",\n  \"remote_id\": \"54f0b7b3-9537-447a-bda2-897f7da26e9f\",\n  \"remote_status\": \"AUTHORISED\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/relink","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","relink"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"relink\": {\n      \"relinked\": true,\n      \"status\": \"update_pending\",\n      \"reason\": null\n    },\n    \"entry\": {\n      \"id\": 1842,\n      \"uuid\": \"9c2f1b7e-4a6d-4f0e-9b1a-2d8c5e7f3a10\",\n      \"type\": {\n        \"value\": \"purchase_order_invoice\",\n        \"label\": \"Purchase Order Invoice\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"update_pending\",\n        \"label\": \"Synced, Pending Update\",\n        \"color\": \"warning\",\n        \"reason\": null\n      },\n      \"can_sync_now\": true,\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"49063.4000\",\n      \"total_credit\": \"49063.4000\",\n      \"document_number\": \"BILL-1842\",\n      \"reference\": \"PO-0327: INVCBUSA-2000001\",\n      \"sync_links\": [\n        {\n          \"remote_type\": \"xero_bill\",\n          \"remote_id\": \"54f0b7b3-9537-447a-bda2-897f7da26e9f\",\n          \"link_state\": \"linked_stale\",\n          \"remote_status\": \"AUTHORISED\"\n        }\n      ],\n      \"operations\": []\n    }\n  },\n  \"message\": \"Linked to the existing provider document — it will update on the next sync.\"\n}"}]},{"name":"Fetch Latest From Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/fetch-remote","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","fetch-remote"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"The inbound mirror of \"Sync Now\" (— two-way sync, on demand): instead of PUSHING local changes out, it re-reads this entry's remote document(s) FROM the accounting provider (Xero / QuickBooks) and re-grades the sync link RIGHT NOW. For each supported, still-linked connection it fetches the current remote truth via the same InboundChangeProcessor funnel the webhook + nightly sweep use — picking up drift (→ linked_conflict), a void/delete (→ remote_gone), a settled/paid lock (→ remote_locked), or a previously settled lock that has re-opened for edits — the paying payment / credit note was reversed at the provider, e.g. Xero PAID → AUTHORISED — which un-parks the link (→ linked_stale) so it is ready to resync — and refreshes `last_remote_seen_at`. A 404 at the provider degrades to a synthetic-deleted snapshot so the link still parks remote_gone rather than silently staying Synced.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns **synchronously** (the response reflects the re-read); the bulk equivalent is the `fetch_remote` action on POST /api/ledger/entries/bulk, which runs the same per-entry work as a tracked job.\n\n**Deferral:** if a push for this entry is in flight, the funnel writes NOTHING (touching the link would erase the drift signals reconciliation needs) and the response carries `data.fetch.deferred: true` with a \"try again once the in-flight sync settles\" message — still HTTP 200.\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission (403 without it).\n\n**Request body:** none.\n\n**Response:** 200 with `data.fetch` ({ checked, not_linked, deferred, primary, outcomes }) and `data.entry` (the refreshed ledger entry object so the new link state renders without a second round-trip). `data.fetch.primary` is the most-notable settled outcome across the re-read links by severity (`remote_gone` > `remote_locked` > `conflict` > `remote_reopened` > `current`), or null when nothing was re-read. `message` explains the outcome. Returns **502 Bad Gateway** when the provider read itself fails (e.g. expired auth / network) — no link state is changed. Returns 404 when the entry does not exist.\n\nWhen the provider has settled the bill with a credit note that SKU has not mirrored as a vendor-credit allocation, the response reports `data.fetch.unreflected_credit = true` and lists the affected notes in `data.fetch.unreflected_credit_notes` (each with `credit_note_number`, `applied_amount` and `shortfall`), and `message` explains that a matching vendor credit must be created or allocated to reconcile the bill."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/fetch-remote","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","fetch-remote"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fetch\": {\n      \"checked\": 1,\n      \"not_linked\": false,\n      \"deferred\": false,\n      \"primary\": \"current\",\n      \"outcomes\": {\n        \"current\": 1\n      },\n      \"unreflected_credit\": false,\n      \"unreflected_credit_notes\": []\n    },\n    \"entry\": {\n      \"id\": 1842,\n      \"type\": {\n        \"value\": \"bill\",\n        \"label\": \"Bill\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"reason\": null\n      },\n      \"document_number\": \"BILL-1842\",\n      \"reference\": \"5cKTkaXNDpXqmNv0MzaOHAMppp6CsZOYXrgMbDv4UDg\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"1305.86\",\n      \"total_credit\": \"1305.86\",\n      \"document_total\": \"842.67\",\n      \"sync_provider\": \"Xero\",\n      \"sync_links\": [\n        {\n          \"connection_id\": 7,\n          \"remote_type\": \"xero_bill\",\n          \"remote_id\": \"57406763-6b49-4be8-98b5-16750c106f6e\",\n          \"link_state\": \"linked_current\",\n          \"last_remote_seen_at\": \"2026-06-30T01:41:05Z\"\n        }\n      ]\n    }\n  },\n  \"message\": \"Refreshed from the provider — the entry is up to date.\"\n}"}]},{"name":"Get Entry Sync Inspection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-inspection","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-inspection"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Explain why a journal entry is (or is not) syncing to the accounting provider. Read-only — never writes.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:**\n- `eligible` (boolean) — the entry will sync automatically as it stands\n- `enableable` (boolean) — the entry won't auto-sync, but a manual sync (or a `force_enabled` override) will push it: its only blockers are settings opt-outs\n- `can_sync_now` (boolean) — `eligible OR enableable`; whether a manual sync would succeed right now\n- `reasons` (array of strings) — why automatic sync is blocked (empty when eligible). Possible codes: `override_disabled`, `type_disabled`, `channel_disabled`, `granularity_off`, `before_type_sync_start_date`, `before_provider_sync_start_date`, `batch_member`, `batch_open`, `internal_only`, `connection_inactive`, `no_accounting_connection`\n- `structural_reasons` (array of strings) — the subset that blocks even a manual sync (empty when the entry is eligible or enableable)\n- `sync_override` (string|null) — the entry's durable override (`force_enabled` / `force_disabled`), if any\n- `sync_override_provenance` (object|null) — who or what set the override: `source` (`user`, `legacy_cutover`, or `system`), `set_at` (ISO 8601), `set_by` (`{id, name}` of the user, or null)\n\nNotes: `channel_disabled` blocks scheduled sync only — a manual sync still pushes the entry. Structural codes (`connection_inactive`, `batch_member`, `batch_open`, `internal_only`, `before_provider_sync_start_date`) cannot be bypassed.\n\nReturns 404 when the entry does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-inspection","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-inspection"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entry_id\": 1842,\n    \"eligible\": false,\n    \"enableable\": true,\n    \"can_sync_now\": true,\n    \"reasons\": [\n      \"channel_disabled\",\n      \"override_disabled\"\n    ],\n    \"structural_reasons\": [],\n    \"sync_override\": \"force_disabled\",\n    \"sync_override_provenance\": {\n      \"source\": \"legacy_cutover\",\n      \"set_at\": \"2026-07-16T14:00:00+00:00\",\n      \"set_by\": null\n    }\n  },\n  \"message\": null\n}"}]},{"name":"Set Sync Override","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-override","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-override"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Set or clear the entry's durable sync override (Layer A). This endpoint is THE sanctioned writer of `ledger_journal_entries.sync_override` — the override is durable user intent, and regeneration never touches the column, so it survives rebuilds (fixes the legacy is_sync_enabled clobber bug).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body fields:**\n- `override` (required-present, nullable) — one of:\n  - `\"force_enabled\"` — force the entry eligible for sync\n  - `\"force_disabled\"` — force the entry excluded from sync\n  - `null` — clear the override back to derived eligibility\n\nThe key MUST be present in the body (HTTP 422 if omitted); send `null` to clear.\n\nAfter the write, sync work and display status are re-evaluated. The response echoes the entry's id, the saved sync_override and the recomputed display_status. Returns 404 when the entry does not exist.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it.\n\nEvery write records provenance (who set the override and when), returned as `sync_override_provenance` on the entry; clearing the override clears the provenance with it.","body":{"mode":"raw","raw":"{\n  \"override\": \"force_disabled\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/sync-override","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","sync-override"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1842,\n    \"sync_override\": \"force_disabled\",\n    \"display_status\": \"excluded\",\n    \"can_sync_now\": true,\n    \"locked_update_pending\": false,\n    \"locked_amend_blocked\": false\n  },\n  \"message\": \"Sync override updated.\"\n}"}]},{"name":"Set Reference Override","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/reference-override","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","reference-override"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Set or clear the entry's durable **reference override**. The override is the custom reference shown in SKU and SENT TO THE ACCOUNTING PROVIDER (Xero/QBO) as the reference / invoice number, in place of the auto-derived `reference`. Like `sync_override` it is durable user intent — carried across draft regeneration and posted reversal+replacement — and the original `reference` is always retained for traceability.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body fields:**\n- `reference` (required-present, nullable string, max 191) — the custom reference. Send an empty string or `null` to clear the override back to the derived reference.\n\nThe key MUST be present (HTTP 422 if omitted). The response echoes the entry id, the derived `reference`, the saved `reference_override`, and `display_reference` (= override ?? reference, what the UI shows and what syncs). Returns 404 when the entry does not exist.\n\nPermission: requires `accounting.sync`.","body":{"mode":"raw","raw":"{\n  \"reference\": \"PO-0001.55\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/reference-override","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","reference-override"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1842,\n    \"document_number\": \"JE-1842\",\n    \"reference\": \"PO-0001\",\n    \"reference_override\": \"PO-0001.55\",\n    \"display_reference\": \"PO-0001.55\"\n  },\n  \"message\": \"Reference updated.\"\n}"}]},{"name":"Set Nominal Override","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/nominal-overrides","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","nominal-overrides"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Pin a durable manual **nominal-code (GL account) override** on the entry: \"when this entry would post to `from_nominal_code_id`, post to `to_nominal_code_id` instead.\" The override is keyed by the entry identity and **re-applied during derivation on every rebuild**, so it survives regeneration the way `sync_override` does — while amounts, dates and lines keep tracking the source document (it pins ONLY the account, NOT a whole-entry lock).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nApplying it rebuilds the entry through the normal pipeline: a **draft** regenerates with the remapped account; a **posted** entry **reverses + re-posts** a correction (the accounting-correct path). Re-editing an already-overridden line keys off the line's ORIGINALLY-DERIVED account, so send `from_nominal_code_id = nominal_code_id_original ?? nominal_code_id`.\n\n**Authentication:** Requires Bearer token.\n\n**Request body fields:**\n- `from_nominal_code_id` (required, integer, exists:nominal_codes) — the originally-derived account to remap.\n- `to_nominal_code_id` (required, integer, exists:nominal_codes, different from `from`) — the account to post to.\n\nTo revert, use DELETE on this endpoint instead. Returns 404 when the entry does not exist.\n\nPermission: requires `accounting.sync`.","body":{"mode":"raw","raw":"{\n  \"from_nominal_code_id\": 10,\n  \"to_nominal_code_id\": 20\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/nominal-overrides","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","nominal-overrides"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Account override saved — the entry will regenerate with the new account shortly.\"\n}"}]},{"name":"Remove Nominal Override","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/nominal-overrides","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","nominal-overrides"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]},"description":"Remove the nominal-code override for one originally-derived account (`from_nominal_code_id`) so the line reverts to its source-derived account on the next rebuild.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body fields:**\n- `from_nominal_code_id` (required, integer) — the derived account whose override is being removed.\n\nReturns 404 when the entry does not exist. Permission: requires `accounting.sync`."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/entries/{entry}/nominal-overrides","host":["{{baseUrl}}"],"path":["api","ledger","entries",":entry","nominal-overrides"],"variable":[{"key":"entry","value":"1842","description":"Ledger journal entry ID (numeric). Route-model bound — returns 404 if the entry does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Override removed — the line will revert to its derived account shortly.\"\n}"}]},{"name":"Bulk Entry Action","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/bulk","host":["{{baseUrl}}"],"path":["api","ledger","entries","bulk"]},"description":"Dispatch one tracked bulk action over ledger entries. Eligible/excluded counts are computed server-side via EligibilityResolver BEFORE dispatch, so the response counts are accurate. The job reports progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission (403 without it).\n\n**Request body fields:**\n- `action` (required) — one of: `sync_now` (queue an immediate provider push), `set_override` (force sync on/off — requires `override`), `rebuild` (regenerate from source; posted entries corrected via reversal + replacement), `unlink` (sever the provider sync link so SKU stops tracking the remote doc — a later sync CREATES a new doc), `clear_errors` (dismiss parked needs_action / failed_retryable operations WITHOUT retrying), `fetch_remote` (the INBOUND mirror of sync_now — re-read the remote document(s) and re-grade the link state: drift / void / settled-lock; runs as a tracked job), `delete` (HARD-delete the entry — permanently removes the journal entry, its GL lines, provider sync links and operation history, and nulls any sibling reversal pointer; IRREVERSIBLE; unlike the other actions it runs even when ledger generation is disabled).\n- `scope` (optional, `selected` default | `all` | `all_stale`) — `all` targets every entry matching the CURRENT filters (send the same `filter[...]` / `filter_groups` query params as the list); `all_stale` targets every stale pre-cutover (frozen history) entry, so one `rebuild` call drains the entire stale worklist rather than only its preview page. Both are resolved server-side and capped at 5000; `entry_ids` is then optional/ignored.\n- `entry_ids` (array, required unless `scope=all` or `scope=all_stale`, max 1000) — the explicitly selected entry ids.\n- `override` (required when `action=set_override`) — `force_enabled` | `force_disabled` | null (clear).\n\n**Eligibility (excluded from the action, counted in `excluded_count`):** `sync_now` → entries eligible on at least one connection; `rebuild` → source still exists; `unlink` and `fetch_remote` → entry currently has a live remote link; `clear_errors` → entry carries a clearable parked error; `set_override` and `delete` → always applicable.\n\n**Note:** when ledger generation is disabled (kill switch) no job dispatches — the response carries `note: \"generation_disabled\"` and `tracked_job_log_id: null`. The `delete` action is the one exception: it always dispatches its job so test/erroneous entries can be cleaned up while the kill switch is on.\n\n**Response fields:** `tracked_job_log_id` (null when no job dispatched), `total` (entries the job will process), `eligible_count`, `excluded_count`. When `scope=all` or `scope=all_stale` and the match set exceeds the cap (default 5000, `ledger.bulk.all_scope_cap`), the remainder is dropped and the response adds `all_scope_truncated: true`, `matched_total` (total entries matching the filters), and `cap` (the limit applied); the message then names how many of how many entries were started.\n\n**`replace_nominal_code` action (find & replace account):** remaps every line deriving `from_nominal_code_id` to `to_nominal_code_id` across the selected/all-filtered entries by pinning a durable per-entry override (re-applied on every rebuild). Extra body fields when `action = \"replace_nominal_code\"`:\n- `from_nominal_code_id` (required, integer, exists:nominal_codes)\n- `to_nominal_code_id` (required, integer, exists:nominal_codes, different from `from`)\nRuns as a tracked background job (tracked job log endpoints).","body":{"mode":"raw","raw":"{\n  \"action\": \"unlink\",\n  \"entry_ids\": [\n    1842,\n    1836,\n    1831\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/bulk","host":["{{baseUrl}}"],"path":["api","ledger","entries","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821,\n    \"total\": 312,\n    \"eligible_count\": 298,\n    \"excluded_count\": 14\n  },\n  \"message\": \"Bulk action started — track progress in the job tray.\",\n  \"status\": \"success\"\n}"}]},{"name":"Export Journal Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/export","host":["{{baseUrl}}"],"path":["api","ledger","entries","export"]},"description":"Download the journal-entry list as an XLSX or CSV file (the Export modal). Honours the same filters as the index plus `format` (xlsx/csv) and `columns` (visible-column subset). Scope is expressed by the filters sent: 'all' sends only the base scope, 'filtered' sends the active filters, 'selected' adds filter[ids]. Returns a binary file download (Content-Disposition), not JSON. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Selection Summary","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/entries/selection-summary","host":["{{baseUrl}}"],"path":["api","ledger","entries","selection-summary"]},"description":"Per-nominal-code debit/credit/line-count breakdown of a selection of entries plus grand totals — powers the table's expandable Selection Summary panel (parity with the legacy SelectedTransactionsSummary), sourced from the real journal lines.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body:**\n- `scope` (optional, `selected` default | `all`) — `all` summarizes every entry matching the CURRENT filters (forward the same `filter[...]` / `filter_groups` query params), capped at 5000; `entry_ids` then optional.\n- `entry_ids` (array, required unless `scope=all`, max 5000) — the selected entry ids.\n\n**Response:** `entry_count`, `currency` (null when the selection mixes currencies), `total_debit`, `total_credit`, and `accounts[]` of `{nominal_code_id, code, name, debit, credit, line_count}` (unmapped lines collapse under a null nominal_code_id).","body":{"mode":"raw","raw":"{\n  \"entry_ids\": [\n    1842,\n    1836,\n    1831\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/selection-summary","host":["{{baseUrl}}"],"path":["api","ledger","entries","selection-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"selection_summary\": {\n      \"entry_count\": 2,\n      \"currency\": \"USD\",\n      \"total_debit\": \"140.0000\",\n      \"total_credit\": \"140.0000\",\n      \"accounts\": [\n        {\n          \"nominal_code_id\": 4,\n          \"code\": \"1000\",\n          \"name\": \"Inventory Control\",\n          \"debit\": \"140.0000\",\n          \"credit\": \"0.0000\",\n          \"line_count\": 2\n        },\n        {\n          \"nominal_code_id\": 3,\n          \"code\": \"5000\",\n          \"name\": \"Cost of Goods Sold\",\n          \"debit\": \"0.0000\",\n          \"credit\": \"140.0000\",\n          \"line_count\": 2\n        }\n      ]\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Repost All Entries","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/repost-all","host":["{{baseUrl}}"],"path":["api","ledger","entries","repost-all"]},"description":"Repost every current (non-discarded, non-reversed) ledger entry so posted GL lines pick up a changed chart of accounts — the onboarding backfill after adopting a provider's chart. Reuses the bulk rebuild pipeline: posted entries auto-reverse + replace with the new nominal codes, drafts regenerate in place, batch aggregates route through the batch state machine. Requires the `accounting.sync` permission. Returns the tracked job log id + eligible/excluded counts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/entries/repost-all","host":["{{baseUrl}}"],"path":["api","ledger","entries","repost-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5120,\n    \"total\": 842,\n    \"eligible_count\": 842,\n    \"excluded_count\": 0\n  },\n  \"message\": \"Repost started for 842 ledger entries — track progress in the job tray.\"\n}"}]},{"name":"Get Entry by Source","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/by-source?source_type=App\\Models\\PurchaseInvoice&source_id=3","host":["{{baseUrl}}"],"path":["api","ledger","entries","by-source"],"query":[{"key":"source_type","value":"App\\Models\\PurchaseInvoice","description":"Source model FQN (required)","disabled":true},{"key":"source_id","value":"3","description":"Source record id (required)","disabled":true}]},"description":"The current v2 ledger journal entry for a source document (or data:null). Lets a source-doc accounting tab (Purchase Invoice, PO, Sales Order, etc.) show its v2 ledger entry as the accounting transaction — linked to /v2/ledger/entries/{id} — instead of the legacy v1 accounting_transaction. source_type is the source model FQN.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/by-source?source_type=App\\Models\\PurchaseInvoice&source_id=3","host":["{{baseUrl}}"],"path":["api","ledger","entries","by-source"],"query":[{"key":"source_type","value":"App\\Models\\PurchaseInvoice","description":"Source model FQN (required)","disabled":true},{"key":"source_id","value":"3","description":"Source record id (required)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"document_number\": \"JE-3\",\n    \"reference\": \"PO-0001: ionv001\",\n    \"display_status\": \"excluded\",\n    \"can_sync_now\": true,\n    \"locked_update_pending\": false,\n    \"locked_amend_blocked\": false,\n    \"total_debit\": \"5000.0000\",\n    \"total_credit\": \"5000.0000\",\n    \"effective_at\": \"2026-06-26T00:00:00Z\"\n  }\n}"}]},{"name":"List Entries by Source","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/entries/by-source-list?source_type=Modules\\Amazon\\Entities\\AmazonFinancialEventGroup&source_id=16","host":["{{baseUrl}}"],"path":["api","ledger","entries","by-source-list"],"query":[{"key":"source_type","value":"Modules\\Amazon\\Entities\\AmazonFinancialEventGroup","description":"Source model FQN (required)","disabled":true},{"key":"source_id","value":"16","description":"Source record id (required)","disabled":true}]},"description":"Every live (non-discarded, non-reversal, non-reversed) v2 ledger journal entry for a source document, as a lightweight list. Where /by-source returns only the latest single entry, a source can post more than one current entry — an Amazon settlement posts both an invoice AND a bill — so a source-doc accounting list (e.g. the Amazon bank-transaction detail page) needs the full set. Each item links to /v2/ledger/entries/{id}. source_type is the source model FQN.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns data: an array of { id, type, reference, total }. Empty array when the source has no live entries.\n\n**`total`** is the NET document total (the provider-booked face value — net control-account movement), not the gross debit total. For an Amazon settlement bill with internal reserve contra legs the two differ (e.g. 842.67 net vs 1,305.86 gross)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/entries/by-source-list?source_type=Modules\\Amazon\\Entities\\AmazonFinancialEventGroup&source_id=16","host":["{{baseUrl}}"],"path":["api","ledger","entries","by-source-list"],"query":[{"key":"source_type","value":"Modules\\Amazon\\Entities\\AmazonFinancialEventGroup","description":"Source model FQN (required)","disabled":true},{"key":"source_id","value":"16","description":"Source record id (required)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 29,\n      \"type\": \"sales_order_invoice\",\n      \"document_number\": \"INV-29\",\n      \"reference\": \"aS1O-So4T6lFwowEq3JBCtjdts5TNjL553ZUrzAGZFk\",\n      \"total\": \"115229.9300\"\n    },\n    {\n      \"id\": 30,\n      \"type\": \"bill\",\n      \"document_number\": \"BILL-30\",\n      \"reference\": \"aS1O-So4T6lFwowEq3JBCtjdts5TNjL553ZUrzAGZFk\",\n      \"total\": \"38755.6700\"\n    }\n  ]\n}"}]},{"name":"List Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/payments","host":["{{baseUrl}}"],"path":["api","ledger","payments"]},"description":"SKU-side payments (App\\Models\\Payment) paginated, each with its source document and the linked accounting-provider payment (Xero/QBO) cross-link. Backs the Accounting v2 Payments tab. `provider_payment` is null when the payment has not been synced to a provider; `status` is synced / error / not_synced.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthenticate with a Personal Access Token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/payments","host":["{{baseUrl}}"],"path":["api","ledger","payments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"amount\": \"59.99\",\n      \"currency_code\": \"USD\",\n      \"payment_date\": \"2026-06-14T00:00:00+00:00\",\n      \"type\": \"direct\",\n      \"payment_type\": \"Amazon Payment\",\n      \"external_reference\": \"114-4389768-5982613\",\n      \"source\": {\n        \"type\": \"App\\\\Models\\\\SalesOrder\",\n        \"id\": 18519,\n        \"label\": \"114-4389768-5982613\",\n        \"link_type_label\": \"Sales Order\",\n        \"link_route\": \"/orders/sales-orders/18519\",\n        \"link_legacy_url\": null,\n        \"url\": \"/orders/sales-orders/18519\"\n      },\n      \"provider_payment\": {\n        \"provider\": \"Xero\",\n        \"reference\": \"pay-86906814-f1e5\",\n        \"link_route\": \"/integrations/xero/payments/12\",\n        \"remote_url\": \"https://go.xero.com/Bank/ViewTransaction.aspx?bankTransactionID=pay-86906814-f1e5\",\n        \"sync_status\": \"synced\"\n      },\n      \"status\": \"synced\",\n      \"created_at\": \"2026-06-14T08:58:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2704,\n  \"per_page\": 15,\n  \"total\": 40547,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Sync Payment to Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/payments/{payment}/sync","host":["{{baseUrl}}"],"path":["api","ledger","payments",":payment","sync"],"variable":[{"key":"payment","value":"42","description":"The SKU payment id"}]},"description":"Manually push (or re-push) one SKU payment to the connected accounting provider (two-way payment sync) — the row action on the Payments tab. Runs inline: eligibility rejections and provider validation errors are persisted to the payment's last_sync_error and returned as 422; transport/auth failures return 502 with no state change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token + `accounting.sync` permission and an active ledger cutover.\n\nEligibility: the payment must be SKU-originated (not ingested from the provider), a cash-style type, and its owner document's current ledger entry must have a live sync link to a provider invoice/bill. On success the payment is linked to the created provider payment (accounting_integration) and its status on the Payments tab flips to Synced."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/payments/{payment}/sync","host":["{{baseUrl}}"],"path":["api","ledger","payments",":payment","sync"],"variable":[{"key":"payment","value":"42","description":"The SKU payment id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payment synced to the accounting provider.\",\n  \"status\": \"success\"\n}"}]},{"name":"List Batches","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches","host":["{{baseUrl}}"],"path":["api","ledger","batches"]},"description":"Paginated ledger batches listing: the grouping key (type, period, channel, currency), lifecycle status with the derived `is_dirty` flag, members_count and the aggregate journal entry summary.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Filters (Spatie QueryBuilder):**\n- `filter[type]` — exact entry type\n- `filter[period_type]` — daily | monthly\n- `filter[status]` — open | dirty | closing | posted | reopened\n- `filter[currency_code]` — exact currency\n- `filter[channel]` — exact integration_instance_id\n- `filter[date_from]` / `filter[date_to]` — m/d/Y on period_start (invalid dates silently ignored)\n- `filter[dirty]` — boolean; true = status dirty or reopened (the needs-rebuild indicator), false = everything else\n\n**Sorts:** id, period_start, type, members_count, created_at (default: -period_start).\n\n**Pagination:** per_page default 10, clamped to max 100.\n\n`entry` is the batch's current aggregate journal entry summary (null when not yet built). `channel` is null for batches not scoped to a channel.\n\n**Advanced filters (`filter_groups`):** base64-encoded JSON tree of AND/OR groups via GroupedFilterSupport (same stack as the entries index).\n**Filterable columns:** `batch_type`, `batch_status`, `batch_period_type`, `currency` (text operators); `id`, `members_count` (numeric operators); `period_start`, `period_end` (date operators); `created_at` (datetime operators). Unregistered columns are rejected with HTTP 400.\n\n**Search:** `filter[search]` matches the batch type and the aggregate journal entry's reference.\n**Sorts:** id, period_start, type, members_count, currency_code, status, created_at, channel (channel name via subquery) — prefix with - for DESC; default -period_start.\n\n**Provider sync (entry object):** each batch's `entry` includes `provider_status` — the accounting provider's own status for the synced document (e.g. AUTHORISED, POSTED, PAID; null when never synced) — and `provider_link`, the linked provider document (`provider`, `label`, `link_route`, `remote_url`; null when never synced)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/batches","host":["{{baseUrl}}"],"path":["api","ledger","batches"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 57,\n      \"type\": {\n        \"value\": \"fba_shipments\",\n        \"label\": \"FBA Shipments\"\n      },\n      \"period_type\": \"monthly\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"channel\": {\n        \"id\": 8,\n        \"name\": \"Amazon US\"\n      },\n      \"currency_code\": \"USD\",\n      \"status\": \"open\",\n      \"is_dirty\": false,\n      \"members_count\": 1240,\n      \"entry\": {\n        \"id\": 1901,\n        \"reference\": \"BATCH-FBA-SHIPMENTS-2026-06\",\n        \"status\": \"draft\",\n        \"display_status\": {\n          \"key\": \"pending_sync\",\n          \"label\": \"Pending Sync\",\n          \"color\": \"info\"\n        },\n        \"can_sync_now\": true,\n        \"provider_link\": null,\n        \"provider_status\": null,\n        \"total_debit\": \"48211.7500\",\n        \"total_credit\": \"48211.7500\"\n      },\n      \"created_at\": \"2026-06-01T00:05:11+00:00\"\n    },\n    {\n      \"id\": 52,\n      \"type\": {\n        \"value\": \"batch_sales_order_invoice\",\n        \"label\": \"Batch Sales Order Invoice\"\n      },\n      \"period_type\": \"daily\",\n      \"period_start\": \"2026-06-08\",\n      \"period_end\": \"2026-06-08\",\n      \"channel\": {\n        \"id\": 5,\n        \"name\": \"Shopify Main Store\"\n      },\n      \"currency_code\": \"USD\",\n      \"status\": \"posted\",\n      \"is_dirty\": false,\n      \"members_count\": 86,\n      \"entry\": {\n        \"id\": 1888,\n        \"reference\": \"BATCH-SALES-2026-06-08-SHOPIFY\",\n        \"status\": \"posted\",\n        \"display_status\": {\n          \"key\": \"synced\",\n          \"label\": \"Synced\",\n          \"color\": \"success\"\n        },\n        \"can_sync_now\": true,\n        \"provider_link\": {\n          \"provider\": \"Xero\",\n          \"remote_type\": \"xero_invoice\",\n          \"remote_id\": \"b7c1e2a4-9f3d-4a2b-8e6c-2f1d0a9b8c77\",\n          \"link_type_label\": \"Invoice\",\n          \"label\": \"INV-1042\",\n          \"link_route\": \"/integrations/xero/invoices/318\",\n          \"remote_url\": \"https://go.xero.com/app/invoicing/view/b7c1e2a4-9f3d-4a2b-8e6c-2f1d0a9b8c77\"\n        },\n        \"provider_status\": \"AUTHORISED\",\n        \"total_debit\": \"10422.9000\",\n        \"total_credit\": \"10422.9000\"\n      },\n      \"created_at\": \"2026-06-08T00:02:33+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-alt.test/api/ledger/batches?page=1\",\n  \"from\": 1,\n  \"last_page\": 6,\n  \"last_page_url\": \"https://sku-alt.test/api/ledger/batches?page=6\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/batches?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/batches?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-alt.test/api/ledger/batches?page=2\",\n  \"path\": \"https://sku-alt.test/api/ledger/batches\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 54\n}"}]},{"name":"Get Batch","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]},"description":"Batch detail: the batch resource (under the `batch` key) plus `totals_by_account` — the aggregate journal entry's GL impact grouped by nominal code, one row per account with its debit and credit sums (4-decimal strings).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n`totals_by_account` is an empty array when the batch's aggregate entry has not been built yet. Returns 404 when the batch does not exist.\n\n**Provider sync (entry object):** each batch's `entry` includes `provider_status` — the accounting provider's own status for the synced document (e.g. AUTHORISED, POSTED, PAID; null when never synced) — and `provider_link`, the linked provider document (`provider`, `label`, `link_route`, `remote_url`; null when never synced)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"batch\": {\n      \"id\": 57,\n      \"type\": {\n        \"value\": \"fba_shipments\",\n        \"label\": \"FBA Shipments\"\n      },\n      \"period_type\": \"monthly\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"channel\": {\n        \"id\": 8,\n        \"name\": \"Amazon US\"\n      },\n      \"currency_code\": \"USD\",\n      \"status\": \"open\",\n      \"is_dirty\": false,\n      \"members_count\": 1240,\n      \"entry\": {\n        \"id\": 1901,\n        \"reference\": \"BATCH-FBA-SHIPMENTS-2026-06\",\n        \"status\": \"draft\",\n        \"display_status\": {\n          \"key\": \"pending_sync\",\n          \"label\": \"Pending Sync\",\n          \"color\": \"info\"\n        },\n        \"can_sync_now\": true,\n        \"provider_link\": null,\n        \"provider_status\": null,\n        \"total_debit\": \"48211.7500\",\n        \"total_credit\": \"48211.7500\"\n      },\n      \"created_at\": \"2026-06-01T00:05:11+00:00\"\n    },\n    \"totals_by_account\": [\n      {\n        \"nominal_code\": {\n          \"id\": 40,\n          \"code\": \"4000\",\n          \"name\": \"Sales Revenue\"\n        },\n        \"debit\": \"0.0000\",\n        \"credit\": \"48211.7500\"\n      },\n      {\n        \"nominal_code\": {\n          \"id\": 12,\n          \"code\": \"1100\",\n          \"name\": \"Accounts Receivable\"\n        },\n        \"debit\": \"48211.7500\",\n        \"credit\": \"0.0000\"\n      }\n    ]\n  }\n}"}]},{"name":"List Batch Members","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/members","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","members"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]},"description":"Paginated member documents of a batch — the A2X-style lineage view. Each member row carries:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `member` — the cross-link view-model for the member document (morph type + ID, friendly label/reference, link_type_label, the application UI link_route when a detail page exists)\n- `contribution` — the member's debit/credit contribution inside this batch (its journal lines summed by direction, 4-decimal strings)\n- `added_at` — when the document joined the batch\n\n**Authentication:** Requires Bearer token.\n\n**Pagination:** per_page default 10, clamped to max 100. Newest members first.\n\nReturns 404 when the batch does not exist.\n\n**Advanced filters (`filter_groups`):** base64-encoded JSON tree of AND/OR groups via GroupedFilterSupport.\n**Filterable columns:** `member_type` (text operators); `member_id`, `id` (numeric operators); `added_at` (datetime operators). Unregistered columns are rejected with HTTP 400.\n\n**Search:** `filter[search]` matches the member's morph type and (when numeric, # prefix allowed) the document id.\n**Sorts:** id, member_id, member_type, added_at, member (alias of member_id), debit, credit, document_date (contribution sums via correlated subquery) — prefix with - for DESC; default -id.\n\n**Response field `document_date`:** the member's accounting date (its entry's effective_at — the source document's date), distinct from `added_at` (when the membership row was created). Sortable via `sort=document_date`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/members","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","members"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9120,\n      \"member\": {\n        \"type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n        \"id\": 44312,\n        \"label\": \"SO-10293-F1\",\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_route\": null,\n        \"link_legacy_url\": null,\n        \"url\": null\n      },\n      \"contribution\": {\n        \"debit\": \"129.9900\",\n        \"credit\": \"129.9900\"\n      },\n      \"added_at\": \"2026-06-08T10:15:30+00:00\"\n    },\n    {\n      \"id\": 9119,\n      \"member\": {\n        \"type\": \"App\\\\Models\\\\SalesOrder\",\n        \"id\": 10288,\n        \"label\": \"SO-10288\",\n        \"link_type_label\": \"Sales Order\",\n        \"link_route\": \"/orders/sales-orders/10288\",\n        \"link_legacy_url\": null,\n        \"url\": \"/orders/sales-orders/10288\"\n      },\n      \"contribution\": {\n        \"debit\": \"84.5000\",\n        \"credit\": \"84.5000\"\n      },\n      \"added_at\": \"2026-06-08T09:42:12+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-alt.test/api/ledger/batches/57/members?page=1\",\n  \"from\": 1,\n  \"last_page\": 124,\n  \"last_page_url\": \"https://sku-alt.test/api/ledger/batches/57/members?page=124\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/batches/57/members?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-alt.test/api/ledger/batches/57/members?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-alt.test/api/ledger/batches/57/members?page=2\",\n  \"path\": \"https://sku-alt.test/api/ledger/batches/57/members\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 1240\n}"}]},{"name":"Get Batch History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/history","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","history"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]},"description":"Batch membership + correction history. Returns two keys:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `events` — a paginated list of membership audit events (action added | removed, the member cross-link, `occurred_after_post` — whether the batch's aggregate entry was already POSTED at the moment of the change, i.e. the change triggered an automatic reversal + replacement) — newest first, per_page default 10 clamped to 100\n- `reversal_chain` — every non-discarded aggregate journal entry sourced from this batch, oldest first: the current entry, reversed originals and the reversal mirror rows (id, reference, status, reversal_of_id, replaced_by_id, created_at)\n\n**Authentication:** Requires Bearer token.\n\nReturns 404 when the batch does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/history","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","history"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"events\": {\n      \"data\": [\n        {\n          \"id\": 15233,\n          \"action\": \"added\",\n          \"member\": {\n            \"type\": \"App\\\\Models\\\\SalesOrder\",\n            \"id\": 10301,\n            \"label\": \"SO-10301\",\n            \"link_type_label\": \"Sales Order\",\n            \"link_route\": \"/orders/sales-orders/10301\",\n            \"link_legacy_url\": null,\n            \"url\": \"/orders/sales-orders/10301\"\n          },\n          \"occurred_after_post\": true,\n          \"created_at\": \"2026-06-09T16:20:44+00:00\"\n        },\n        {\n          \"id\": 15201,\n          \"action\": \"removed\",\n          \"member\": {\n            \"type\": \"App\\\\Models\\\\SalesOrder\",\n            \"id\": 10295,\n            \"label\": \"SO-10295\",\n            \"link_type_label\": \"Sales Order\",\n            \"link_route\": \"/orders/sales-orders/10295\",\n            \"link_legacy_url\": null,\n            \"url\": \"/orders/sales-orders/10295\"\n          },\n          \"occurred_after_post\": false,\n          \"created_at\": \"2026-06-08T11:02:10+00:00\"\n        }\n      ],\n      \"current_page\": 1,\n      \"first_page_url\": \"https://sku-alt.test/api/ledger/batches/52/history?page=1\",\n      \"from\": 1,\n      \"last_page\": 9,\n      \"last_page_url\": \"https://sku-alt.test/api/ledger/batches/52/history?page=9\",\n      \"links\": [\n        {\n          \"url\": null,\n          \"label\": \"&laquo; Previous\",\n          \"active\": false\n        },\n        {\n          \"url\": \"https://sku-alt.test/api/ledger/batches/52/history?page=1\",\n          \"label\": \"1\",\n          \"active\": true\n        },\n        {\n          \"url\": \"https://sku-alt.test/api/ledger/batches/52/history?page=2\",\n          \"label\": \"Next &raquo;\",\n          \"active\": false\n        }\n      ],\n      \"next_page_url\": \"https://sku-alt.test/api/ledger/batches/52/history?page=2\",\n      \"path\": \"https://sku-alt.test/api/ledger/batches/52/history\",\n      \"per_page\": 10,\n      \"prev_page_url\": null,\n      \"to\": 10,\n      \"total\": 88\n    },\n    \"reversal_chain\": [\n      {\n        \"id\": 1888,\n        \"reference\": \"BATCH-SALES-2026-06-08-SHOPIFY\",\n        \"status\": \"reversed\",\n        \"reversal_of_id\": null,\n        \"replaced_by_id\": 1925,\n        \"created_at\": \"2026-06-08T00:02:35+00:00\"\n      },\n      {\n        \"id\": 1924,\n        \"reference\": \"BATCH-SALES-2026-06-08-SHOPIFY\",\n        \"status\": \"posted\",\n        \"reversal_of_id\": 1888,\n        \"replaced_by_id\": null,\n        \"created_at\": \"2026-06-09T16:21:02+00:00\"\n      },\n      {\n        \"id\": 1925,\n        \"reference\": \"BATCH-SALES-2026-06-08-SHOPIFY\",\n        \"status\": \"posted\",\n        \"reversal_of_id\": null,\n        \"replaced_by_id\": null,\n        \"created_at\": \"2026-06-09T16:21:02+00:00\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Batch Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/activity-log","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","activity-log"],"variable":[{"key":"batch","value":"12","description":"Ledger batch id"}]},"description":"The batch's standard LogsActivity feed (the detail page Activity tab): creation plus every status transition (open, dirty, closing, posted, reopened) with old/new values, causer and timestamp. Guarded query-update transitions are logged manually by the repository, so the feed covers the full state machine.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nNote: membership add/remove changes are NOT mirrored here — they live in the dedicated `/history` endpoint (ledger_batch_member_events)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/activity-log","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","activity-log"],"variable":[{"key":"batch","value":"12","description":"Ledger batch id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 166,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"LedgerBatch\",\n      \"subject_id\": 12,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"dirty\"\n        },\n        \"old\": {\n          \"status\": \"closing\"\n        },\n        \"metadata\": {\n          \"type\": \"sales_order_fulfillment\",\n          \"period_type\": \"daily\",\n          \"period_start\": \"2026-06-11\",\n          \"currency_code\": \"USD\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-12T23:12:00.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Rebuild Batch","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","rebuild"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]},"description":"Manually rebuild the batch's aggregate journal entry: marks the batch dirty (posted batches flip to `reopened` — the post-post correction pathway, where the rebuild reverses + replaces the posted aggregate entry) and dispatches a background job immediately (no debounce for a manual request; the job's per-batch uniqueness still collapses doubles).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nDeliberately NOT a tracked job: batch builds run in seconds on the per-tenant serial queue, and the batch row's status transition (dirty/reopened → open/closing) is the user-visible completion signal.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:** none.\n\n**Response:** accepted-style 200 — the work is queued (App\\Response normalizes every 2xx to 200). Returns 404 when the batch does not exist.\n\nPermission: requires `accounting.sync` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/batches/{batch}/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","batches",":batch","rebuild"],"variable":[{"key":"batch","value":"57","description":"Ledger batch ID (numeric). Route-model bound — returns 404 if the batch does not exist."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Batch rebuild queued — the aggregate entry will be rebuilt shortly.\"\n}"}]},{"name":"Get Account Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]},"description":"GL account drill-down header (the nominal code detail page): the account's identity plus debit/credit/net totals and line count. Accepts the SAME filter[...] and `filter_groups` params as the lines endpoint, so the KPIs always describe exactly what the lines table shows.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Filterable columns (filter_groups):** `entry_reference`, `entry_type`, `line_direction`, `line_description`, `currency` (text operators); `amount`, `entry_id`, `id` (numeric operators); `effective_at` (date operators). Unregistered columns are rejected with HTTP 400.\n\n`account.posted_lines_count` is the UNfiltered count of live journal lines on the account (independent of the filter params) — the type editor uses it to decide whether a reclassification is guarded.\n\n`account.is_system_reserved` is true when the account is a control account mapped in the accounting settings (A/R, A/P, inventory control, …) — its type is locked and the editor disables the control.\n\n`account.integration_account` is the connected accounting-provider account (Xero or QBO) this nominal code maps to, or null when no provider is connected or no match exists. `link_basis` is `mapping` for an explicit polymorphic mapping (QBO always sets it; Xero sets it when the chart was mapped through the onboarding wizard) or `code` when inferred by matching the account code (xero_accounts.Code ⇄ nominal_codes.code — the fallback Xero's sync uses for an adopted chart). The ledger account page renders the provider account inline and, for Xero, deep-links to /v2/integrations/xero/accounts/{integration_account.id}."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"account\": {\n      \"id\": 6,\n      \"code\": \"1200\",\n      \"name\": \"Accounts Receivable\",\n      \"type\": \"Current\",\n      \"posted_lines_count\": 16,\n      \"is_system_reserved\": true,\n      \"archived_at\": null,\n      \"integration_account\": {\n        \"provider\": \"xero\",\n        \"provider_label\": \"Xero\",\n        \"id\": 61,\n        \"external_id\": \"2c8b3e10-7f4a-4d2e-9b1c-5a6f8e0d1234\",\n        \"code\": \"1200\",\n        \"name\": \"Accounts Receivable\",\n        \"type\": \"CURRENT\",\n        \"class\": \"ASSET\",\n        \"status\": \"ACTIVE\",\n        \"link_basis\": \"code\"\n      }\n    },\n    \"totals\": {\n      \"total_debit\": \"44545.4100\",\n      \"total_credit\": \"0.0000\",\n      \"net\": \"44545.4100\",\n      \"lines_count\": 16\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Account Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/lines","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","lines"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]},"description":"Paginated journal lines hitting one GL account — every line of every non-discarded entry, reversals included (originals and reversal mirrors both appear and net to zero, as a general ledger account view should read).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Quick filters:** `filter[direction]` (debit|credit), `filter[type]` (entry type), `filter[date_from]` / `filter[date_to]` (m/d/Y on entry effective date), `filter[search]` (entry reference + descriptions).\n**Advanced filters (`filter_groups`):** same columns as Get Account Overview.\n**Sorts:** id, amount, direction, effective_at, entry (reference), entry_type, debit, credit — default -effective_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/lines","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","lines"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 91,\n      \"direction\": \"debit\",\n      \"amount\": \"5081.13\",\n      \"tax_amount\": null,\n      \"description\": \"Accounts receivable\",\n      \"entry\": {\n        \"id\": 24,\n        \"reference\": \"SALES_ORDER_INVOICE-2671\",\n        \"reference_suffix\": 0,\n        \"type\": {\n          \"value\": \"sales_order_invoice\",\n          \"label\": \"Sales Order Invoice\"\n        },\n        \"status\": \"draft\",\n        \"effective_at\": \"2026-06-08T00:00:00+00:00\",\n        \"currency_code\": \"USD\"\n      },\n      \"source\": {\n        \"type\": \"App\\\\Models\\\\SalesOrder\",\n        \"id\": 2671,\n        \"label\": \"SO-2671\",\n        \"link_type_label\": \"Sales Order\",\n        \"link_route\": \"/orders/sales-orders/2671\",\n        \"link_legacy_url\": null,\n        \"url\": \"/orders/sales-orders/2671\"\n      }\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 16\n}"}]},{"name":"Update Account Type","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/type","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","type"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]},"description":"Reclassify a GL account's type (the account-class enum).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token. Gated by the `accounting.manage_settings` permission.\n\n**Body:** `type` (required) — one of: Revenue, Expense, Asset, Liability, Equity, Bank, Current, Inventory, Fixed, Directcosts, Currliab, Termliab, Sales.\n\n**Tiered guardrail (mirrors NetSuite/SAP/QBO/Xero):**\n1. No-op (same type) → always allowed.\n2. System/reserved control account (mapped in accounting settings — A/R, A/P, inventory control, COGS, sales tax) → BLOCKED regardless of posting (422). Re-map the setting to a different account instead.\n3. No posted journal lines → the type may change to anything.\n4. Posted lines exist → the new type must stay in the SAME reclassification group (same statement side AND same normal balance): same-group changes (e.g. Current → Fixed asset, Liability → Equity) are allowed; changes that cross the Balance Sheet ↔ Income Statement boundary or flip the normal balance (e.g. Asset → Expense) are rejected with 422.\n\nReturns the same shape as Get Account Overview so the page header re-renders in place. The change is recorded in the account's activity log.","body":{"mode":"raw","raw":"{\n  \"type\": \"Fixed\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/type","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","type"],"variable":[{"key":"nominalCode","value":"6","description":"Nominal code id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"account\": {\n      \"id\": 6,\n      \"code\": \"1500\",\n      \"name\": \"Office Equipment\",\n      \"type\": \"Fixed\",\n      \"posted_lines_count\": 4,\n      \"is_system_reserved\": false,\n      \"archived_at\": null\n    },\n    \"totals\": {\n      \"total_debit\": \"12000.0000\",\n      \"total_credit\": \"0.0000\",\n      \"net\": \"12000.0000\",\n      \"lines_count\": 4\n    }\n  },\n  \"message\": \"Account type updated.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Ledger Account Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/activity-log","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","activity-log"],"variable":[{"key":"nominalCode","value":"48","description":"Ledger (nominal) account ID"}]},"description":"Returns a paginated audit trail for a single general-ledger account, newest first. Each entry records the event, the affected record, a snapshot of changed properties, who made the change, and when. Supports free-text search across the actor name, event and properties.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/accounts/{nominalCode}/activity-log","host":["{{baseUrl}}"],"path":["api","ledger","accounts",":nominalCode","activity-log"],"variable":[{"key":"nominalCode","value":"48","description":"Ledger (nominal) account ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 771204,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"NominalCode\",\n      \"subject_id\": 48,\n      \"properties\": {\n        \"old\": {\n          \"account_type\": \"asset\"\n        },\n        \"attributes\": {\n          \"account_type\": \"expense\"\n        }\n      },\n      \"causer_name\": \"Jane Accountant\",\n      \"created_at\": \"2026-07-05T09:12:44Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Granularity Matrix","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/settings/granularity","host":["{{baseUrl}}"],"path":["api","ledger","settings","granularity"]},"description":"Read the type × channel posting granularity matrix stored on the accounting connection (— the Cin7-style settings matrix), consumed by BatchGranularityResolver.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Matrix shape:** `{ \"<type>\": { \"default\": \"<granularity>\", \"channels\": { \"<integration instance id>\": \"<granularity>\" } } }` where granularity is one of:\n- `off` — the type generates no synced accounting output for the channel\n- `per_document` — every source document syncs as its own journal entry\n- `daily` — documents aggregate into one batch per local day\n- `monthly` — documents aggregate into one batch per local month\n\nAn empty object means no overrides are stored — legacy per-type defaults apply. Also returns `connection_id` — the accounting connection the matrix lives on.\n\nReturns 404 when no accounting connection is configured."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/settings/granularity","host":["{{baseUrl}}"],"path":["api","ledger","settings","granularity"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"granularity_matrix\": {\n      \"sales_order_invoice\": {\n        \"default\": \"per_document\",\n        \"channels\": {\n          \"5\": \"daily\",\n          \"8\": \"off\"\n        }\n      },\n      \"sales_order_fulfillment\": {\n        \"default\": \"off\"\n      },\n      \"fba_shipments\": {\n        \"default\": \"monthly\",\n        \"channels\": {\n          \"8\": \"monthly\"\n        }\n      },\n      \"inventory_adjustment\": {\n        \"default\": \"per_document\"\n      }\n    },\n    \"connection_id\": 3\n  }\n}"}]},{"name":"Update Granularity Matrix","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/settings/granularity","host":["{{baseUrl}}"],"path":["api","ledger","settings","granularity"]},"description":"Validate, clamp and persist the type × channel granularity matrix. Returns the matrix AS SAVED — the client must re-render from the response because of the server-side clamp.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Request body fields:**\n- `matrix` (present, object) — MAY be an empty object `{}`: an empty matrix clears all stored overrides back to the legacy per-type defaults\n- `matrix.<type>` (object) — keyed by AccountingTransactionTypeEnum value (e.g. sales_order_invoice, fba_shipments); unknown types are rejected\n- `matrix.<type>.default` (required, string) — `off` | `per_document` | `daily` | `monthly`\n- `matrix.<type>.channels` (optional, object) — per-channel overrides keyed by EXISTING integration instance ID (string keys); unknown IDs are rejected\n- `matrix.<type>.channels.<id>` (string) — `off` | `per_document` | `daily` | `monthly`\n\n**Server-side FBA clamp:** FBA monthly-only types (fba_adjustments, fba_customer_returns, fba_receipts, fba_shipments, fba_vendor_returns, fba_warehouse_transfers, amazon_pending_inbound_shipment) are clamped server-side — `daily` / `per_document` become `monthly`; `off` survives. The clamp is never trusted to the client.\n\n**Validation errors (422):** unknown type key, invalid granularity value, non-object type/channels config, or non-existent channel integration instance ID — all reported under the `matrix` key.\n\nReturns 404 when no accounting connection is configured.\n\nPermission: requires `accounting.manage_settings` (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it.","body":{"mode":"raw","raw":"{\n  \"matrix\": {\n    \"sales_order_invoice\": {\n      \"default\": \"per_document\",\n      \"channels\": {\n        \"5\": \"daily\",\n        \"8\": \"off\"\n      }\n    },\n    \"sales_order_fulfillment\": {\n      \"default\": \"off\"\n    },\n    \"fba_shipments\": {\n      \"default\": \"monthly\",\n      \"channels\": {\n        \"8\": \"monthly\"\n      }\n    },\n    \"inventory_adjustment\": {\n      \"default\": \"per_document\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/settings/granularity","host":["{{baseUrl}}"],"path":["api","ledger","settings","granularity"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"granularity_matrix\": {\n      \"sales_order_invoice\": {\n        \"default\": \"per_document\",\n        \"channels\": {\n          \"5\": \"daily\",\n          \"8\": \"off\"\n        }\n      },\n      \"sales_order_fulfillment\": {\n        \"default\": \"off\"\n      },\n      \"fba_shipments\": {\n        \"default\": \"monthly\",\n        \"channels\": {\n          \"8\": \"monthly\"\n        }\n      },\n      \"inventory_adjustment\": {\n        \"default\": \"per_document\"\n      }\n    }\n  },\n  \"message\": \"Granularity settings saved.\"\n}"}]},{"name":"Get Generation Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/settings/generation","host":["{{baseUrl}}"],"path":["api","ledger","settings","generation"]},"description":"Effective state of the ledger-generation kill switch plus outbox health (the Settings → Generation card).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:**\n- `enabled` — the EFFECTIVE state: tenant switch OR the environment override\n- `tenant_enabled` — the per-tenant switch (`AccountingSettings::$ledger_generation_enabled`)\n- `environment_override` — the `LEDGER_GENERATION_ENABLED` env flag; when true, generation runs for every tenant on the install regardless of the tenant switch\n- `generate_purchase_order_transactions` — per-tenant opt-in (`AccountingSettings::$generate_purchase_order_transactions`, default false) for the non-posting PURCHASE_ORDER commitment entry; off by default — when true a PURCHASE_ORDER commitment entry is generated per PO, when false (the default) the PURCHASE_ORDER posting rule returns null so no PO entries are generated (existing ones are left untouched)\n- `outbox.pending` — document changes waiting to be turned into ledger entries\n- `outbox.failed` — outbox rows that exhausted their retry budget (terminal)\n- `outbox.last_processed_at` — last time the generation worker completed a row (null = never)\n- `schedule.next_generation_run_at` — UTC datetime of the next per-minute outbox drain run\n- `schedule.next_reconcile_run_at` — UTC datetime of the next daily reconciliation sweep"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/settings/generation","host":["{{baseUrl}}"],"path":["api","ledger","settings","generation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"generation\": {\n      \"enabled\": true,\n      \"tenant_enabled\": true,\n      \"environment_override\": false,\n      \"generate_purchase_order_transactions\": true,\n      \"outbox\": {\n        \"pending\": 3,\n        \"failed\": 0,\n        \"last_processed_at\": \"2026-06-12 02:31:32\"\n      },\n      \"schedule\": {\n        \"next_generation_run_at\": \"2026-06-12 20:21:00\",\n        \"next_reconcile_run_at\": \"2026-06-13 00:00:00\"\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Generation Switch","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/settings/generation","host":["{{baseUrl}}"],"path":["api","ledger","settings","generation"]},"description":"Flip the per-tenant generation kill switch (`AccountingSettings::$ledger_generation_enabled`) and return the refreshed status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings` permission (403 without it).\n\n**Request body:**\n- `enabled` (boolean, required) — whether this tenant generates accounting entries\n- `generate_purchase_order_transactions` (boolean, optional) — per-tenant opt-in for the non-posting PURCHASE_ORDER commitment entry (`AccountingSettings::$generate_purchase_order_transactions`, default false). Off by default. Omit to leave it unchanged; set true to opt in so a PURCHASE_ORDER commitment entry is generated per PO. When false (the default) the PURCHASE_ORDER posting rule returns null and no PO entries are generated (existing ones are left untouched).\n\n**Note:** the `LEDGER_GENERATION_ENABLED` environment override is not writable from the API — disabling the tenant switch while the override is on leaves generation effectively running, which the response surfaces via `environment_override`.\n- `schedule.next_generation_run_at` — UTC datetime of the next per-minute outbox drain run\n- `schedule.next_reconcile_run_at` — UTC datetime of the next daily reconciliation sweep","body":{"mode":"raw","raw":"{\n  \"enabled\": true,\n  \"generate_purchase_order_transactions\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/settings/generation","host":["{{baseUrl}}"],"path":["api","ledger","settings","generation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"generation\": {\n      \"enabled\": true,\n      \"tenant_enabled\": true,\n      \"environment_override\": false,\n      \"generate_purchase_order_transactions\": true,\n      \"outbox\": {\n        \"pending\": 3,\n        \"failed\": 0,\n        \"last_processed_at\": \"2026-06-12 02:31:32\"\n      },\n      \"schedule\": {\n        \"next_generation_run_at\": \"2026-06-12 20:21:00\",\n        \"next_reconcile_run_at\": \"2026-06-13 00:00:00\"\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Connections","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/connections","host":["{{baseUrl}}"],"path":["api","ledger","connections"]},"description":"The connections panel view-model: one row per supported accounting integration instance (QuickBooks Online / Xero).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Per-connection fields:**\n- `id` / `provider` (`qbo` | `xero`) / `name`\n- `health.sync_status` — the connection's sync status value; `health.paused` — true when sync is not active\n- `lock_date` — the imported provider books-closed lock date (Y-m-d), or null\n- `rate_budget_remaining` — Xero only: the remaining daily API budget from the X-DayLimit-Remaining header; null for QBO (no daily budget)\n- `last_inbound_event_at` — when the last inbound (webhook/CDC) event arrived, or null\n- `open_operations` — open sync-operation counts keyed by state (pending, queued, in_flight, failed_retryable, needs_action); empty object when no open work\n- `capabilities` — per-provider feature flags used to show/hide reconciliation lanes: `supports_trial_balance` (Starting Balances lane — true for both Xero and QuickBooks Online), `supports_bank_statement_lines` (Statement Match lane — Xero only), `supports_webhooks` (inbound change events — Xero only)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/connections","host":["{{baseUrl}}"],"path":["api","ledger","connections"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connections\": [\n      {\n        \"id\": 3,\n        \"provider\": \"qbo\",\n        \"name\": \"QuickBooks Online\",\n        \"health\": {\n          \"sync_status\": \"active\",\n          \"paused\": false\n        },\n        \"lock_date\": \"2026-04-30\",\n        \"rate_budget_remaining\": null,\n        \"last_inbound_event_at\": \"2026-06-10T18:42:11+00:00\",\n        \"open_operations\": {\n          \"pending\": 4,\n          \"queued\": 2,\n          \"in_flight\": 1,\n          \"needs_action\": 3,\n          \"failed_retryable\": 1\n        },\n        \"capabilities\": {\n          \"supports_trial_balance\": true,\n          \"supports_bank_statement_lines\": false,\n          \"supports_webhooks\": false\n        }\n      },\n      {\n        \"id\": 7,\n        \"provider\": \"xero\",\n        \"name\": \"Xero AU\",\n        \"health\": {\n          \"sync_status\": \"paused\",\n          \"paused\": true\n        },\n        \"lock_date\": \"2026-03-31\",\n        \"rate_budget_remaining\": 4120,\n        \"last_inbound_event_at\": \"2026-06-09T02:15:40+00:00\",\n        \"open_operations\": {},\n        \"capabilities\": {\n          \"supports_trial_balance\": true,\n          \"supports_bank_statement_lines\": true,\n          \"supports_webhooks\": true\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Get Setup Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/setup/status","host":["{{baseUrl}}"],"path":["api","ledger","setup","status"]},"description":"Accounting setup wizard state: which steps are done and what's left.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nReturns `generation_enabled` (the per-tenant on/off switch), `has_chart` + `chart_count` (does a chart of accounts exist), `accounting_integration` ({provider:xero|qbo, name} or null), and `required_mappings` — the step 2 role list (`role`, `label`, `category` plus the default `code`/`name`/`type`), and `suggested_accounts` — the step 1 chart of accounts, each `code` defined once (`code`, `name`, `type`). Manual setup is two steps: edit the accounts, then map each role to one of them. Several roles can share an account. `warehouses` lists the stock-holding warehouses, for the optional step that gives a warehouse its own inventory account."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/setup/status","host":["{{baseUrl}}"],"path":["api","ledger","setup","status"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"setup\": {\n      \"generation_enabled\": false,\n      \"has_chart\": false,\n      \"chart_count\": 0,\n      \"accounting_integration\": null,\n      \"suggested_accounts\": [\n        {\n          \"code\": \"4000\",\n          \"name\": \"Sales\",\n          \"type\": \"Sales\"\n        },\n        {\n          \"code\": \"5000\",\n          \"name\": \"Cost of Goods Sold\",\n          \"type\": \"Directcosts\"\n        },\n        {\n          \"code\": \"2100\",\n          \"name\": \"Accrued Purchases\",\n          \"type\": \"Currliab\"\n        },\n        {\n          \"code\": \"6900\",\n          \"name\": \"Rounding\",\n          \"type\": \"Expense\"\n        }\n      ],\n      \"required_mappings\": [\n        {\n          \"role\": \"sales_orders\",\n          \"label\": \"Revenue recognised when you invoice a sales order.\",\n          \"category\": \"Sales & revenue\",\n          \"code\": \"4000\",\n          \"name\": \"Sales\",\n          \"type\": \"Sales\"\n        },\n        {\n          \"role\": \"shipping_sales_orders\",\n          \"label\": \"Shipping revenue charged to customers on sales orders.\",\n          \"category\": \"Sales & revenue\",\n          \"code\": \"4000\",\n          \"name\": \"Sales\",\n          \"type\": \"Sales\"\n        },\n        {\n          \"role\": \"cogs\",\n          \"label\": \"The inventory cost of items shipped — your cost of goods sold.\",\n          \"category\": \"Cost of goods sold\",\n          \"code\": \"5000\",\n          \"name\": \"Cost of Goods Sold\",\n          \"type\": \"Directcosts\"\n        }\n      ],\n      \"warehouses\": [\n        {\n          \"id\": 1,\n          \"name\": \"Main Warehouse\",\n          \"type\": \"direct\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"West Coast 3PL\",\n          \"type\": \"3pl\"\n        }\n      ]\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Apply Suggested Chart","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/setup/apply-suggested-chart","host":["{{baseUrl}}"],"path":["api","ledger","setup","apply-suggested-chart"]},"description":"Manual accounting setup in two parts: create the chart of accounts, then wire each NominalCodeMappingSettings role to one of those accounts. Gated by the `accounting.manage_settings` permission.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (both optional, sent together — omit both to apply SKU's default chart + assignments):**\n- `accounts` — the chart of accounts. Each: `code` (string), `name` (string), `type` (one of: Revenue, Expense, Asset, Liability, Equity, Bank, Current, Inventory, Fixed, Directcosts, Currliab, Termliab, Sales). Codes must be unique.\n- `assignments` — a `role` → account `code` map. Keys are NominalCodeMappingSettings roles (e.g. `sales_orders`, `cogs`, `inventory_control`, `accounts_payable`); each value is one of the account codes above. Several roles may share a code (e.g. `sales_orders` + `shipping_sales_orders` both on `4000`).\n- `warehouse_inventory_accounts` (optional) — a warehouse id → account `code` map giving a warehouse its own inventory account (posting resolves the inventory account per warehouse). Each code must be one of the accounts above; unknown warehouses are skipped.\n\nOnly allowed when the tenant has NO chart yet — otherwise 422 on `accounts`. Every assignment must reference an account in `accounts`, else 422 on `assignments`; a warehouse mapped to a missing code is 422 on `warehouse_inventory_accounts`.","body":{"mode":"raw","raw":"{\n  \"accounts\": [\n    {\n      \"code\": \"1000\",\n      \"name\": \"Inventory Control\",\n      \"type\": \"Current\"\n    },\n    {\n      \"code\": \"4000\",\n      \"name\": \"Sales\",\n      \"type\": \"Sales\"\n    },\n    {\n      \"code\": \"5000\",\n      \"name\": \"Cost of Goods Sold\",\n      \"type\": \"Directcosts\"\n    }\n  ],\n  \"assignments\": {\n    \"inventory_control\": \"1000\",\n    \"sales_orders\": \"4000\",\n    \"shipping_sales_orders\": \"4000\",\n    \"cogs\": \"5000\"\n  },\n  \"warehouse_inventory_accounts\": {\n    \"12\": \"1000\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/setup/apply-suggested-chart","host":["{{baseUrl}}"],"path":["api","ledger","setup","apply-suggested-chart"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"result\": {\n      \"created\": 14,\n      \"chart_count\": 14\n    }\n  },\n  \"message\": \"Chart of accounts created — 14 accounts added.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Accounting Dimensions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions"]},"description":"Read the tracking-category (Xero) / class (QBO) settings for the accounting connection: the active provider, its dimension capabilities, the mirrored tracking categories/options (or classes) available to map, the sales channels (including a synthetic \"SKU.io (internal)\" pseudo-channel for internal orders), and the saved per-channel slot configuration. Used to build P&L segmentation such as COGS by sales channel.\n\n**Authentication:** Requires Bearer token.\n\nReturns 404 when no accounting connection is configured. For QBO the `capabilities` object also carries `class_tracking_enabled`, `class_tracking_per_line`, and `plan_supports_classes`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connection_id\": 7,\n    \"provider\": \"xero\",\n    \"capabilities\": {\n      \"max_slots\": 2,\n      \"dimension_types\": [\n        \"xero_tracking_category\"\n      ],\n      \"class_tracking_enabled\": null,\n      \"class_tracking_per_line\": null,\n      \"plan_supports_classes\": null,\n      \"write_scope_available\": true,\n      \"warnings\": []\n    },\n    \"dimensions\": [\n      {\n        \"mirror_id\": 12,\n        \"name\": \"Sales Channel\",\n        \"status\": \"ACTIVE\",\n        \"values\": [\n          {\n            \"mirror_id\": 33,\n            \"name\": \"Amazon US\",\n            \"status\": \"ACTIVE\"\n          },\n          {\n            \"mirror_id\": 34,\n            \"name\": \"Shopify\",\n            \"status\": \"ACTIVE\"\n          }\n        ]\n      }\n    ],\n    \"channels\": [\n      {\n        \"instance_id\": 5,\n        \"name\": \"Amazon US\",\n        \"sub_channels\": [\n          {\n            \"id\": 12,\n            \"name\": \"amazon.com\"\n          }\n        ]\n      },\n      {\n        \"instance_id\": null,\n        \"name\": \"SKU.io (internal)\",\n        \"sub_channels\": []\n      }\n    ],\n    \"config\": {\n      \"slots\": [\n        {\n          \"slot\": 1,\n          \"provider_dimension\": {\n            \"type\": \"xero_tracking_category\",\n            \"mirror_id\": 12\n          },\n          \"driver\": \"sales_channel\",\n          \"apply_to\": {\n            \"revenue\": true,\n            \"cogs\": true,\n            \"fba\": true\n          },\n          \"default_value_mirror_id\": null,\n          \"mappings\": [\n            {\n              \"channel_instance_id\": 5,\n              \"value_mirror_id\": 33,\n              \"sub_channel_overrides\": {\n                \"12\": 34\n              }\n            }\n          ]\n        }\n      ]\n    },\n    \"warnings\": [\n      {\n        \"slot\": 1,\n        \"type\": \"unmapped_channels\",\n        \"count\": 1\n      }\n    ]\n  }\n}"}]},{"name":"Update Accounting Dimensions","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions"]},"description":"Save the per-channel slot configuration. Up to two dimension slots are allowed; each slot must reference a distinct provider dimension (a 422 is returned otherwise).\n\n**Authentication:** Requires Bearer token.\n\n**Slot fields:**\n- `slot` — 1 or 2\n- `provider_dimension.type` — `xero_tracking_category` or `qbo_class`\n- `provider_dimension.mirror_id` — the local id of the chosen dimension\n- `driver` — `sales_channel`\n- `apply_to` — object with `revenue`, `cogs`, `fba` booleans (which document families are tagged)\n- `default_value_mirror_id` — fallback value id applied to unmapped channels (null to leave them untagged)\n- `mappings[]` — one row per channel: `channel_instance_id` (null for the internal pseudo-channel), `value_mirror_id`, and optional `sub_channel_overrides` keyed by sub-channel id\n\nReturns the saved configuration with recomputed warnings.","body":{"mode":"raw","raw":"{\n  \"slots\": [\n    {\n      \"slot\": 1,\n      \"provider_dimension\": {\n        \"type\": \"xero_tracking_category\",\n        \"mirror_id\": 12\n      },\n      \"driver\": \"sales_channel\",\n      \"apply_to\": {\n        \"revenue\": true,\n        \"cogs\": true,\n        \"fba\": true\n      },\n      \"default_value_mirror_id\": null,\n      \"mappings\": [\n        {\n          \"channel_instance_id\": 5,\n          \"value_mirror_id\": 33,\n          \"sub_channel_overrides\": {}\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"provider\": \"xero\",\n    \"capabilities\": {\n      \"max_slots\": 2,\n      \"dimension_types\": [\n        \"xero_tracking_category\"\n      ],\n      \"class_tracking_enabled\": null,\n      \"class_tracking_per_line\": null,\n      \"plan_supports_classes\": null,\n      \"write_scope_available\": true,\n      \"warnings\": []\n    },\n    \"dimensions\": [\n      {\n        \"mirror_id\": 12,\n        \"name\": \"Sales Channel\",\n        \"status\": \"ACTIVE\",\n        \"values\": [\n          {\n            \"mirror_id\": 33,\n            \"name\": \"Amazon US\",\n            \"status\": \"ACTIVE\"\n          },\n          {\n            \"mirror_id\": 34,\n            \"name\": \"Shopify\",\n            \"status\": \"ACTIVE\"\n          }\n        ]\n      }\n    ],\n    \"channels\": [\n      {\n        \"instance_id\": 5,\n        \"name\": \"Amazon US\",\n        \"sub_channels\": [\n          {\n            \"id\": 12,\n            \"name\": \"amazon.com\"\n          }\n        ]\n      },\n      {\n        \"instance_id\": null,\n        \"name\": \"SKU.io (internal)\",\n        \"sub_channels\": []\n      }\n    ],\n    \"config\": {\n      \"slots\": [\n        {\n          \"slot\": 1,\n          \"provider_dimension\": {\n            \"type\": \"xero_tracking_category\",\n            \"mirror_id\": 12\n          },\n          \"driver\": \"sales_channel\",\n          \"apply_to\": {\n            \"revenue\": true,\n            \"cogs\": true,\n            \"fba\": true\n          },\n          \"default_value_mirror_id\": null,\n          \"mappings\": [\n            {\n              \"channel_instance_id\": 5,\n              \"value_mirror_id\": 33,\n              \"sub_channel_overrides\": {\n                \"12\": 34\n              }\n            }\n          ]\n        }\n      ]\n    },\n    \"warnings\": [\n      {\n        \"slot\": 1,\n        \"type\": \"unmapped_channels\",\n        \"count\": 1\n      }\n    ]\n  }\n}"}]},{"name":"Refresh Accounting Dimensions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/refresh","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","refresh"]},"description":"Re-pull the connected provider's tracking categories/options (Xero) or classes (QBO) into the local mirror, then return the refreshed settings payload. Runs synchronously; the datasets are small.\n\n**Authentication:** Requires Bearer token.\n\nReturns 502 when the provider could not be reached."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/refresh","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"provider\": \"xero\",\n    \"capabilities\": {\n      \"max_slots\": 2,\n      \"dimension_types\": [\n        \"xero_tracking_category\"\n      ],\n      \"class_tracking_enabled\": null,\n      \"class_tracking_per_line\": null,\n      \"plan_supports_classes\": null,\n      \"write_scope_available\": true,\n      \"warnings\": []\n    },\n    \"dimensions\": [\n      {\n        \"mirror_id\": 12,\n        \"name\": \"Sales Channel\",\n        \"status\": \"ACTIVE\",\n        \"values\": [\n          {\n            \"mirror_id\": 33,\n            \"name\": \"Amazon US\",\n            \"status\": \"ACTIVE\"\n          },\n          {\n            \"mirror_id\": 34,\n            \"name\": \"Shopify\",\n            \"status\": \"ACTIVE\"\n          }\n        ]\n      }\n    ],\n    \"channels\": [\n      {\n        \"instance_id\": 5,\n        \"name\": \"Amazon US\",\n        \"sub_channels\": [\n          {\n            \"id\": 12,\n            \"name\": \"amazon.com\"\n          }\n        ]\n      },\n      {\n        \"instance_id\": null,\n        \"name\": \"SKU.io (internal)\",\n        \"sub_channels\": []\n      }\n    ],\n    \"config\": {\n      \"slots\": [\n        {\n          \"slot\": 1,\n          \"provider_dimension\": {\n            \"type\": \"xero_tracking_category\",\n            \"mirror_id\": 12\n          },\n          \"driver\": \"sales_channel\",\n          \"apply_to\": {\n            \"revenue\": true,\n            \"cogs\": true,\n            \"fba\": true\n          },\n          \"default_value_mirror_id\": null,\n          \"mappings\": [\n            {\n              \"channel_instance_id\": 5,\n              \"value_mirror_id\": 33,\n              \"sub_channel_overrides\": {\n                \"12\": 34\n              }\n            }\n          ]\n        }\n      ]\n    },\n    \"warnings\": [\n      {\n        \"slot\": 1,\n        \"type\": \"unmapped_channels\",\n        \"count\": 1\n      }\n    ]\n  }\n}"}]},{"name":"Create Accounting Dimension Values","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/values","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","values"]},"description":"Create one or more tracking options (Xero) or classes (QBO) in the connected provider and mirror them locally. Names are matched case-insensitively against the mirror first, so an existing value is reused instead of duplicated.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `slot` (1 or 2) and `names` (array of value names, each ≤ 100 chars).\n\nReturns per-name results: `created`, `matched_existing`, and `failed` (each failure carries an `error` code such as `qbo_usage_limit` or `missing_scope` and a message). Partial success is expected.","body":{"mode":"raw","raw":"{\n  \"slot\": 1,\n  \"names\": [\n    \"Amazon US\",\n    \"eBay\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/values","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","values"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": [\n      {\n        \"mirror_id\": 41,\n        \"name\": \"Amazon US\",\n        \"status\": \"ACTIVE\"\n      }\n    ],\n    \"matched_existing\": [\n      {\n        \"mirror_id\": 33,\n        \"name\": \"eBay\"\n      }\n    ],\n    \"failed\": [\n      {\n        \"name\": \"Retail\",\n        \"error\": \"qbo_usage_limit\",\n        \"message\": \"QuickBooks Plus allows 40 combined classes and locations.\"\n      }\n    ]\n  }\n}"}]},{"name":"Create Accounting Dimension","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","dimensions"]},"description":"Create a new Xero tracking category in the connected organisation. Only succeeds when a free active category slot is available (Xero allows at most two active tracking categories).\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `name` (≤ 100 chars).\n\nWhen both active category slots are already consumed, returns an `{ error: \"xero_category_slots_consumed\", message }` body.","body":{"mode":"raw","raw":"{\n  \"name\": \"Sales Channel\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/accounting-dimensions/dimensions","host":["{{baseUrl}}"],"path":["api","ledger","accounting-dimensions","dimensions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mirror_id\": 13,\n    \"name\": \"Sales Channel\",\n    \"status\": \"ACTIVE\"\n  }\n}"}]},{"name":"Get Lock Dates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/period-locks","host":["{{baseUrl}}"],"path":["api","ledger","period-locks"]},"description":"The accounting lock-date control surface: the effective lock (later of your lock date and enforced provider locks), the internal lock with audit info, per-connection provider locks + enforcement, and the locked-period policy.\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/period-locks","host":["{{baseUrl}}"],"path":["api","ledger","period-locks"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period_locks\": {\n      \"effective_lock_date\": \"2026-07-31\",\n      \"internal\": {\n        \"lock_date\": \"2026-06-30\",\n        \"note\": \"June close\",\n        \"set_by\": {\n          \"id\": 12,\n          \"name\": \"Jamie Rivera\"\n        },\n        \"set_at\": \"2026-07-01T14:03:00+00:00\"\n      },\n      \"providers\": [\n        {\n          \"connection_id\": 30,\n          \"provider\": \"xero\",\n          \"connection_name\": \"Xero\",\n          \"lock_date\": \"2026-05-31\",\n          \"enforced\": true,\n          \"imported_at\": \"2026-07-01T06:00:02+00:00\",\n          \"suggestable\": false\n        }\n      ],\n      \"policy\": \"redate\"\n    }\n  }\n}"}]},{"name":"Apply Provider Lock Suggestion","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/period-locks/apply-suggestion","host":["{{baseUrl}}"],"path":["api","ledger","period-locks","apply-suggestion"]},"description":"Adopt a connection's imported provider lock date as the internal accounting lock date.\n\n**Body:** `connection_id` (integer, required).\n\nReturns the updated lock-date surface; 422 when the connection has no imported provider lock or the date precedes the accounting start date.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 30\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/period-locks/apply-suggestion","host":["{{baseUrl}}"],"path":["api","ledger","period-locks","apply-suggestion"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period_locks\": {\n      \"effective_lock_date\": \"2026-07-31\",\n      \"internal\": {\n        \"lock_date\": \"2026-06-30\",\n        \"note\": \"June close\",\n        \"set_by\": {\n          \"id\": 12,\n          \"name\": \"Jamie Rivera\"\n        },\n        \"set_at\": \"2026-07-01T14:03:00+00:00\"\n      },\n      \"providers\": [\n        {\n          \"connection_id\": 30,\n          \"provider\": \"xero\",\n          \"connection_name\": \"Xero\",\n          \"lock_date\": \"2026-05-31\",\n          \"enforced\": true,\n          \"imported_at\": \"2026-07-01T06:00:02+00:00\",\n          \"suggestable\": false\n        }\n      ],\n      \"policy\": \"redate\"\n    }\n  }\n}"}]},{"name":"Toggle Provider Lock Enforcement","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/period-locks/provider/{connectionId}","host":["{{baseUrl}}"],"path":["api","ledger","period-locks","provider",":connectionId"],"variable":[{"key":"connectionId","value":"","description":"The connection ID."}]},"description":"Set whether a connection's imported provider lock is enforced locally.\n\n**Path:** `connectionId` (integer). **Body:** `enforced` (boolean). Off ⇒ the provider date is suggestion-only.\n\nReturns the updated lock-date surface.","body":{"mode":"raw","raw":"{\n  \"enforced\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/ledger/period-locks/provider/{connectionId}","host":["{{baseUrl}}"],"path":["api","ledger","period-locks","provider",":connectionId"],"variable":[{"key":"connectionId","value":"","description":"The connection ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period_locks\": {\n      \"effective_lock_date\": \"2026-07-31\",\n      \"internal\": {\n        \"lock_date\": \"2026-06-30\",\n        \"note\": \"June close\",\n        \"set_by\": {\n          \"id\": 12,\n          \"name\": \"Jamie Rivera\"\n        },\n        \"set_at\": \"2026-07-01T14:03:00+00:00\"\n      },\n      \"providers\": [\n        {\n          \"connection_id\": 30,\n          \"provider\": \"xero\",\n          \"connection_name\": \"Xero\",\n          \"lock_date\": \"2026-05-31\",\n          \"enforced\": true,\n          \"imported_at\": \"2026-07-01T06:00:02+00:00\",\n          \"suggestable\": false\n        }\n      ],\n      \"policy\": \"redate\"\n    }\n  }\n}"}]},{"name":"Get Opening Balance Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]},"description":"The opening balance is an INTERNAL journal entry seeding each GL account's position as of the tenant's books-start date — it is NEVER synced to the accounting provider (non-bypassable `internal_only` eligibility), which already holds these balances. The inventory line is derived from the valuation at end of day prior to the Inventory Start Date and snapshotted at apply time. Spec: docs/plans/ledger-opening-balance-entry.md.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nReturns the document (draft or applied) with its lines, the live derived inventory figure, drift vs the applied snapshot, the suggested equity account, the prior-history double-count warning count, and the effective generation switch."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-01-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"12500.0000\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"960\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 1,\n            \"nominal_code\": {\n              \"id\": 6,\n              \"code\": \"1200\",\n              \"name\": \"Accounts Receivable\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"5000.0000\",\n            \"is_inventory_line\": false\n          },\n          {\n            \"id\": 2,\n            \"nominal_code\": {\n              \"id\": 4,\n              \"code\": \"1000\",\n              \"name\": \"Inventory Control\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"12500.0000\",\n            \"is_inventory_line\": true\n          }\n        ],\n        \"entry\": {\n          \"id\": 61,\n          \"reference\": \"OB-2026-01-01\",\n          \"status\": \"draft\",\n          \"total_debit\": \"17500.0000\",\n          \"effective_at\": \"2025-12-31T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-01-01\",\n      \"derived_inventory_total\": \"12500.0000\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"960\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 0,\n      \"generation_enabled\": true\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Upsert Opening Balance Draft","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]},"description":"The opening balance is an INTERNAL journal entry seeding each GL account's position as of the tenant's books-start date — it is NEVER synced to the accounting provider (non-bypassable `internal_only` eligibility), which already holds these balances. The inventory line is derived from the valuation at end of day prior to the Inventory Start Date and snapshotted at apply time. Spec: docs/plans/ledger-opening-balance-entry.md.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\n**Request body:** `as_of_date` (Y-m-d, must equal the Inventory Start Date at apply time), optional `equity_nominal_code_id` (balancing account), optional `notes`, and `lines[]` of `{nominal_code_id, direction: debit|credit, amount > 0}` — accounts must be unique; the inventory account is system-managed and may not appear. 422 once the document is applied (delete and recreate, or rebuild).","body":{"mode":"raw","raw":"{\n  \"as_of_date\": \"2026-01-01\",\n  \"equity_nominal_code_id\": 14,\n  \"notes\": null,\n  \"lines\": [\n    {\n      \"nominal_code_id\": 6,\n      \"direction\": \"debit\",\n      \"amount\": \"5000.0000\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-01-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"12500.0000\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"960\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 1,\n            \"nominal_code\": {\n              \"id\": 6,\n              \"code\": \"1200\",\n              \"name\": \"Accounts Receivable\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"5000.0000\",\n            \"is_inventory_line\": false\n          },\n          {\n            \"id\": 2,\n            \"nominal_code\": {\n              \"id\": 4,\n              \"code\": \"1000\",\n              \"name\": \"Inventory Control\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"12500.0000\",\n            \"is_inventory_line\": true\n          }\n        ],\n        \"entry\": {\n          \"id\": 61,\n          \"reference\": \"OB-2026-01-01\",\n          \"status\": \"draft\",\n          \"total_debit\": \"17500.0000\",\n          \"effective_at\": \"2025-12-31T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-01-01\",\n      \"derived_inventory_total\": \"12500.0000\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"960\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 0,\n      \"generation_enabled\": true\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Opening Balance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]},"description":"The opening balance is an INTERNAL journal entry seeding each GL account's position as of the tenant's books-start date — it is NEVER synced to the accounting provider (non-bypassable `internal_only` eligibility), which already holds these balances. The inventory line is derived from the valuation at end of day prior to the Inventory Start Date and snapshotted at apply time. Spec: docs/plans/ledger-opening-balance-entry.md.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\nRemoves the document; an applied document's entry is discarded (drafts) or reversed (posted) through the standard source-deleted pathway — the correction chain remains auditable."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Opening balance deleted.\",\n  \"status\": \"success\"\n}"}]},{"name":"Preview Opening Balances from Provider","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/provider-preview?connection_id=12","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","provider-preview"],"query":[{"key":"connection_id","value":"12","description":"REQUIRED. Integer ID of the accounting connection (QuickBooks Online or Xero) whose trial balance is read.","disabled":true}]},"description":"Reads the selected connection's Trial Balance \"as at\" the snapshot date and proposes opening-balance lines mapped onto SKU's chart of accounts. Works for both QuickBooks Online and Xero connections — the trial balance is fetched from whichever provider the connection belongs to. Read-only — nothing is persisted; the frontend uses the result to seed the opening-balance draft editor, which the user then reviews and applies.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMapping rules:\n- Each provider account is matched to a SKU nominal code by **code**.\n- The signed provider balance (debit-positive) is split into a `direction` (`debit` when ≥ 0, else `credit`) and a positive `amount`.\n- Near-zero balances (|balance| < 0.005) are skipped.\n- The **inventory-control** account is excluded (returned as `skipped_inventory`) — SKU derives that opening line from its own valuation, so importing the provider figure would double-count it.\n- Provider accounts with no code, or whose code matches no nominal code, are returned in `unmatched` so the user can map them and re-fetch.\n\n**Errors:** returns `422` with a friendly message when the connection's provider cannot produce a trial balance report, and `404` when `connection_id` is not a supported accounting connection.\n\n**Authentication:** Requires Bearer token. (Read-only route — no extra permission middleware; the mutating apply/upsert routes enforce `accounting.manage_settings`.)\n\n**Query parameters:**\n- `connection_id` (integer, required) — the integration instance to read from.\n- `as_of` (date `Y-m-d`, optional) — trial-balance snapshot date; defaults to today.\n\nEach `lines[]` and `unmatched[]` item also carries account metadata from the provider's chart of accounts: `account_class` (normalized bucket: `Asset`, `Liability`, `Equity`, `Revenue`, or `Expense`; null when unknown), `account_type` (the provider's own finer account type label, e.g. \"Fixed Asset\"), and `mirror_account_id` (the id of the provider account record in SKU, for linking to its detail view; null when the account is not mirrored locally)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/provider-preview?connection_id=12","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","provider-preview"],"query":[{"key":"connection_id","value":"12","description":"REQUIRED. Integer ID of the accounting connection (QuickBooks Online or Xero) whose trial balance is read.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_import\": {\n      \"connection_id\": 12,\n      \"as_of\": \"2026-01-01\",\n      \"lines\": [\n        {\n          \"nominal_code_id\": 6,\n          \"code\": \"1200\",\n          \"name\": \"Accounts Receivable\",\n          \"direction\": \"debit\",\n          \"amount\": \"5000.00\",\n          \"provider_account_name\": \"Accounts Receivable (1200)\",\n          \"provider_balance\": 5000\n        },\n        {\n          \"nominal_code_id\": 21,\n          \"code\": \"2100\",\n          \"name\": \"Accounts Payable\",\n          \"direction\": \"credit\",\n          \"amount\": \"3200.50\",\n          \"provider_account_name\": \"Accounts Payable (2100)\",\n          \"provider_balance\": -3200.5\n        }\n      ],\n      \"unmatched\": [\n        {\n          \"code\": \"4500\",\n          \"name\": \"Foreign Exchange Gains (4500)\",\n          \"provider_balance\": -125.75\n        },\n        {\n          \"code\": null,\n          \"name\": \"Rounding\",\n          \"provider_balance\": 0.42\n        }\n      ],\n      \"skipped_inventory\": {\n        \"nominal_code_id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\",\n        \"direction\": \"debit\",\n        \"amount\": \"12500.00\",\n        \"provider_account_name\": \"Inventory Control (1000)\",\n        \"provider_balance\": 12500\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Create Opening Balance Equity Account","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/equity-account","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","equity-account"]},"description":"Create the provider-conventional \"Opening Balance Equity\" account when the chart of accounts has none, so the opening-balance form's balancing-equity selector has something to point at. The created account is type `Equity` and is a never-synced internal plug. Its `code` is the first free preferred code (970, then 3000, then 9999, then numerically incremented past the last candidate), checked against ALL codes including archived ones since `code` is the unique key.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\n**Idempotent:** if an account whose name contains \"opening balance\" already exists, that existing account is returned and no new account is created.\n\nNo request body. Returns the created (or existing) nominal code as `data.nominal_code`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/equity-account","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","equity-account"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"nominal_code\": {\n      \"id\": 14,\n      \"code\": \"970\",\n      \"name\": \"Opening Balance Equity\"\n    }\n  },\n  \"message\": \"Opening Balance Equity account created.\",\n  \"status\": \"success\"\n}"}]},{"name":"Apply Opening Balance","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/apply","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","apply"]},"description":"The opening balance is an INTERNAL journal entry seeding each GL account's position as of the tenant's books-start date — it is NEVER synced to the accounting provider (non-bypassable `internal_only` eligibility), which already holds these balances. The inventory line is derived from the valuation at end of day prior to the Inventory Start Date and snapshotted at apply time. Spec: docs/plans/ledger-opening-balance-entry.md.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\nValidates (as_of_date === Inventory Start Date; equity account present when lines don't balance; Inventory Control mapping set when valuation > 0; generation enabled), snapshots the derived inventory figure, and generates the entry through the standard outbox pipeline. The computed equity counter-line guarantees the entry balances.\n\n**Errors:** 422 with field-specific messages for each failed precondition."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/apply","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","apply"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-01-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"12500.0000\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"960\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 1,\n            \"nominal_code\": {\n              \"id\": 6,\n              \"code\": \"1200\",\n              \"name\": \"Accounts Receivable\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"5000.0000\",\n            \"is_inventory_line\": false\n          },\n          {\n            \"id\": 2,\n            \"nominal_code\": {\n              \"id\": 4,\n              \"code\": \"1000\",\n              \"name\": \"Inventory Control\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"12500.0000\",\n            \"is_inventory_line\": true\n          }\n        ],\n        \"entry\": {\n          \"id\": 61,\n          \"reference\": \"OB-2026-01-01\",\n          \"status\": \"draft\",\n          \"total_debit\": \"17500.0000\",\n          \"effective_at\": \"2025-12-31T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-01-01\",\n      \"derived_inventory_total\": \"12500.0000\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"960\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 0,\n      \"generation_enabled\": true\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Rebuild Opening Balance","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","rebuild"]},"description":"The opening balance is an INTERNAL journal entry seeding each GL account's position as of the tenant's books-start date — it is NEVER synced to the accounting provider (non-bypassable `internal_only` eligibility), which already holds these balances. The inventory line is derived from the valuation at end of day prior to the Inventory Start Date and snapshotted at apply time. Spec: docs/plans/ledger-opening-balance-entry.md.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync`.\n\nRe-derives the inventory snapshot and regenerates the entry — an unchanged document is a hash no-op; a posted entry is corrected via reversal + replacement. Use when the overview reports `drift` (the live valuation moved after a backfill)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","rebuild"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-01-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"12500.0000\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"960\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 1,\n            \"nominal_code\": {\n              \"id\": 6,\n              \"code\": \"1200\",\n              \"name\": \"Accounts Receivable\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"5000.0000\",\n            \"is_inventory_line\": false\n          },\n          {\n            \"id\": 2,\n            \"nominal_code\": {\n              \"id\": 4,\n              \"code\": \"1000\",\n              \"name\": \"Inventory Control\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"12500.0000\",\n            \"is_inventory_line\": true\n          }\n        ],\n        \"entry\": {\n          \"id\": 61,\n          \"reference\": \"OB-2026-01-01\",\n          \"status\": \"draft\",\n          \"total_debit\": \"17500.0000\",\n          \"effective_at\": \"2025-12-31T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-01-01\",\n      \"derived_inventory_total\": \"12500.0000\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"960\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 0,\n      \"generation_enabled\": true\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Pending Start Date Transition","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition"]},"description":"Returns the pending guarded accounting-start-date change awaiting confirmation, or `null` under `start_date_transition` when the books are settled (no change in flight).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen an applied opening balance's effective accounting start date is moved, the change is PARKED rather than applied immediately: the old anchor's books are already posted, so the user must explicitly confirm (apply) or abandon (rollback). This read-only endpoint surfaces that parked change so the UI can render the review banner.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields (`start_date_transition`):**\n- `id` — transition row id\n- `status` — `pending` while awaiting confirmation\n- `old_effective_start_date` / `new_effective_start_date` — the effective accounting start dates (where the opening entry posts)\n- `old_anchor_date` / `new_anchor_date` — the trial-balance \"as at\" anchor (= effective start − 1 day) that the replacement opening balance is imported against\n- `old_opening_total` — the frozen total of the currently-applied opening balance\n- `new_opening_total` — the PROJECTED total of the replacement opening balance at the new anchor. This is `null` until the replacement trial balance has been captured at `new_anchor_date` — a GET preview never forces a metered provider capture, so the projection is simply withheld until the async capture lands.\n\nReturns `{ \"start_date_transition\": null }` when no transition is pending."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"start_date_transition\": {\n      \"id\": 7,\n      \"status\": \"pending\",\n      \"old_effective_start_date\": \"2026-05-01\",\n      \"new_effective_start_date\": \"2026-06-01\",\n      \"old_anchor_date\": \"2026-04-30\",\n      \"new_anchor_date\": \"2026-05-31\",\n      \"old_opening_total\": \"1234.5600\",\n      \"new_opening_total\": \"500.0000\"\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Apply Start Date Transition","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition/apply","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition","apply"]},"description":"Confirms the parked accounting-start-date change. The opening balance is re-imported IN PLACE from the replacement trial balance at the new anchor (the same opening-balance row is kept — preserving its notes, created-by, equity account, applied status and history), its entry is reversed and reposted through the standard outbox pipeline, and the reconciliation is re-anchored + re-backfilled via a tracked Sync Provider GL Journals job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\nNo request body. Applying intentionally permits a metered provider capture if the replacement trial balance hasn't been snapshotted yet (it is a deliberate user action). On success the pending transition settles to `applied` and `opening_balance_overview.pending_start_date_transition` becomes `null`.\n\n**Errors:** 422 when there is no pending transition, when no Xero accounting connection exists, or when ledger generation is disabled for the tenant."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition/apply","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition","apply"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-05-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"0.0000\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"970\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 12,\n            \"nominal_code\": {\n              \"id\": 9,\n              \"code\": \"4000\",\n              \"name\": \"Sales\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"500.0000\",\n            \"is_inventory_line\": false\n          }\n        ],\n        \"entry\": {\n          \"id\": 88,\n          \"reference\": \"OB-2026-05-01/R\",\n          \"status\": \"draft\",\n          \"total_debit\": \"500.0000\",\n          \"effective_at\": \"2026-04-30T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-05-01\",\n      \"derived_inventory_total\": \"0.0000\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"970\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 1,\n      \"generation_enabled\": true,\n      \"pending_start_date_transition\": null\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Rollback Start Date Transition","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition/rollback","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition","rollback"]},"description":"Abandons the parked accounting-start-date change while it is still pending. The effective accounting start date is reverted to its old value and the transition settles to `cancelled` — the posted books are left completely untouched (no reversal, no rebuild, no reconciliation re-anchor). Safe because while pending the books were never changed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe revert is written directly to settings (not through the Settings endpoint) so it does NOT re-trigger the start-date-change hook that would park a fresh transition.\n\n**Authentication:** Requires Bearer token + `accounting.manage_settings`.\n\nNo request body. On success `opening_balance_overview.pending_start_date_transition` becomes `null` and the opening balance + its posted entry are unchanged.\n\n**Errors:** 422 when there is no pending transition to roll back."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/opening-balance/transition/rollback","host":["{{baseUrl}}"],"path":["api","ledger","opening-balance","transition","rollback"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"opening_balance_overview\": {\n      \"opening_balance\": {\n        \"id\": 1,\n        \"as_of_date\": \"2026-05-01\",\n        \"currency_code\": \"USD\",\n        \"status\": \"applied\",\n        \"inventory_total\": \"1234.5600\",\n        \"equity_nominal_code\": {\n          \"id\": 14,\n          \"code\": \"970\",\n          \"name\": \"Opening Balance Equity\"\n        },\n        \"notes\": null,\n        \"lines\": [\n          {\n            \"id\": 3,\n            \"nominal_code\": {\n              \"id\": 6,\n              \"code\": \"1200\",\n              \"name\": \"Accounts Receivable\"\n            },\n            \"direction\": \"debit\",\n            \"amount\": \"1234.5600\",\n            \"is_inventory_line\": false\n          }\n        ],\n        \"entry\": {\n          \"id\": 61,\n          \"reference\": \"OB-2026-05-01\",\n          \"status\": \"posted\",\n          \"total_debit\": \"1234.5600\",\n          \"effective_at\": \"2026-04-30T23:59:59+00:00\"\n        }\n      },\n      \"inventory_start_date\": \"2026-05-01\",\n      \"derived_inventory_total\": \"1234.5600\",\n      \"inventory_nominal_code\": {\n        \"id\": 4,\n        \"code\": \"1000\",\n        \"name\": \"Inventory Control\"\n      },\n      \"suggested_equity_nominal_code\": {\n        \"id\": 14,\n        \"code\": \"970\",\n        \"name\": \"Opening Balance Equity\"\n      },\n      \"drift\": null,\n      \"prior_history_count\": 1,\n      \"generation_enabled\": true,\n      \"pending_start_date_transition\": null\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Generation Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/generation/candidates","host":["{{baseUrl}}"],"path":["api","ledger","generation","candidates"]},"description":"Preview of the source documents eligible to have ledger entries generated — the entries page \"Generate\" modal. A document is a candidate when it passes the same readiness gate the legacy generation used (`scopeAccountingReady`: drafts, unmapped lines, Amazon channel orders, … are excluded) AND it has no current (non-discarded, non-reversed) ledger entry.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:**\n- `candidates` — Laravel paginator of `{source_type, source_id, type_label, reference, url, date}` rows. `url` is the application UI detail route when one exists; `date` is the document's accounting date (Y-m-d). Without `filter[source_type]` the listing walks every type in tab (label) order, each type's rows newest-first.\n- `tabs` — one row per source type that currently has candidates (`{source_type, label, count}`), label-sorted — drives the modal's tab strip\n- `total` — candidate count across all types for the date range\n- `schedule.next_generation_run_at` / `schedule.next_reconcile_run_at` — UTC datetimes of the next per-minute drain run and the next daily reconciliation sweep (these documents are picked up automatically; a manual run just front-runs the schedule)\n- `has_frozen_history` — whether the tenant has any imported (migrated) ledger history. When true, imported entries are frozen: scope runs skip them unless `include_frozen` is passed to Run Generation Now.\n- `enabled` — the effective generation switch (tenant setting OR environment override); when false a run request would be rejected\n\n**Date filtering** applies to each document's own accounting date column (invoice date, fulfillment date, adjustment date, …), not created_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/generation/candidates","host":["{{baseUrl}}"],"path":["api","ledger","generation","candidates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"candidates\": {\n      \"current_page\": 1,\n      \"data\": [\n        {\n          \"source_type\": \"App\\\\Models\\\\Bill\",\n          \"source_id\": 4,\n          \"type_label\": \"Bill\",\n          \"reference\": \"BILL-1042\",\n          \"url\": null,\n          \"date\": \"2026-06-05\"\n        },\n        {\n          \"source_type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n          \"source_id\": 911,\n          \"type_label\": \"Sales Order Fulfillment\",\n          \"reference\": \"SO-2231/F1\",\n          \"url\": null,\n          \"date\": \"2026-06-04\"\n        }\n      ],\n      \"last_page\": 1,\n      \"per_page\": 10,\n      \"total\": 2,\n      \"from\": 1,\n      \"to\": 2\n    },\n    \"tabs\": [\n      {\n        \"source_type\": \"App\\\\Models\\\\Bill\",\n        \"label\": \"Bill\",\n        \"count\": 1\n      },\n      {\n        \"source_type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n        \"label\": \"Sales Order Fulfillment\",\n        \"count\": 1\n      }\n    ],\n    \"total\": 2,\n    \"schedule\": {\n      \"next_generation_run_at\": \"2026-06-12 20:21:00\",\n      \"next_reconcile_run_at\": \"2026-06-13 00:00:00\"\n    },\n    \"enabled\": true,\n    \"has_frozen_history\": true\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Run Generation Now","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/generation/run","host":["{{baseUrl}}"],"path":["api","ledger","generation","run"]},"description":"Trigger on-demand entry generation: every candidate in scope (see List Generation Candidates) is enqueued as an `updated` ledger outbox row and the drain job is dispatched immediately — the SAME pipeline the per-minute schedule runs, just started now. The posting service's source_version_hash makes already-current documents a free no-op, so the trigger is idempotent.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission (403 without it).\n\n**Request body (all optional):**\n- `candidates` (array|null, max 1000) — explicit selection of documents to generate: `[{source_type, source_id}, ...]`. When present, ONLY these are enqueued and the type/date scope is ignored (the modal's multi-select). Each `source_type` must be a registered source FQN (422 otherwise).\n- `source_type` (string|null) — restrict to one source document FQN from the posting-rule registry; omit/null for all types\n- `date_from` / `date_to` (Y-m-d|null) — restrict by each document's accounting date; `date_to` must be >= `date_from`\n- `include_frozen` (boolean, default false) — scope runs normally skip documents dated before the tenant's accounting cutover (their imported history is frozen so it is never rewritten by accident). Set true to deliberately re-derive that frozen history with the current posting rules — this replaces the migrated figures and can update linked, still-editable provider documents, so treat it as a confirmed administrative action. Ignored when `candidates` is present (hand-picked documents always regenerate).\n\n**Errors:** 422 with an `enabled` error when ledger generation is disabled for the tenant (enable it under Settings → Generation first); 422 for unknown `source_type`.\n\n**Response:** `data.result.enqueued` is the number of documents processed/enqueued. `data.result.skipped_locked_period` counts documents that were skipped because they are dated in a locked accounting period — these are not generated (unlock the period or change the document date, then try again). A locked-period document is reported this way rather than failing the whole run.","body":{"mode":"raw","raw":"{\n  \"source_type\": \"App\\\\Models\\\\Bill\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\",\n  \"candidates\": [\n    {\n      \"source_type\": \"App\\\\Models\\\\Bill\",\n      \"source_id\": 4\n    },\n    {\n      \"source_type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n      \"source_id\": 911\n    }\n  ],\n  \"include_frozen\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/generation/run","host":["{{baseUrl}}"],"path":["api","ledger","generation","run"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"result\": {\n      \"enqueued\": 2,\n      \"skipped_locked_period\": 0\n    }\n  },\n  \"message\": \"Enqueued 2 document(s) for generation — entries will appear within the next minute.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Reconciliation Window","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/window?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","window"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]},"description":"The connection's reconcile window and per-kind cache freshness — \"documents cached from X through Y, last refreshed Z\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nThe window runs from now back to the LATER of the connection's sync start floor and the generation start (earliest current ledger entry). 404 when connection_id is not a supported accounting connection."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/window?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","window"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connection_id\": 5,\n    \"from\": \"2026-01-01\",\n    \"to\": \"2026-06-13\",\n    \"cache_status\": [\n      {\n        \"remote_type\": \"qbo_invoice\",\n        \"backfilled_from\": \"2026-01-01\",\n        \"backfilled_through\": \"2026-06-13\",\n        \"document_count\": 182,\n        \"last_backfilled_at\": \"2026-06-12T02:00:00+00:00\"\n      }\n    ]\n  }\n}"}]},{"name":"Reconciliation Matches","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/matches?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","matches"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The three reconcile buckets for a connection over the (optional) document-date window.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Buckets:**\n- `matched` — SKU entries linked to a provider document (with the cached remote snapshot for variance display)\n- `sku_only` — eligible SKU entries with no link (would create a remote document)\n- `provider_only` — cached provider documents with no link and not dismissed\n\n`from`/`to` (Y-m-d) override the default window. `meta.counts` carries the bucket sizes, including `excluded` (the count of unlinked entries that are not eligible to sync — fetched in full via the excluded endpoint). 404 when connection_id is not a supported accounting connection."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/matches?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","matches"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched\": [\n      {\n        \"entry\": {\n          \"id\": 4821,\n          \"uuid\": \"9f1c...\",\n          \"type\": {\n            \"value\": \"sales_order_invoice\",\n            \"label\": \"Sales Order Invoice\"\n          },\n          \"status\": \"posted\",\n          \"effective_at\": \"2026-06-05T00:00:00+00:00\",\n          \"currency_code\": \"USD\",\n          \"total_debit\": \"250.0000\",\n          \"total_credit\": \"250.0000\",\n          \"reference\": \"INV-1042\",\n          \"reference_suffix\": 0\n        },\n        \"link\": {\n          \"id\": 77,\n          \"provider\": \"qbo\",\n          \"remote_type\": \"qbo_invoice\",\n          \"remote_id\": \"145\",\n          \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=145\",\n          \"link_state\": \"linked_current\",\n          \"remote_status\": \"Active\",\n          \"last_remote_seen_at\": \"2026-06-12T02:00:00+00:00\"\n        },\n        \"remote\": {\n          \"remote_type\": \"qbo_invoice\",\n          \"remote_id\": \"145\",\n          \"reference\": \"INV-1042\",\n          \"total\": \"250.0000\",\n          \"currency\": \"USD\",\n          \"document_date\": \"2026-06-05\",\n          \"status\": \"Active\",\n          \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=145\"\n        }\n      }\n    ],\n    \"sku_only\": [\n      {\n        \"id\": 4822,\n        \"uuid\": \"9f1c...\",\n        \"type\": {\n          \"value\": \"sales_order_invoice\",\n          \"label\": \"Sales Order Invoice\"\n        },\n        \"status\": \"posted\",\n        \"effective_at\": \"2026-06-05T00:00:00+00:00\",\n        \"currency_code\": \"USD\",\n        \"total_debit\": \"250.0000\",\n        \"total_credit\": \"250.0000\",\n        \"reference\": \"INV-1043\",\n        \"reference_suffix\": 0\n      }\n    ],\n    \"provider_only\": [\n      {\n        \"remote_type\": \"qbo_invoice\",\n        \"remote_id\": \"146\",\n        \"reference\": \"INV-9001\",\n        \"total\": \"250.0000\",\n        \"currency\": \"USD\",\n        \"document_date\": \"2026-06-05\",\n        \"status\": \"Active\",\n        \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=145\"\n      }\n    ]\n  },\n  \"meta\": {\n    \"from\": \"2026-01-01\",\n    \"to\": \"2026-06-13\",\n    \"counts\": {\n      \"matched\": 1,\n      \"sku_only\": 1,\n      \"provider_only\": 1,\n      \"excluded\": 12\n    }\n  }\n}"}]},{"name":"List Excluded SKU Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/excluded?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","excluded"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The SKU ledger entries that are excluded from sync for a connection over the (optional) document-date window — unlinked entries that are not eligible to sync, each with the reason(s) it's blocked.\n\n**Authentication:** Requires Bearer token.\n\nThese are exactly the entries hidden from the `sku_only` bucket of the matches endpoint (an empty `sku_only` does not mean everything is synced — thousands of entries can be excluded). Loaded on its own so the matches payload stays light.\n\nEach row carries `reasons[]` as `{code, label}` pairs. Common reason codes: `override_disabled` (manually disabled), `type_disabled`, `channel_disabled`, `before_provider_sync_start_date`, `before_type_sync_start_date`, `batch_member`, `batch_open`, `connection_inactive`, `internal_only`, `granularity_off`.\n\n`from`/`to` (Y-m-d) override the default window. 404 when connection_id is not a supported accounting connection."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/excluded?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","excluded"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4830,\n      \"reference\": \"INV-1050\",\n      \"type\": {\n        \"value\": \"sales_order_invoice\",\n        \"label\": \"Sales Order Invoice\"\n      },\n      \"effective_at\": \"2026-06-05T00:00:00+00:00\",\n      \"currency_code\": \"USD\",\n      \"document_total\": \"250.0000\",\n      \"reasons\": [\n        {\n          \"code\": \"override_disabled\",\n          \"label\": \"Sync manually disabled\"\n        }\n      ]\n    },\n    {\n      \"id\": 4831,\n      \"reference\": \"BILL-2201\",\n      \"type\": {\n        \"value\": \"bill\",\n        \"label\": \"Bill\"\n      },\n      \"effective_at\": \"2026-06-04T00:00:00+00:00\",\n      \"currency_code\": \"USD\",\n      \"document_total\": \"980.0000\",\n      \"reasons\": [\n        {\n          \"code\": \"type_disabled\",\n          \"label\": \"Transaction type not synced\"\n        },\n        {\n          \"code\": \"before_provider_sync_start_date\",\n          \"label\": \"Dated before the sync start date\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Matched Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/matched?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","matched"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The SKU ledger entries already linked to a provider document on a connection, as a paginated, filterable, sortable list. Each row also carries the linked provider document's snapshot in `remote` (remote total, status, and a deep link) so a variance between the two sides can be spotted.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required); standard pagination (`page`, `per_page`), `sort`, per-field `filter[...]`, general `search`, and `filter_groups` (advanced filter tree). Allowed sorts: id, effective_at, reference, total_debit, created_at, type, display_status.\n\n**Response:** 200, a paginated list of entries."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/matched?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","matched"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10488,\n      \"document_number\": \"BILL-10488\",\n      \"type\": {\n        \"value\": \"purchase_order_invoice\",\n        \"label\": \"Purchase Order Invoice\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"color\": \"success\",\n        \"reason\": null\n      },\n      \"effective_at\": \"2026-05-01T00:00:00+00:00\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"3062.6000\",\n      \"document_total\": \"3062.6000\",\n      \"reference\": \"SIBER10488\",\n      \"remote\": {\n        \"remote_type\": \"xero_bill\",\n        \"remote_id\": \"85414bb6-6f88-4c0f-8c53-53e7c1f7128c\",\n        \"link_state\": \"linked_current\",\n        \"remote_status\": \"AUTHORISED\",\n        \"total\": \"3062.6000\",\n        \"document_date\": \"2026-05-01\",\n        \"remote_url\": \"https://go.xero.com/AccountsPayable/View.aspx?InvoiceID=85414bb6-6f88-4c0f-8c53-53e7c1f7128c\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Unlinked Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/unlinked?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","unlinked"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The SKU ledger entries in the window that are NOT yet linked to a provider document on a connection — both the sync-eligible ones and the ineligible (excluded) ones — as a paginated, filterable, sortable list. Each row carries its live per-connection sync `eligibility` (`eligible` plus the block `reasons`, e.g. `type_disabled`, `channel_disabled`) so the ineligible ones can be flagged.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required); standard pagination, `sort`, per-field `filter[...]`, general `search`, and `filter_groups`.\n\n**Response:** 200, a paginated list of entries."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/unlinked?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","unlinked"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10488,\n      \"document_number\": \"BILL-10488\",\n      \"type\": {\n        \"value\": \"purchase_order_invoice\",\n        \"label\": \"Purchase Order Invoice\"\n      },\n      \"status\": \"posted\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"color\": \"success\",\n        \"reason\": null\n      },\n      \"effective_at\": \"2026-05-01T00:00:00+00:00\",\n      \"currency_code\": \"USD\",\n      \"total_debit\": \"3062.6000\",\n      \"document_total\": \"3062.6000\",\n      \"reference\": \"FBA181D492B4: 55641\",\n      \"eligibility\": {\n        \"eligible\": false,\n        \"reasons\": [\n          \"type_disabled\"\n        ]\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Provider-only Documents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/provider-documents?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","provider-documents"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The provider documents (Xero/QBO) that have NOT been linked to a SKU ledger entry and have not been dismissed, over a connection's window — a normalized, paginated, filterable, sortable list across every document kind (invoices, bills, credit notes, journals).\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required); standard pagination; `sort` (prefix with - for DESC; allowed: reference, secondary_reference, counterparty, total, sub_total, tax_total, amount_due, document_date, due_date, line_count, provider_updated_at, status, remote_type, remote_id); per-field `filter[...]` (`remote_type`, `status`, `doc_class` = `invoice`|`journal`, `date_from`/`date_to`); general `search` (matches reference, secondary reference, counterparty, amount, and exact provider id); and `filter_groups`. Each row's `id` is the composite \"{remote_type}:{remote_id}\".\n\n**Response fields:** `doc_class` splits invoice-shaped documents (invoices/bills/credit notes) from journals. Invoice-shaped rows carry `counterparty`, `secondary_reference` (the provider's free-text reference), `sub_total`, `tax_total`, `amount_due`, and `due_date`; journal rows carry `line_count`. `provider_updated_at` is the provider-side last-modified timestamp. Fields not applicable to a document kind are null.\n\n**Response:** 200, a paginated list of provider documents."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/provider-documents?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","provider-documents"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"xero_bill:85414bb6-6f88-4c0f-8c53-53e7c1f7128c\",\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"85414bb6-6f88-4c0f-8c53-53e7c1f7128c\",\n      \"doc_class\": \"invoice\",\n      \"reference\": \"FBA181D492B4: 55641\",\n      \"secondary_reference\": \"PO-7788\",\n      \"counterparty\": \"Acme Corp\",\n      \"total\": \"3950.0000\",\n      \"sub_total\": \"3291.6700\",\n      \"tax_total\": \"658.3300\",\n      \"amount_due\": \"0.0000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2026-05-23\",\n      \"due_date\": \"2026-06-22\",\n      \"line_count\": null,\n      \"provider_updated_at\": \"2026-05-24T09:15:00+00:00\",\n      \"status\": \"PAID\",\n      \"remote_url\": \"https://go.xero.com/AccountsPayable/View.aspx?InvoiceID=85414bb6-6f88-4c0f-8c53-53e7c1f7128c\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Dismissed Documents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismissed?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismissed"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The provider documents previously dismissed from reconciliation on a connection, as a paginated, filterable, sortable list — the \"show dismissed\" view for reviewing and restoring documents that were hidden. Restore them with POST /api/ledger/reconciliation/restore or /restore/bulk.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required); standard pagination; `sort` (prefix with - for DESC; allowed: reference, secondary_reference, counterparty, total, sub_total, tax_total, amount_due, document_date, due_date, line_count, provider_updated_at, status, remote_type, remote_id); `filter[...]` (`remote_type`, `status`, `doc_class` = `invoice`|`journal`, `date_from`/`date_to`); `search`; and `filter_groups`. Each row's `id` is the composite \"{remote_type}:{remote_id}\".\n\n**Response:** 200, a paginated list of dismissed documents (same row shape as the provider-only list, including `doc_class`, `counterparty`, `secondary_reference`, `sub_total`, `tax_total`, `amount_due`, `due_date`, `line_count`, and `provider_updated_at`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismissed?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismissed"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"xero_bill:11c2a7d0-882e-4a19-9f6b-73c0d9a1e2ff\",\n      \"remote_type\": \"xero_bill\",\n      \"remote_id\": \"11c2a7d0-882e-4a19-9f6b-73c0d9a1e2ff\",\n      \"doc_class\": \"invoice\",\n      \"reference\": \"Regular Payroll Jun 1 – Jun 15\",\n      \"secondary_reference\": \"PO-7788\",\n      \"counterparty\": \"Acme Corp\",\n      \"total\": \"1371.2600\",\n      \"sub_total\": \"3291.6700\",\n      \"tax_total\": \"658.3300\",\n      \"amount_due\": \"0.0000\",\n      \"currency\": \"USD\",\n      \"document_date\": \"2026-06-15\",\n      \"due_date\": \"2026-06-22\",\n      \"line_count\": null,\n      \"provider_updated_at\": \"2026-05-24T09:15:00+00:00\",\n      \"status\": \"PAID\",\n      \"remote_url\": \"https://go.xero.com/AccountsPayable/View.aspx?InvoiceID=11c2a7d0-882e-4a19-9f6b-73c0d9a1e2ff\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Reconciliation Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/counts?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","counts"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The unfiltered counts for a connection: matched (linked), SKU-only (eligible unlinked), excluded (ineligible unlinked), and provider-only (unlinked provider documents).\n\n**Authentication:** Requires Bearer token.\n\n**Response:** 200 with the four counts."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/counts?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","counts"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched\": 546,\n    \"sku_only\": 0,\n    \"excluded\": 8257,\n    \"provider_only\": 258\n  }\n}"}]},{"name":"List Entry Link Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/link-candidates?connection_id=30&remote_type=xero_bill&remote_id=85414bb6-6f88-4c0f-8c53-53e7c1f7128c","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","link-candidates"],"query":[{"key":"connection_id","value":"30","description":"Accounting connection id. Required.","disabled":true},{"key":"remote_type","value":"xero_bill","description":"The kind of provider document (e.g. xero_bill, xero_invoice, qbo_invoice). Required.","disabled":true},{"key":"remote_id","value":"85414bb6-6f88-4c0f-8c53-53e7c1f7128c","description":"The provider document id to find SKU entries for. Required.","disabled":true}]},"description":"The SKU ledger entries a provider-only document could be linked to — the confidence-ranked picker for the reverse direction of the manual link (pick the SKU entry that matches a provider document, identified by `remote_type` + `remote_id`).\n\nRanks the connection's unlinked entries against the target document, spanning BOTH the eligible (`sku_only`) and the excluded (ineligible) entries — an entry that will never sync can still be the real counterpart of a provider document, and linking it is safe (it reconciles the document out of the provider-only set without pushing anything). Each candidate carries per-signal match flags — `amount_match`, `date_match`, `reference_match`, `confident` — plus its sync eligibility: `eligible` (boolean) and `eligibility_reasons[]` (reason codes such as `type_disabled`, `channel_disabled`) so ineligible candidates can be flagged.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required), `remote_type` (required, e.g. xero_bill), `remote_id` (required — the provider document id), `search` (optional). Returns 404 when connection_id is not a supported accounting connection, and 422 when a required parameter is missing.\n\n**Response:** 200 with `data` as an array of candidate entries ordered most-confident first. Link the chosen entry with POST /api/ledger/reconciliation/link."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/link-candidates?connection_id=30&remote_type=xero_bill&remote_id=85414bb6-6f88-4c0f-8c53-53e7c1f7128c","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","link-candidates"],"query":[{"key":"connection_id","value":"30","description":"Accounting connection id. Required.","disabled":true},{"key":"remote_type","value":"xero_bill","description":"The kind of provider document (e.g. xero_bill, xero_invoice, qbo_invoice). Required.","disabled":true},{"key":"remote_id","value":"85414bb6-6f88-4c0f-8c53-53e7c1f7128c","description":"The provider document id to find SKU entries for. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"entry_id\": 10927,\n      \"reference\": \"FBA181D492B4: 55641\",\n      \"document_number\": \"BILL-10927\",\n      \"type_label\": \"Purchase Order Invoice\",\n      \"date\": \"2024-05-22T07:00:00+00:00\",\n      \"total\": \"3950.0000\",\n      \"currency\": \"USD\",\n      \"amount_match\": true,\n      \"date_match\": true,\n      \"reference_match\": true,\n      \"confident\": true,\n      \"eligible\": false,\n      \"eligibility_reasons\": [\n        \"type_disabled\"\n      ]\n    },\n    {\n      \"entry_id\": 10930,\n      \"reference\": \"FBA181D492B4\",\n      \"document_number\": \"BILL-10930\",\n      \"type_label\": \"Purchase Order Invoice\",\n      \"date\": \"2024-06-01T07:00:00+00:00\",\n      \"total\": \"120.0000\",\n      \"currency\": \"USD\",\n      \"amount_match\": false,\n      \"date_match\": false,\n      \"reference_match\": true,\n      \"confident\": false,\n      \"eligible\": true,\n      \"eligibility_reasons\": []\n    }\n  ]\n}"}]},{"name":"Reconciliation Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/report?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","report"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The period-comparison report for a connection over the (optional) document-date window: monthly SKU-ledger totals vs the provider-mirror, with per-period and grand-total variance highlighting. Read entirely off the local provider document cache — no provider API calls.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Shape:** `data.rows[]` is one row per calendar month with activity, most-recent first. Each row carries `sku_entry_count` / `sku_total_debit` / `sku_total_credit` (the matched + SKU-only entries), `provider_document_count` / `provider_total` (the matched remotes + provider-only documents), and the deltas `count_variance` (sku − provider count) and `amount_variance` (sku debit − provider total, 4dp). `has_variance` is true when the counts differ or the amount delta exceeds the configured tolerance (`ledger.sync.dedup.amount_tolerance`, default 0.01).\n\n`data.summary` rolls the same fields up across every period (`period_count`, `periods_with_variance`). `data.currency` is the dominant currency or null when the window is empty. `from`/`to` (Y-m-d) override the default window. 404 when connection_id is not a supported accounting connection."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/report?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","report"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connection_id\": 5,\n    \"from\": \"2026-01-01\",\n    \"to\": \"2026-06-13\",\n    \"currency\": \"USD\",\n    \"rows\": [\n      {\n        \"period\": \"2026-06\",\n        \"period_label\": \"Jun 2026\",\n        \"sku_entry_count\": 12,\n        \"sku_total_debit\": \"4250.0000\",\n        \"sku_total_credit\": \"4250.0000\",\n        \"provider_document_count\": 12,\n        \"provider_total\": \"4250.0000\",\n        \"count_variance\": 0,\n        \"amount_variance\": \"0.0000\",\n        \"has_variance\": false\n      },\n      {\n        \"period\": \"2026-05\",\n        \"period_label\": \"May 2026\",\n        \"sku_entry_count\": 9,\n        \"sku_total_debit\": \"3100.0000\",\n        \"sku_total_credit\": \"3100.0000\",\n        \"provider_document_count\": 8,\n        \"provider_total\": \"2850.0000\",\n        \"count_variance\": 1,\n        \"amount_variance\": \"250.0000\",\n        \"has_variance\": true\n      }\n    ],\n    \"summary\": {\n      \"period_count\": 2,\n      \"periods_with_variance\": 1,\n      \"sku_entry_count\": 21,\n      \"sku_total_debit\": \"7350.0000\",\n      \"sku_total_credit\": \"7350.0000\",\n      \"provider_document_count\": 20,\n      \"provider_total\": \"7100.0000\",\n      \"count_variance\": 1,\n      \"amount_variance\": \"250.0000\",\n      \"has_variance\": true\n    }\n  }\n}"}]},{"name":"Preview Auto-Match","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/auto-match/preview","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","auto-match","preview"]},"description":"Compute the confident auto-match pairs for a connection WITHOUT linking anything — the preview behind the reconcile Auto-Match confirmation. Returns one row per proposed pairing of an unmatched SKU entry (SKU-only or excluded) to a provider-only document whose reference, amount (within tolerance) and date (within window) confidently match. Review the rows, then send the ones you want to keep to Run Auto-Match to link them.\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n`from`/`to` (Y-m-d) are optional and default to the connection's reconcile window.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"from\": \"2026-01-01\",\n  \"to\": \"2026-06-13\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/auto-match/preview","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","auto-match","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"entry_id\": 8213,\n      \"entry_reference\": \"INV-1042\",\n      \"entry_document_number\": \"INV-8213\",\n      \"entry_type_label\": \"Sales Order Invoice\",\n      \"entry_date\": \"2026-06-02T00:00:00+00:00\",\n      \"entry_total\": \"200.00\",\n      \"entry_currency\": \"USD\",\n      \"remote_type\": \"qbo_invoice\",\n      \"remote_id\": \"142\",\n      \"remote_reference\": \"INV-1042\",\n      \"remote_status\": \"Open\",\n      \"remote_date\": \"2026-06-03\",\n      \"remote_total\": \"200.00\",\n      \"remote_currency\": \"USD\",\n      \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=142\"\n    }\n  ]\n}"}]},{"name":"Run Auto-Match","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/auto-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","auto-match"]},"description":"Link the auto-match pairs confirmed from Preview Auto-Match. Send a `matches` array of `{entry_id, remote_type, remote_id}` rows; the eligible set is recomputed and only the intersection is linked, so a pairing that has since become ineligible is skipped rather than force-linked. Returns the number of links forged; each is recorded linked_stale so the next sync pushes an Update. An empty `matches` array links nothing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Body fields:**\n- `connection_id` (integer, required) — the accounting connection.\n- `matches` (array, required) — confirmed pairs; each `{entry_id, remote_type, remote_id}`. May be empty.\n- `matches[].entry_id` (integer, required) — the SKU ledger entry to link.\n- `matches[].remote_type` (string, required) — provider document type, e.g. `qbo_invoice`, `xero_invoice`.\n- `matches[].remote_id` (string, required) — the provider document id.\n- `from` / `to` (Y-m-d, optional) — window override; defaults to the connection's reconcile window.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"matches\": [\n    {\n      \"entry_id\": 8213,\n      \"remote_type\": \"qbo_invoice\",\n      \"remote_id\": \"142\"\n    },\n    {\n      \"entry_id\": 8214,\n      \"remote_type\": \"qbo_invoice\",\n      \"remote_id\": \"143\"\n    }\n  ],\n  \"from\": \"2026-01-01\",\n  \"to\": \"2026-06-13\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/auto-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","auto-match"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"linked\": 2\n  },\n  \"message\": \"2 documents auto-matched.\"\n}"}]},{"name":"Backfill Provider Cache","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/backfill","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","backfill"]},"description":"Populate the local provider document cache (the xero_/qbo_ mirror) for a connection by dispatching a tracked background job that downloads every remote document over the reconcile window. The reconcile screen, matching, and the period-comparison report all read off this local cache, so this is the on-demand, UI-triggered equivalent of the `ledger:cache:backfill` artisan command. Returns the tracked job log id so the frontend can follow progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n`from`/`to` (Y-m-d) are optional and default to the connection's reconcile window (the connection's sync start date through today).","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/backfill","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","backfill"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8412\n  },\n  \"message\": \"Caching provider documents from Xero — track progress in the job tray.\"\n}"}]},{"name":"Link Remote Document","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/link","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","link"]},"description":"Manually link a SKU entry to an existing provider document — the operator's \"this is the same document\" action. Recorded linked_stale so the next sync pushes an Update bringing the remote into line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nLinking a document also clears any reconcile-screen dismissal recorded against it.\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n422 when the entry already has a link on this connection.\n\n**Ownership validation:** the (remote_type, remote_id) pair must be a cached provider document belonging to the given connection. A document from another connection (or one not yet pulled into the local cache) is rejected with HTTP 422 — pull provider documents for the connection first, then link.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"entry_id\": 4822,\n  \"remote_type\": \"qbo_invoice\",\n  \"remote_id\": \"146\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/link","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","link"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 78,\n    \"provider\": \"qbo\",\n    \"remote_type\": \"qbo_invoice\",\n    \"remote_id\": \"146\",\n    \"remote_url\": \"https://app.qbo.intuit.com/app/invoice?txnId=145\",\n    \"link_state\": \"linked_stale\",\n    \"remote_status\": \"Active\",\n    \"last_remote_seen_at\": \"2026-06-12T02:00:00+00:00\"\n  },\n  \"message\": \"Linked to the provider document.\"\n}"}]},{"name":"Dismiss Provider Document","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismiss","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismiss"]},"description":"Dismiss a provider-only document — mark a remote document as \"not a SKU document\" so it stops surfacing in the provider-only bucket. Idempotent on the remote identity.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"remote_type\": \"qbo_invoice\",\n  \"remote_id\": \"146\",\n  \"reason\": \"Pre-existing supplier bill, not SKU-managed\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismiss","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Document dismissed from reconciliation.\"\n}"}]},{"name":"Bulk Dismiss Provider Documents","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismiss/bulk","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismiss","bulk"]},"description":"Dismiss many provider-only documents from reconciliation in one action (idempotent). Provide either `ids` (an array of composite \"{remote_type}:{remote_id}\" identifiers — the selected rows) or `apply_to_all: true` with `filters` to dismiss every provider-only document matching those filters. An optional `reason` is stored on each.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `connection_id` (required, integer); `ids` (array of strings, required unless `apply_to_all`); `apply_to_all` (boolean); `filters` (object, optional) — the list filters to scope `apply_to_all`, e.g. `{\"search\": \"Contractor Payment\"}`. Accepts flat filter values (`search`, `remote_type`, `status`, `date_from`, `date_to`) plus an optional `filter_groups` tree (same structure as the list endpoint's `filter_groups` parameter). When omitted, `apply_to_all` targets every document in the reconcile window.; `reason` (string, optional).\n\n**Response:** 200 with the number dismissed.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"apply_to_all\": true,\n  \"filters\": {\n    \"search\": \"Contractor Payment\"\n  },\n  \"reason\": \"not a SKU document\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/dismiss/bulk","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","dismiss","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dismissed\": 1\n  },\n  \"message\": \"1 document dismissed from reconciliation.\"\n}"}]},{"name":"Bulk Restore Provider Documents","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/restore/bulk","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","restore","bulk"]},"description":"Restore (un-dismiss) many provider documents in one action, returning them to reconciliation. Provide either `ids` (composite \"{remote_type}:{remote_id}\" identifiers — the selected rows) or `apply_to_all: true` with `filters` to restore every dismissed document matching those filters.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `connection_id` (required, integer); `ids` (array of strings, required unless `apply_to_all`); `apply_to_all` (boolean); `filters` (object, optional) — the list filters to scope `apply_to_all`, e.g. `{\"search\": \"Contractor Payment\"}`. Accepts flat filter values (`search`, `remote_type`, `status`, `date_from`, `date_to`) plus an optional `filter_groups` tree (same structure as the list endpoint's `filter_groups` parameter). When omitted, `apply_to_all` targets every document in the reconcile window..\n\n**Response:** 200 with the number restored.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"apply_to_all\": true,\n  \"filters\": {\n    \"search\": \"Contractor Payment\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/restore/bulk","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","restore","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"restored\": 1\n  },\n  \"message\": \"1 document restored to reconciliation.\"\n}"}]},{"name":"Restore Provider Document","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/restore","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","restore"]},"description":"Undo a dismissal — restore a previously dismissed provider document to the reconcile screen.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"remote_type\": \"qbo_invoice\",\n  \"remote_id\": \"146\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/restore","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","restore"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Document restored to reconciliation.\"\n}"}]},{"name":"List Provider Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/payments?connection_id=2","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","payments"],"query":[{"key":"connection_id","value":"2","description":"Accounting connection (IntegrationInstance) id.","disabled":true}]},"description":"Provider payments (Xero/QBO) from the local mirror for a connection, each flagged with whether it has already been imported as a SKU payment. Backs the Reconciliation > Payments view.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthenticate with a PAT."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/payments?connection_id=2","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","payments"],"query":[{"key":"connection_id","value":"2","description":"Accounting connection (IntegrationInstance) id.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"remote_type\": \"xero_payment\",\n      \"remote_id\": \"19979c8d-b674-4784-a5ed-595a1c5356d4\",\n      \"reference\": \"19979c8d-b674-4784-a5ed-595a1c5356d4\",\n      \"amount\": \"500.0000\",\n      \"date\": \"2026-06-18T00:00:00+00:00\",\n      \"imported\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 15,\n  \"total\": 74,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Import Provider Payments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/payments/import","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","payments","import"]},"description":"Import provider payments into SKU — create the matching SKU payment on each payment's source document, via the same idempotent pathway as the automatic inbound pull. With remote_ids, only those; omit remote_ids to import every not-yet-imported provider payment. Requires accounting.sync permission.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse data: {attempted, imported}.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 2,\n  \"remote_ids\": [\n    \"19979c8d-b674-4784-a5ed-595a1c5356d4\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/payments/import","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","payments","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"attempted\": 1,\n    \"imported\": 1\n  },\n  \"message\": \"1 payment imported into SKU.\"\n}"}]},{"name":"Get Inventory Divergence","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]},"description":"Inventory sub-ledger reconciliation (Lane 2). SKU is the authoritative subsidiary ledger for inventory, so this returns one row per inventory control account comparing SKU's per-account inventory value against the provider's live GL balance (pulled from the Xero Trial Balance) — most divergent first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token. The provider connection must have the `accounting.reports.read` scope.\n\n**Row fields:** `gl_code`, `gl_account_name`, `gl_account_id`, `sku_value` (null when SKU cannot value the account, e.g. Amazon FBA accounts valued via a separate subsystem), `sku_quantity`, `provider_balance`, `divergence` (provider_balance − sku_value; null when sku_value is null), `status` (`divergent` | `matched` | `sku_unavailable`).\n\nThe warehouse→GL mapping is SKU's own `warehouses.nominal_code_id`. A non-zero divergence is the basis for a suggested adjusting journal on the provider side."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"gl_code\": \"142\",\n      \"gl_account_name\": \"SMO Inventory (142)\",\n      \"gl_account_id\": \"5e55e704-1a2b-4c3d-9e8f-0a1b2c3d4e5f\",\n      \"sku_value\": 569947.14,\n      \"sku_quantity\": 26463,\n      \"provider_balance\": 1042053.4,\n      \"divergence\": 472106.26,\n      \"status\": \"divergent\"\n    },\n    {\n      \"gl_code\": \"141\",\n      \"gl_account_name\": \"Amazon FBA US Inventory (141)\",\n      \"gl_account_id\": \"d35c45a4-aa11-4b22-8c33-9d44e55f6071\",\n      \"sku_value\": null,\n      \"sku_quantity\": null,\n      \"provider_balance\": 269416,\n      \"divergence\": null,\n      \"status\": \"sku_unavailable\"\n    },\n    {\n      \"gl_code\": \"145\",\n      \"gl_account_name\": \"Amazon FBA CA Inventory (145)\",\n      \"gl_account_id\": \"b312ed80-1122-4334-8556-77889900aabb\",\n      \"sku_value\": null,\n      \"sku_quantity\": null,\n      \"provider_balance\": 8859,\n      \"divergence\": null,\n      \"status\": \"sku_unavailable\"\n    }\n  ],\n  \"success\": true\n}"}]},{"name":"Inventory Recon Accounts (Earmark Suggestions)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/accounts","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","accounts"]},"description":"Candidate inventory control accounts for the daily reconciliation earmark step. Pulls SKU's current-asset nominal codes (plus any warehouse-mapped account), cross-references the provider's cached current-asset chart (Xero `xero_accounts`, matched by code — **no live provider call**), computes each account's point-in-time SKU inventory value as-of now, and flags which look like inventory accounts. Suggested-then-code ordered.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Row fields:** `nominal_code_id`, `code`, `sku_name`, `sku_type`, `provider_account_name`, `provider_account_type`, `provider_account_id` (nullable when no provider match), `warehouse_count`, `warehouse_names[]`, `is_earmarked` (the user's persisted decision), `is_suggested` (heuristic), `suggestion_reasons[]` (strongest first: warehouse-mapped, SKU type Inventory, provider type Inventory, name looks like inventory), `current_sku_value` (null when no warehouse — and therefore no SKU inventory — maps to it)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/accounts","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","accounts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"nominal_code_id\": 87,\n      \"code\": \"142\",\n      \"sku_name\": \"SMO Inventory\",\n      \"sku_type\": \"Inventory\",\n      \"provider_account_name\": \"SMO Inventory\",\n      \"provider_account_type\": \"INVENTORY\",\n      \"provider_account_id\": \"5e55e704-1a2b-4c3d-9e8f-0a1b2c3d4e5f\",\n      \"warehouse_count\": 1,\n      \"warehouse_names\": [\n        \"ShipMyOrders\"\n      ],\n      \"is_earmarked\": true,\n      \"is_suggested\": true,\n      \"suggestion_reasons\": [\n        \"Mapped to warehouse ShipMyOrders\",\n        \"SKU account type is Inventory\",\n        \"Name looks like inventory\"\n      ],\n      \"current_sku_value\": 569792.24\n    },\n    {\n      \"nominal_code_id\": 88,\n      \"code\": \"141\",\n      \"sku_name\": \"Amazon FBA US Inventory\",\n      \"sku_type\": \"Inventory\",\n      \"provider_account_name\": \"Amazon FBA US Inventory\",\n      \"provider_account_type\": \"INVENTORY\",\n      \"provider_account_id\": \"d35c45a4-aa11-4b22-8c33-9d44e55f6071\",\n      \"warehouse_count\": 0,\n      \"warehouse_names\": [],\n      \"is_earmarked\": false,\n      \"is_suggested\": true,\n      \"suggestion_reasons\": [\n        \"SKU account type is Inventory\",\n        \"Name looks like inventory\"\n      ],\n      \"current_sku_value\": null\n    }\n  ],\n  \"success\": true\n}"}]},{"name":"Save Earmarked Inventory Accounts","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/accounts","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","accounts"]},"description":"Replace the earmarked inventory control account set and return the refreshed candidate list. The submitted set replaces existing earmarks wholesale — an empty array clears them. The earmarked accounts are what the daily series and rebuild job operate on.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Request body:**\n- `nominal_code_ids` (array, **required/present** — may be empty): nominal code ids to earmark. Each must exist in `nominal_codes`.\n\nReturns the same payload shape as `GET .../inventory/accounts` with `is_earmarked` reflecting the new set.","body":{"mode":"raw","raw":"{\n  \"nominal_code_ids\": [\n    87,\n    88\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/accounts","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","accounts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"nominal_code_id\": 87,\n      \"code\": \"142\",\n      \"sku_name\": \"SMO Inventory\",\n      \"sku_type\": \"Inventory\",\n      \"provider_account_name\": \"SMO Inventory\",\n      \"provider_account_type\": \"INVENTORY\",\n      \"provider_account_id\": \"5e55e704-1a2b-4c3d-9e8f-0a1b2c3d4e5f\",\n      \"warehouse_count\": 1,\n      \"warehouse_names\": [\n        \"ShipMyOrders\"\n      ],\n      \"is_earmarked\": true,\n      \"is_suggested\": true,\n      \"suggestion_reasons\": [\n        \"Mapped to warehouse ShipMyOrders\",\n        \"SKU account type is Inventory\",\n        \"Name looks like inventory\"\n      ],\n      \"current_sku_value\": 569792.24\n    },\n    {\n      \"nominal_code_id\": 88,\n      \"code\": \"141\",\n      \"sku_name\": \"Amazon FBA US Inventory\",\n      \"sku_type\": \"Inventory\",\n      \"provider_account_name\": \"Amazon FBA US Inventory\",\n      \"provider_account_type\": \"INVENTORY\",\n      \"provider_account_id\": \"d35c45a4-aa11-4b22-8c33-9d44e55f6071\",\n      \"warehouse_count\": 0,\n      \"warehouse_names\": [],\n      \"is_earmarked\": false,\n      \"is_suggested\": true,\n      \"suggestion_reasons\": [\n        \"SKU account type is Inventory\",\n        \"Name looks like inventory\"\n      ],\n      \"current_sku_value\": null\n    }\n  ],\n  \"success\": true\n}"}]},{"name":"Inventory Daily Divergence Series","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/daily?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","daily"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]},"description":"The materialized daily reconciliation series, one entry per earmarked account (or per `nominal_code_ids[]` when given): SKU's point-in-time inventory value vs the provider GL balance for each end-of-day, and the stored divergence — the \"which days diverge\" view. Reads materialized rows only (**no live provider or valuation call**); the SKU side is built by the rebuild job and the provider side by capture-provider.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach day's SKU value uses the same valuation cutoff as the inventory valuation report, so a day ties to running that report for that end-of-day.\n\n**Authentication:** Requires Bearer token.\n\n**Series fields:** `nominal_code_id`, `code`, `name`, `provider_account_name`, `days_total`, `days_divergent`, `days_matched`, `days_provider_missing`, `latest_sku_value`, `latest_provider_balance`, `latest_divergence`, `latest_as_of_date`, `points[]`.\n\n**Point fields:** `as_of_date`, `sku_value`, `sku_quantity`, `provider_balance` (null on days not yet captured), `divergence` (null when either side missing), `status` (`divergent` | `matched` | `provider_missing` | `sku_missing`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/daily?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","daily"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection (IntegrationInstance) id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"nominal_code_id\": 87,\n      \"code\": \"142\",\n      \"name\": \"SMO Inventory\",\n      \"provider_account_name\": \"SMO Inventory\",\n      \"days_total\": 796,\n      \"days_divergent\": 540,\n      \"days_matched\": 250,\n      \"days_provider_missing\": 6,\n      \"latest_sku_value\": 569792.24,\n      \"latest_provider_balance\": 1042053.4,\n      \"latest_divergence\": 472261.16,\n      \"latest_as_of_date\": \"2026-06-27\",\n      \"points\": [\n        {\n          \"as_of_date\": \"2024-04-23\",\n          \"sku_value\": 0,\n          \"sku_quantity\": 0,\n          \"provider_balance\": null,\n          \"divergence\": null,\n          \"status\": \"provider_missing\"\n        },\n        {\n          \"as_of_date\": \"2026-06-26\",\n          \"sku_value\": 568120.05,\n          \"sku_quantity\": 26390,\n          \"provider_balance\": null,\n          \"divergence\": null,\n          \"status\": \"provider_missing\"\n        },\n        {\n          \"as_of_date\": \"2026-06-27\",\n          \"sku_value\": 569792.24,\n          \"sku_quantity\": 26463,\n          \"provider_balance\": 1042053.4,\n          \"divergence\": 472261.16,\n          \"status\": \"divergent\"\n        }\n      ]\n    }\n  ],\n  \"success\": true\n}"}]},{"name":"Get Inventory Reconciliation Day Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/day-detail?connection_id=5&nominal_code_id=87&date=2026-06-27","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","day-detail"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"nominal_code_id","value":"87","description":"The earmarked inventory control account (nominal code) id to explain. Required.","disabled":true},{"key":"date","value":"2026-06-27","description":"The local day to explain (date). Required.","disabled":true}]},"description":"For one earmarked inventory control account on one day, returns the reconciled figures for that day (SKU inventory value, provider GL balance, and their divergence) plus the underlying detail that produced them: the provider journal lines posted to the account that day and the inventory movements that changed SKU's value that day. Use it to trace a divergence to its source documents — reads materialized/cached data only, no live provider call.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `as_of_date`, `nominal_code_id`, `code`, `name`, `provider_account_name`, `sku_value`, `sku_quantity`, `provider_balance`, `divergence`, `provider_net_total` (sum of the day's provider journal-line net amounts), `sku_value_delta_total` (sum of the day's movement value deltas), `provider_lines[]` (`journal_number`, `journal_date`, `source_type`, `source_id`, `account_code`, `account_name`, `net_amount`, `gross_amount`, `tax_amount`), `sku_movements[]` (`id`, `movement_date`, `type`, `warehouse_name`, `product_sku`, `product_name`, `quantity`, `unit_cost`, `value_delta`, `reference`, `link_type`, `link_id`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/day-detail?connection_id=5&nominal_code_id=87&date=2026-06-27","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","day-detail"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"nominal_code_id","value":"87","description":"The earmarked inventory control account (nominal code) id to explain. Required.","disabled":true},{"key":"date","value":"2026-06-27","description":"The local day to explain (date). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-06-27\",\n    \"nominal_code_id\": 87,\n    \"code\": \"142\",\n    \"name\": \"SMO Inventory\",\n    \"provider_account_name\": \"SMO Inventory\",\n    \"sku_value\": 569792.24,\n    \"sku_quantity\": 41250,\n    \"provider_balance\": 571675.22,\n    \"divergence\": 1882.98,\n    \"provider_net_total\": 1882.98,\n    \"sku_value_delta_total\": -63.28,\n    \"provider_lines\": [\n      {\n        \"journal_number\": \"212538\",\n        \"journal_date\": \"2026-06-27\",\n        \"source_type\": \"ACCPAY\",\n        \"source_id\": \"b1f2c0d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d\",\n        \"account_code\": \"142\",\n        \"account_name\": \"SMO Inventory\",\n        \"net_amount\": 1882.98,\n        \"gross_amount\": 1882.98,\n        \"tax_amount\": 0\n      }\n    ],\n    \"sku_movements\": [\n      {\n        \"id\": 3071,\n        \"movement_date\": \"2026-06-27T09:14:00.000000Z\",\n        \"type\": \"adjustment\",\n        \"warehouse_name\": \"ShipMyOrders Warehouse\",\n        \"product_sku\": \"TM-191-O-124\",\n        \"product_name\": \"Titanium Mount 191\",\n        \"quantity\": -1,\n        \"unit_cost\": 63.28,\n        \"value_delta\": -63.28,\n        \"reference\": \"3071\",\n        \"link_type\": \"InventoryAdjustment\",\n        \"link_id\": 3071\n      }\n    ]\n  }\n}"}]},{"name":"Get Inventory Reconciliation Awaiting-Sync Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/unsynced?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","unsynced"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"Per earmarked inventory account, the SKU ledger activity not reflected in the provider balance, split by sync disposition: `pending_ledger`/`pending_count` WILL reach the provider once it syncs (self-resolving), while `excluded_ledger`/`excluded_count` will NEVER sync (dated before the books' sync start date, or internal-only) — a permanent mismatch a measure-from baseline sets aside. Batch-aggregate aware (a batched document counts once, via its batch). Requires connection_id."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/unsynced?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","unsynced"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-07-20\",\n    \"accounts\": [\n      {\n        \"nominal_code_id\": 87,\n        \"code\": \"141\",\n        \"name\": \"Amazon FBA US Inventory\",\n        \"pending_ledger\": 0,\n        \"excluded_ledger\": -299950.38,\n        \"pending_count\": 0,\n        \"excluded_count\": 41\n      },\n      {\n        \"nominal_code_id\": 88,\n        \"code\": \"142\",\n        \"name\": \"SMO Inventory\",\n        \"pending_ledger\": -1010.56,\n        \"excluded_ledger\": 1498366.15,\n        \"pending_count\": 2,\n        \"excluded_count\": 239\n      }\n    ]\n  }\n}"}]},{"name":"Get Inventory Reconciliation Opening Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/opening-breakdown?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","opening-breakdown"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The warehouse-first opening breakdown for reconciling inventory to the accounting provider. For each earmarked inventory control account, returns the provider general-ledger balance and its divergence from the SKU inventory value at the opening date, broken down into the individual warehouses that hold that account's stock. The provider balance and divergence are reported at the account level (a provider account has no warehouse dimension); the SKU side sums standard and Amazon FBA inventory per warehouse. Warehouses that currently hold no stock are still listed so an account's full warehouse footprint is visible. The opening date is the reconciliation baseline when one has been set, otherwise the configured inventory start date. Reads materialized/cached data only — no live provider call.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `as_of_date` (the effective opening date, null when no accounts are earmarked or no opening date is configured), `from_baseline` (whether `as_of_date` came from a set baseline rather than the inventory start date), `accounts[]` — each with `nominal_code_id`, `code`, `name`, `provider_account_name`, `sku_value` (sum of its warehouses), `sku_quantity`, `provider_balance`, `divergence` (provider_balance minus sku_value, null when no provider balance is available), `point_as_of_date` (the day the provider balance was measured), and `warehouses[]` (`warehouse_id`, `warehouse_name`, `is_fba`, `sku_value`, `sku_quantity`). Each account also carries `unsynced_ledger` — SKU ledger postings dated on/before the opening that haven't synced to the provider yet; adding it to `divergence` shows how much of the opening gap is just unsynced pre-baseline activity (self-resolving) versus a true gap. Each account also carries `pending_ledger` (unsynced activity dated on/before the opening that WILL sync) and `excluded_ledger` (activity that will never sync — the pre-baseline mismatch the baseline sets aside)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/opening-breakdown?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","opening-breakdown"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2024-04-22\",\n    \"from_baseline\": true,\n    \"accounts\": [\n      {\n        \"nominal_code_id\": 88,\n        \"code\": \"141\",\n        \"name\": \"Amazon FBA US Inventory\",\n        \"provider_account_name\": \"Amazon FBA US Inventory\",\n        \"sku_value\": 4024.84,\n        \"sku_quantity\": 65,\n        \"provider_balance\": 0,\n        \"divergence\": -4024.84,\n        \"pending_ledger\": 0,\n        \"excluded_ledger\": 0,\n        \"point_as_of_date\": \"2024-04-22\",\n        \"warehouses\": [\n          {\n            \"warehouse_id\": 29,\n            \"warehouse_name\": \"FBA US (AMZ)\",\n            \"is_fba\": true,\n            \"sku_value\": 4024.84,\n            \"sku_quantity\": 65\n          }\n        ]\n      },\n      {\n        \"nominal_code_id\": 87,\n        \"code\": \"142\",\n        \"name\": \"SMO Inventory\",\n        \"provider_account_name\": \"SMO Inventory\",\n        \"sku_value\": 569792.24,\n        \"sku_quantity\": 41250,\n        \"provider_balance\": 0,\n        \"divergence\": -569792.24,\n        \"pending_ledger\": 0,\n        \"excluded_ledger\": -125000,\n        \"point_as_of_date\": \"2024-04-22\",\n        \"warehouses\": [\n          {\n            \"warehouse_id\": 4,\n            \"warehouse_name\": \"ShipMyOrders Warehouse\",\n            \"is_fba\": false,\n            \"sku_value\": 569792.24,\n            \"sku_quantity\": 41250\n          },\n          {\n            \"warehouse_id\": 12,\n            \"warehouse_name\": \"Overflow Warehouse\",\n            \"is_fba\": false,\n            \"sku_value\": 0,\n            \"sku_quantity\": 0\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Get Inventory Reconciliation Baseline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"The reconcile-opening context for an inventory reconciliation connection: the current recon baseline (a \"line in the sand\" date the divergence view is measured from — null when none is set), the inventory start date the series otherwise opens from, and the accounting provider's lock date.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `baseline_date` (null when no baseline is set), `baseline_note`, `inventory_start_date` (where the series opens from without a baseline), `provider_lock_date` (null when the provider reports no lock), `opening_locked` (true when the correction date falls on/before the provider lock — corrections then must be made on the SKU side, not posted to the provider)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"baseline_date\": \"2025-01-01\",\n    \"baseline_note\": \"Pre-2025 books unreliable — fresh start\",\n    \"inventory_start_date\": \"2024-04-22\",\n    \"provider_lock_date\": \"2013-12-31\",\n    \"opening_locked\": false\n  }\n}"}]},{"name":"Set Inventory Reconciliation Baseline","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"]},"description":"Draw the reconciliation baseline: measure divergence from `baseline_date` forward and freeze the history before it out of the view. View-only and reversible — no reconciled figure, opening balance, or start date is changed. Returns the refreshed context.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `connection_id` (required), `baseline_date` (required, date), `note` (optional, max 500 chars).\n\n**Response fields:** `baseline_date` (null when no baseline is set), `baseline_note`, `inventory_start_date` (where the series opens from without a baseline), `provider_lock_date` (null when the provider reports no lock), `opening_locked` (true when the correction date falls on/before the provider lock — corrections then must be made on the SKU side, not posted to the provider).","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"baseline_date\": \"2025-01-01\",\n  \"note\": \"Pre-2025 books unreliable — fresh start\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"baseline_date\": \"2025-01-01\",\n    \"baseline_note\": \"Pre-2025 books unreliable — fresh start\",\n    \"inventory_start_date\": \"2024-04-22\",\n    \"provider_lock_date\": \"2013-12-31\",\n    \"opening_locked\": false\n  }\n}"}]},{"name":"Clear Inventory Reconciliation Baseline","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]},"description":"Remove the reconciliation baseline; the full history returns to the divergence view. Returns the refreshed context.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `baseline_date` (null when no baseline is set), `baseline_note`, `inventory_start_date` (where the series opens from without a baseline), `provider_lock_date` (null when the provider reports no lock), `opening_locked` (true when the correction date falls on/before the provider lock — corrections then must be made on the SKU side, not posted to the provider)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/baseline?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","baseline"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"baseline_date\": null,\n    \"baseline_note\": null,\n    \"inventory_start_date\": \"2024-04-22\",\n    \"provider_lock_date\": \"2013-12-31\",\n    \"opening_locked\": false\n  }\n}"}]},{"name":"Get Inventory Reconciliation Adjustment Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/preview?connection_id=5&nominal_code_id=87&effective_date=2024-04-22","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","preview"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"nominal_code_id","value":"87","description":"The earmarked inventory control account. Required.","disabled":true},{"key":"effective_date","value":"2024-04-22","description":"The date to align at. Required.","disabled":true}]},"description":"The proposed adjusting journal that would move the provider's inventory control account to match SKU as of a date — computed read-only so you see exactly what would post. `divergence = provider − SKU`; a positive gap credits the inventory control account (reducing it) and debits the counter, both for the same amount. When the date is inside a locked provider period `postable` is false: post the journal dated on or after `earliest_postable_date` instead. Accounts backed by Amazon warehouses (FBA/AWD) are Amazon-sourced — their stock comes from Amazon and cannot be adjusted in SKU (`sku_side_adjustable` is false), so they can only be reconciled provider-side; other accounts may instead correct SKU's opening for the warehouses in `warehouses`.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `divergence`, `amount`, `needs_adjustment`, `direction_summary`, `counter_nominal_code_id`/`counter_code`/`counter_name`, `postable`, `blocked_reason`, `provider_lock_date`, `sku_side_adjustable` (whether the account has editable non-Amazon warehouses), `earliest_postable_date` (first date the provider accepts a post — lock date + 1 day, null when unlocked), `lines[]` (`nominal_code_id`, `code`, `name`, `direction`, `amount`), `warehouses[]` (`id`, `name` — the SKU-adjustable, non-Amazon warehouses the SKU-side fix can target). `already_adjusted` is true when this account was already reconciled on this date (posting is blocked to avoid double-correcting), with `existing_adjustment_id` pointing at the prior adjustment."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/preview?connection_id=5&nominal_code_id=87&effective_date=2024-04-22","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","preview"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"nominal_code_id","value":"87","description":"The earmarked inventory control account. Required.","disabled":true},{"key":"effective_date","value":"2024-04-22","description":"The date to align at. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"nominal_code_id\": 87,\n    \"code\": \"141\",\n    \"name\": \"Amazon FBA US Inventory\",\n    \"provider_account_name\": \"Amazon FBA US Inventory\",\n    \"effective_date\": \"2024-04-22\",\n    \"divergence\": 104005.26,\n    \"amount\": 104005.26,\n    \"needs_adjustment\": true,\n    \"direction_summary\": \"Credit Amazon FBA US Inventory and debit Opening Balance Equity — reduces the provider GL to match SKU.\",\n    \"counter_nominal_code_id\": 94,\n    \"counter_code\": \"970\",\n    \"counter_name\": \"Opening Balance Equity\",\n    \"postable\": true,\n    \"blocked_reason\": null,\n    \"provider_lock_date\": \"2013-12-31\",\n    \"sku_side_adjustable\": false,\n    \"earliest_postable_date\": \"2014-01-01\",\n    \"already_adjusted\": false,\n    \"existing_adjustment_id\": null,\n    \"lines\": [\n      {\n        \"nominal_code_id\": 87,\n        \"code\": \"141\",\n        \"name\": \"Amazon FBA US Inventory\",\n        \"direction\": \"credit\",\n        \"amount\": 104005.26\n      },\n      {\n        \"nominal_code_id\": 94,\n        \"code\": \"970\",\n        \"name\": \"Opening Balance Equity\",\n        \"direction\": \"debit\",\n        \"amount\": 104005.26\n      }\n    ],\n    \"warehouses\": []\n  }\n}"}]},{"name":"Get Inventory Reconciliation Adjustment Journal","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/journal?connection_id=5&adjustment_id=1","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","journal"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"adjustment_id","value":"1","description":"The posted adjustment id (returned by the post endpoint). Required.","disabled":true}]},"description":"Where a posted inventory reconciliation adjustment landed in SKU's ledger — so a client can deep-link the user to the journal entry the adjustment created. The adjustment posts asynchronously, so immediately after posting this returns `pending: true` with null ids; poll it with the returned `adjustment_id` until `pending` is false, then use `journal_entry_id` to open the journal.\n\n**Authentication:** Requires Bearer token.\n\n**Response fields:** `pending` (true until the journal exists), `journal_entry_id` (the created journal entry's id, null while pending), `reference` (the journal's reference, e.g. `INV-RECON-ADJ-1`), `status` (the journal's lifecycle state, e.g. `draft` or `posted`), `deletable` (true while the journal has not yet synced to the provider — so the adjustment can be reversed and discarded cleanly)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/journal?connection_id=5&adjustment_id=1","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","journal"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"adjustment_id","value":"1","description":"The posted adjustment id (returned by the post endpoint). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending\": false,\n    \"journal_entry_id\": 49687,\n    \"reference\": \"INV-RECON-ADJ-1\",\n    \"status\": \"draft\",\n    \"deletable\": true\n  }\n}"}]},{"name":"Ensure Adjustment Counter Account","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/counter-account","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","counter-account"]},"description":"Ensure a conventional \"Opening Balance Equity\" counter account exists (creating it if the chart of accounts has none), so the adjusting journal's balancing leg has a target. Idempotent — reuses an existing opening-balance-named account.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `connection_id` (required).\n\n**Response:** `{ data: { id, code, name } }`.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment/counter-account","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment","counter-account"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 94,\n    \"code\": \"970\",\n    \"name\": \"Opening Balance Equity\"\n  }\n}"}]},{"name":"Post Inventory Reconciliation Adjustment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment"]},"description":"Post the adjusting journal to bring the provider's inventory control account into line with SKU. The amount and direction are recomputed server-side from the divergence (the client can't post an arbitrary figure); the balanced journal is posted to the provider as a manual journal. An already-aligned or locked-period account is rejected 422.\n\n**Authentication:** Requires Bearer token.\n\n**Body:** `connection_id` (required), `nominal_code_id` (required), `counter_nominal_code_id` (required), `effective_date` (required, date), `note` (optional, max 500 chars).\n\n**Response:** `{ data: { adjustment_id }, message }`.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"nominal_code_id\": 87,\n  \"counter_nominal_code_id\": 94,\n  \"effective_date\": \"2024-04-22\",\n  \"note\": \"Align opening to SKU\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"adjustment_id\": 12\n  },\n  \"message\": \"Adjusting journal posted — it will sync to the provider.\"\n}"}]},{"name":"Reverse Inventory Reconciliation Adjustment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment?connection_id=5&adjustment_id=1","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"adjustment_id","value":"1","description":"The posted adjustment id to reverse. Required.","disabled":true}]},"description":"Reverse (delete) a posted inventory reconciliation adjustment while its journal has not yet synced to the accounting provider, discarding the draft journal so the opening can be re-reconciled (for example, at a corrected date). Once the journal has synced to the provider this returns 422 — undoing it then requires posting a reversing entry in the provider.\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:** `connection_id` (required), `adjustment_id` (required — the adjustment returned by the post endpoint).\n\n**Behavior:** discards the adjustment's unsynced draft journal via the standard source-deleted pathway; the SKU inventory value is unchanged."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/adjustment?connection_id=5&adjustment_id=1","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","adjustment"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id. Required.","disabled":true},{"key":"adjustment_id","value":"1","description":"The posted adjustment id to reverse. Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Adjustment reversed — its journal was discarded.\"\n}"}]},{"name":"Provider GL Sync Estimate","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/sync-estimate?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","sync-estimate"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id (the provider's integration instance). Required.","disabled":true}]},"description":"A **pre-flight, zero-API** estimate for the unified provider GL sync (Lane 2): how many Xero calls the operation would cost for the chosen window against how many remain in today's API budget, so the user can weigh it before spending any of it. Computed locally from the cached journal cadence (distinct journals over their date span) plus the one Trial Balance anchor call — it makes **no** calls to the provider.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:**\n- `connection_id` (integer, **required**): accounting connection id whose journals/budget are estimated.\n- `from` (date, optional): window start (Y-m-d). Clamped up to the Inventory Start Date — an earlier value never lowers the window below the opening-balance anchor. Defaults to the Inventory Start Date.\n- `to` (date, optional, `after_or_equal:from`): window end (Y-m-d). Defaults to today.\n\n**Response (`data`):**\n- `can_sync` (boolean): false when the Inventory Start Date is unset (no lower bound to anchor against); `reason` explains why.\n- `reason` (string|null): why the sync can't run, when `can_sync` is false.\n- `cadence_known` (boolean): false on a first-ever sync (nothing cached to extrapolate from) — then `estimated_calls` is null.\n- `estimated_calls` (integer|null): total projected Xero calls (pages + probes + anchor). Null when cadence is unknown.\n- `estimated_pages` (integer|null): projected forward Journals pages (incl. the terminating empty page).\n- `estimated_probe_calls` (integer): binary-search probe calls to locate a start offset below the cache (0 when resuming above the cache or from empty).\n- `anchor_calls` (integer): 0 or 1 — the metered Trial Balance call, charged only when no anchor has been captured for the opening day yet.\n- `journals_per_day` (number|null): the cached cadence the page count is extrapolated from.\n- `daily_remaining` (integer|null): Xero calls left in today's budget (from the connection's tracked usage; null if not tracked yet).\n- `daily_limit` (integer): Xero's per-organisation daily API cap (5000).\n- `daily_reset_at` (string|null): ISO8601 timestamp when the daily budget resets.\n- `over_budget` (boolean): true when `estimated_calls` exceeds `daily_remaining`.\n- `inventory_start_date` (string|null): Y-m-d lower bound of the window.\n- `window_from` (string|null): Y-m-d clamped window start actually estimated.\n- `window_to` (string): Y-m-d window end actually estimated.\n- `cached_from` / `cached_to` (string|null): Y-m-d span of journals already cached."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/sync-estimate?connection_id=5","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","sync-estimate"],"query":[{"key":"connection_id","value":"5","description":"Accounting connection id (the provider's integration instance). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"can_sync\": true,\n    \"reason\": null,\n    \"cadence_known\": true,\n    \"estimated_calls\": 19,\n    \"estimated_pages\": 18,\n    \"estimated_probe_calls\": 0,\n    \"anchor_calls\": 1,\n    \"journals_per_day\": 9.42,\n    \"daily_remaining\": 4870,\n    \"daily_limit\": 5000,\n    \"daily_reset_at\": \"2026-06-28T00:00:00+00:00\",\n    \"over_budget\": false,\n    \"inventory_start_date\": \"2026-01-01\",\n    \"window_from\": \"2026-01-01\",\n    \"window_to\": \"2026-06-27\",\n    \"cached_from\": \"2026-03-15\",\n    \"cached_to\": \"2026-06-20\"\n  }\n}"}]},{"name":"Rebuild Inventory Daily Series","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","rebuild"]},"description":"Kick the background tracked job that materializes the **SKU side** of the daily series (point-in-time inventory value per account per day). Free — no provider calls. Returns the tracked job log id so the UI can follow it in the global progress tray.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Request body:**\n- `connection_id` (integer, **required**): accounting connection id the points are keyed to.\n- `nominal_code_ids` (array, optional): subset of earmarked account ids. Defaults to all earmarked.\n- `from` (date, optional): local-day window start. Defaults to the inventory start date.\n- `to` (date, optional, after_or_equal:from): local-day window end. Defaults to now.\n\nWindow defaults span inventory_start_date → today (~hundreds of days), so this is a long-running job.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"nominal_code_ids\": [\n    87\n  ],\n  \"from\": \"2026-01-01\",\n  \"to\": \"2026-06-27\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/rebuild","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","rebuild"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Inventory reconciliation rebuild started\"\n}"}]},{"name":"Capture Provider Inventory Balances","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/capture-provider","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","capture-provider"]},"description":"Capture the provider's GL balance for the earmarked inventory accounts as-of a day onto the daily series — the metered counterpart to the (free) SKU-side rebuild. **Makes one live Xero Trial Balance call** (needs `accounting.reports.read`), so callers drive the cadence; the provider series is intentionally sparse (only captured days get a row). Days/accounts with no matching provider account are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Request body:**\n- `connection_id` (integer, **required**): accounting connection id.\n- `to` (date, optional): as-of day for the Trial Balance. Defaults to now.\n\nReturns `{ captured: <number of accounts written> }`.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"to\": \"2026-06-27\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/capture-provider","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","capture-provider"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"captured\": 1\n  },\n  \"success\": true\n}"}]},{"name":"Sync Provider GL Journals","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/sync-journals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","sync-journals"]},"description":"Kick the background tracked job that pulls the provider's **GL journals feed** (Xero Journals) into the local cache — the metered half of the daily reconciliation. One paginated pull per run; resumes incrementally from the highest JournalNumber already cached. Once cached, **Rebuild Inventory Daily Series** reconstructs the daily provider balance from the cache with no further provider call. Returns the tracked job log id so the UI can follow it in the global progress tray.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Request body:**\n- `connection_id` (integer, **required**): accounting connection id (the provider's integration instance) whose journals are pulled.\n- `from` (date `Y-m-d`, optional): lower-bounds the pull by journal date. Clamped up to the Inventory Start Date (the opening anchor replaces summing the ledger before it), so an earlier value is accepted but never lowers the window below the anchor. When omitted, the window starts at the Inventory Start Date.\n- `full` (boolean, optional, default `false`): when `true`, re-pulls the entire ledger from JournalNumber 0 instead of resuming incrementally from the highest cached journal.\n\n**Side effect:** makes metered API calls to the accounting provider (one page per ~100 journals), capped at the connection's remaining daily Xero API budget — a budget-out pauses the run cleanly and it auto-resumes once the budget refreshes.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5,\n  \"from\": \"2026-01-01\",\n  \"full\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/sync-journals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","sync-journals"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4822\n  },\n  \"message\": \"Provider GL journals sync started\"\n}"}]},{"name":"List Statement Imports","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements"]},"description":"Paginated list of prior bank-statement screenshot extractions (most recent first), each with its parsed line count and spent/received totals.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 6,\n      \"status\": \"ready\",\n      \"source\": \"upload\",\n      \"original_filename\": \"statement.png\",\n      \"line_count\": 2,\n      \"spent_total\": \"621.1100\",\n      \"received_total\": \"144.2200\",\n      \"error_message\": null,\n      \"created_at\": \"2026-06-28T10:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"last_page\": 1,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Upload Statement Screenshot","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements"]},"description":"Upload a screenshot of bank statement lines and **queue** its OCR extraction (Azure Document Intelligence prebuilt-layout). Returns immediately with the import in the `extracting` state plus a top-level `tracked_job_log_id`; the parsed lines arrive once the background a background job completes (watch it via the tracked job log endpoints, then re-fetch the import via GET `.../bank-statements/{id}`). Deferring the OCR keeps an unreachable provider from hanging the upload request.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nXero exposes no API for raw statement lines, hence the screenshot path. Handles both Xero layouts: the cash-coding grid (one line per row) and the two-column reconcile card view (date / description / type stacked in one column).\n\n**Content-Type:** multipart/form-data.\n**Authentication:** Requires Bearer token.\n\nIf the OCR provider cannot read the image, the job flips the import to `failed` with an `error_message` (surfaced via the tracked job log endpoints and on re-fetch) — the upload request itself still succeeds.","body":{"mode":"formdata","formdata":[{"key":"image","type":"file","src":[]},{"key":"source","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"status\": \"extracting\",\n    \"source\": \"upload\",\n    \"original_filename\": \"statement.png\",\n    \"line_count\": 0,\n    \"spent_total\": null,\n    \"received_total\": null,\n    \"error_message\": null,\n    \"created_at\": \"2026-06-28T10:00:00+00:00\",\n    \"lines\": []\n  },\n  \"tracked_job_log_id\": 42\n}"}]},{"name":"Get Statement Import","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport"],"variable":[{"key":"bankStatementImport","value":"6","description":"Import id."}]},"description":"A single statement-screenshot extraction with all its parsed lines.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport"],"variable":[{"key":"bankStatementImport","value":"6","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"status\": \"ready\",\n    \"source\": \"upload\",\n    \"original_filename\": \"statement.png\",\n    \"line_count\": 2,\n    \"spent_total\": \"621.1100\",\n    \"received_total\": \"144.2200\",\n    \"error_message\": null,\n    \"created_at\": \"2026-06-28T10:00:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 11,\n        \"bank_statement_import_id\": 6,\n        \"statement_date\": \"2025-12-15\",\n        \"payee\": null,\n        \"description\": \"ORIG CO NAME:Amazon Mexico Se\",\n        \"reference\": \"POSCREDIT\",\n        \"spent\": null,\n        \"received\": \"144.2200\",\n        \"direction\": \"received\",\n        \"match_status\": \"unmatched\",\n        \"sort_order\": 0\n      },\n      {\n        \"id\": 12,\n        \"bank_statement_import_id\": 6,\n        \"statement_date\": \"2026-01-08\",\n        \"payee\": null,\n        \"description\": \"Online ACH Payment To Stainout\",\n        \"reference\": \"BILLPAYMENT\",\n        \"spent\": \"621.1100\",\n        \"received\": null,\n        \"direction\": \"spent\",\n        \"match_status\": \"unmatched\",\n        \"sort_order\": 1\n      }\n    ]\n  }\n}"}]},{"name":"Delete Statement Import","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport"],"variable":[{"key":"bankStatementImport","value":"6","description":"Import id."}]},"description":"Delete a statement extraction and its parsed lines.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport"],"variable":[{"key":"bankStatementImport","value":"6","description":"Import id."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"List Line Match Suggestions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/suggestions","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","suggestions"],"variable":[{"key":"bankStatementImport","value":"24","description":"Import id."}]},"description":"For each parsed line in an import, candidate SKU ledger entries it could reconcile against. Money-in lines (Received) match AR documents (Sales Order Invoice, Vendor Credit); money-out lines (Spent) match AP documents (Bill, Purchase Order Invoice, Sales Credit). Candidates are entries of the matching type whose total is within $0.01 of the line amount and whose effective date is within 60 days of the statement date, ranked by date proximity then amount closeness. `synced` flags entries already pushed to the provider.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Candidate kinds:** `match_kind=entry` is a single SKU document; `match_kind=settlement` is an Amazon settlement aggregate — matched on the settlement's recorded payout (amazon_financial_event_groups.ConvertedTotalCurrencyAmount), carrying every ledger entry it generated in `entry_ids` (sales invoices + fee bills + carved-out landed-cost bills linked via amazon_report_settlement_data). Confirming a settlement candidate POSTs all of `entry_ids`.\n\nSettlement candidates carry `settlement_id` (the AmazonFinancialEventGroup id — links to /integrations/amazon/finance/bank-transaction/{id}), `settlement_reference` (the FinancialEventGroupId shown as the settlement #), and `entries[]` (each linked ledger entry: id, reference, entry_type_label, is_landed_cost) so the UI can deep-link every document.\n\n**Per-suggestion `dismissed_count`** (integer): how many candidates the user has declared “not a match” on this line (via Dismiss Line Match Suggestion). Dismissed candidates are excluded from `candidates` and restorable as a set via Restore Dismissed Suggestions.\n\n**Group candidates** (`match_kind=group`): several of one supplier's documents that together settle a money-out payment. When the line's memo names the supplier, combinations may also NET vendor credits against the invoices (payment = invoices − credits) — the label reads e.g. '2 invoices − 1 credit' and `amount` is the net. Each `entries[]` element carries its own `entry_type`, `amount`, `counterparty_name` and `effective_at` so the UI renders a signed calculation."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/suggestions","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","suggestions"],"variable":[{"key":"bankStatementImport","value":"24","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"line\": {\n        \"id\": 451,\n        \"bank_statement_import_id\": 23,\n        \"statement_date\": \"2026-04-28\",\n        \"payee\": null,\n        \"description\": \"ORIG CO NAME:Amazon Mexico\",\n        \"reference\": \"POSCREDIT\",\n        \"spent\": null,\n        \"received\": \"432.2700\",\n        \"direction\": \"received\",\n        \"match_status\": \"unmatched\",\n        \"sort_order\": 0,\n        \"matches\": []\n      },\n      \"candidates\": [\n        {\n          \"match_kind\": \"entry\",\n          \"amount\": \"432.2700\",\n          \"effective_at\": \"2026-04-26\",\n          \"source_label\": \"Bill\",\n          \"synced\": false,\n          \"ledger_journal_entry_id\": 612,\n          \"entry_type\": \"bill\",\n          \"entry_type_label\": \"Bill\",\n          \"counterparty_name\": \"Acme Supplies Inc\",\n          \"reference\": \"…\",\n          \"currency_code\": \"USD\",\n          \"source_type\": \"App\\\\Models\\\\Bill\",\n          \"source_id\": 91\n        },\n        {\n          \"match_kind\": \"settlement\",\n          \"amount\": \"432.2700\",\n          \"effective_at\": \"2026-04-28\",\n          \"source_label\": \"Amazon Settlement\",\n          \"synced\": false,\n          \"settlement_id\": 350,\n          \"settlement_reference\": \"5cKTkaXNDp…\",\n          \"entry_ids\": [\n            700,\n            701,\n            702\n          ],\n          \"entry_count\": 3,\n          \"components\": [\n            {\n              \"label\": \"Sales Order Invoice\",\n              \"count\": 1,\n              \"amount\": \"1274.9395\"\n            },\n            {\n              \"label\": \"Bill\",\n              \"count\": 1,\n              \"amount\": \"1305.8630\"\n            },\n            {\n              \"label\": \"Landed-cost Bill\",\n              \"count\": 1,\n              \"amount\": \"129.8400\"\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Confirm Line Match","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","match"],"variable":[{"key":"bankStatementLine","value":"479","description":"Statement line id."}]},"description":"Confirm one or more ledger entries as the match for a line. Persists a denormalized snapshot of each match (so it survives ledger rebuilds) and marks the line `matched`. Idempotent — re-matching the same entry is a no-op.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:** `entry_ids` (required array of ledger_journal_entry ids).\n**Authentication:** Requires Bearer token.\n\n**`sync_block`** (on each line): pre-push sync verdict for the line's matched document(s) — `null` when every document will sync, otherwise `{ blocked: true, enableable: bool, reasons: string[], blocked_entry_ids: int[], enableable_entry_ids: int[] }`. Surfaced so the UI can warn (and offer Enable sync) BEFORE a push that would otherwise silently not reach Xero.\n\n**Optional Amazon-settlement context** (omit for a single-document match): `match_kind` ('entry' | 'settlement'), `settlement_id` (required when match_kind=settlement), `settlement_reference`, `settlement_payout` (the net payout the bank line matched on). When present, every persisted match row records the settlement so the UI labels it an 'Amazon Settlement · {payout}' regardless of how many SKU documents it touched.","body":{"mode":"raw","raw":"{\n  \"entry_ids\": [\n    10\n  ],\n  \"match_kind\": \"settlement\",\n  \"settlement_id\": 337,\n  \"settlement_reference\": \"5cKTkaXNDpXqmNv0MzaOHAMppp6CsZOYXrgMbDv4UDg\",\n  \"settlement_payout\": \"432.27\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","match"],"variable":[{"key":"bankStatementLine","value":"479","description":"Statement line id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 479,\n    \"bank_statement_import_id\": 24,\n    \"statement_date\": \"2024-04-26\",\n    \"payee\": null,\n    \"description\": \"ACH Payment to supplier A\",\n    \"reference\": \"BILLPAYMENT\",\n    \"spent\": \"73.9000\",\n    \"received\": null,\n    \"direction\": \"spent\",\n    \"match_status\": \"matched\",\n    \"sort_order\": 0,\n    \"sync_block\": null,\n    \"matches\": [\n      {\n        \"id\": 1,\n        \"ledger_journal_entry_id\": 10,\n        \"entry_type\": \"bill\",\n        \"entry_type_label\": \"Bill\",\n        \"match_kind\": \"settlement\",\n        \"settlement_id\": 337,\n        \"settlement_reference\": \"5cKTkaXNDpXqmNv0MzaOHAMppp6CsZOYXrgMbDv4UDg\",\n        \"settlement_payout\": \"432.2700\",\n        \"reference\": \"xjwbaRFTPT8...\",\n        \"counterparty_name\": \"Supplier A\",\n        \"amount\": \"73.9000\",\n        \"effective_at\": \"2024-04-24\",\n        \"source_type\": \"App\\\\Models\\\\Bill\",\n        \"source_id\": 42,\n        \"source_label\": \"Bill\"\n      }\n    ]\n  }\n}"}]},{"name":"Clear Line Match","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","match"],"variable":[{"key":"bankStatementLine","value":"479","description":"Statement line id."}]},"description":"Remove all confirmed matches for a line and mark it `unmatched`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","match"],"variable":[{"key":"bankStatementLine","value":"479","description":"Statement line id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 479,\n    \"bank_statement_import_id\": 24,\n    \"statement_date\": \"2024-04-26\",\n    \"payee\": null,\n    \"description\": \"ACH Payment to supplier A\",\n    \"reference\": \"BILLPAYMENT\",\n    \"spent\": \"73.9000\",\n    \"received\": null,\n    \"direction\": \"spent\",\n    \"match_status\": \"unmatched\",\n    \"sort_order\": 0,\n    \"matches\": []\n  }\n}"}]},{"name":"Dismiss Line Match Suggestion","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/dismiss-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","dismiss-match"],"variable":[{"key":"bankStatementLine","value":"93","description":"Statement line id."}]},"description":"Declare a suggested candidate \"not a match\" for this line. The candidate's identity is pinned to the line (order-independent fingerprint), so the same document/combination is never re-offered by Line Match Suggestions or confirmed by Auto-match — and a dismissed group combination's per-supplier slot frees up for the next-best combination on the next refresh. Undone by the Restore Dismissed Suggestions endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:**\n- `match_kind` (required, 'entry' | 'settlement' | 'group') — the candidate's kind exactly as the suggestions endpoint returned it.\n- `entry_ids` (required unless match_kind=settlement, array of integers) — the candidate's ledger entry id(s); order does not matter.\n- `settlement_id` (required when match_kind=settlement, integer) — the Amazon settlement id.\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"match_kind\": \"group\",\n  \"entry_ids\": [\n    338,\n    5348,\n    5623\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/dismiss-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","dismiss-match"],"variable":[{"key":"bankStatementLine","value":"93","description":"Statement line id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Dismissed — that combination will not be suggested again.\",\n  \"data\": []\n}"}]},{"name":"Restore Dismissed Suggestions","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/dismissals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","dismissals"],"variable":[{"key":"bankStatementLine","value":"93","description":"Statement line id."}]},"description":"Clear every \"not a match\" verdict on the line, putting all dismissed candidates back into circulation — they reappear on the next Line Match Suggestions call. Returns how many dismissals were removed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/lines/{bankStatementLine}/dismissals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements","lines",":bankStatementLine","dismissals"],"variable":[{"key":"bankStatementLine","value":"93","description":"Statement line id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Dismissed suggestions restored.\",\n  \"data\": {\n    \"restored\": 2\n  }\n}"}]},{"name":"Auto-match Single-candidate Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/auto-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","auto-match"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]},"description":"Confirm every still-unmatched line in the import that has EXACTLY ONE candidate (an unambiguous match). Lines with zero or multiple candidates are left for the user. Optional body `line_ids` scopes it to a selection (bulk-match the ticked rows); omit to match all.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the number matched and the refreshed import (lines + their matches).\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    479,\n    480\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/auto-match","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","auto-match"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched\": 31,\n    \"import\": {\n      \"id\": 23,\n      \"status\": \"ready\",\n      \"line_count\": 38,\n      \"lines\": [\n        \"…\"\n      ]\n    }\n  }\n}"}]},{"name":"Unmatch All Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/unmatch-all","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","unmatch-all"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]},"description":"Clear the confirmed matches across the import (bulk unmatch). Only lines whose `match_status` is `matched` are affected; the linked SKU documents are untouched — only the bank-line links are removed. Optional body `line_ids` scopes it to a selection (unmatch the ticked rows); omit to unmatch every matched line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the number unmatched and the refreshed import (lines + their matches).\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    479,\n    480\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/unmatch-all","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","unmatch-all"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unmatched\": 31,\n    \"import\": {\n      \"id\": 23,\n      \"status\": \"ready\",\n      \"line_count\": 38,\n      \"lines\": [\n        \"…\"\n      ]\n    }\n  }\n}"}]},{"name":"Push Matched Lines to Xero","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/push-to-xero","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","push-to-xero"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]},"description":"Push the matched line(s)' SKU document(s) to the accounting provider (Xero) via the shared ledger sync pipeline (the same dedup-aware path the rest of the app posts through). Only lines whose `match_status` is `matched` are pushed; each matched entry that is already linked-current in Xero is skipped, others are enqueued as a Create/Update sync operation. Optional body `line_ids` scopes it to a selection (a single line, or a bulk pick); omit to push every matched line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nA line flips to `synced` the moment all of its documents are confirmed in Xero; lines whose documents are still being pushed stay `matched` and self-heal to `synced` on the next refresh (suggestions / show) once the async push lands.\n\nReturns: `entries_enqueued` (entries run through the sync pipeline), `lines_synced` (lines now fully in Xero), `lines_pending` (lines still pushing), and the refreshed import (lines + their matches).\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    479,\n    480\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/push-to-xero","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","push-to-xero"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entries_enqueued\": 33,\n    \"lines_synced\": 28,\n    \"lines_pending\": 5,\n    \"import\": {\n      \"id\": 23,\n      \"status\": \"ready\",\n      \"line_count\": 38,\n      \"lines\": [\n        \"…\"\n      ]\n    }\n  }\n}"}]},{"name":"Enable Sync on Matched Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/enable-sync","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","enable-sync"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]},"description":"Force-enable sync on the matched line(s)' document(s) whose sync is currently **disabled-but-enableable** — a settings opt-out (e.g. this entry type isn't synced, or it's before the sync start date) or a per-entry `force_disabled` override. Writes a `force_enabled` override on each such entry (via the same path as the per-entry override endpoint) so a subsequent **Push to Xero** actually reaches the provider instead of silently no-opping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nStructurally-blocked documents — a batch member, an open batch, an inactive connection, or internal-only entries — are **left untouched** (they can't be force-enabled). Optional body `line_ids` scopes it to a single line's Enable or a bulk selection; omit to enable across every matched line.\n\nReturns: `entries_enabled` (documents flipped to force_enabled), `lines_affected` (matched lines touched), and the refreshed import (lines + their matches, with cleared `sync_block`s).\n\nGuarded by the `accounting.sync` permission.\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    479,\n    480\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/bank-statements/{bankStatementImport}/enable-sync","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","bank-statements",":bankStatementImport","enable-sync"],"variable":[{"key":"bankStatementImport","value":"23","description":"Import id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entries_enabled\": 4,\n    \"lines_affected\": 1,\n    \"import\": {\n      \"id\": 23,\n      \"status\": \"ready\",\n      \"line_count\": 38,\n      \"lines\": [\n        \"…\"\n      ]\n    }\n  }\n}"}]},{"name":"Resume Provider GL Journals Sync","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/resume-journals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","resume-journals"]},"description":"Manually **resume a budget-paused** provider GL journals sync from its stored cursor, instead of waiting for the hourly auto-resume sweep (`ledger:reconciliation:resume-provider-sync`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen the metered backfill (see **Sync Provider GL Journals**) exhausts its reserved per-run provider-call budget, it pauses cleanly and records a resume cursor on the connection (`integration_settings.inventoryReconSync`: `resume_offset`, `from`, `user_id`, `paused_at`). This endpoint re-dispatches the tracked job from that cursor — same `connection_id`, `full=false`, picking up at the saved `from` / `resume_offset` — and returns the tracked job log id so the UI can follow it in the global progress tray.\n\n**Authentication:** Requires Bearer token + `accounting.sync` permission.\n\n**Request body:**\n- `connection_id` (integer, **required**): accounting connection id whose paused sync is resumed.\n\n**Responses:**\n- `200` — a paused run existed; the resume job was dispatched. Returns `data.tracked_job_log_id`.\n- `409` — no paused provider GL sync is recorded for this connection (nothing to resume).\n- `422` — `connection_id` missing or not an integer.","body":{"mode":"raw","raw":"{\n  \"connection_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/reconciliation/inventory/resume-journals","host":["{{baseUrl}}"],"path":["api","ledger","reconciliation","inventory","resume-journals"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4823\n  },\n  \"message\": \"Provider GL journals sync resumed\"\n}"}]},{"name":"List Close Periods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods","host":["{{baseUrl}}"],"path":["api","ledger","close","periods"]},"description":"Every month in the closable range (most recent first) with lifecycle status (open, in_review, closing, closed), checklist progress, blocking-failure and warning counts, and close sign-off metadata. Months are materialized lazily — a month that has never been interacted with reports status open with is_started false.\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/close/periods","host":["{{baseUrl}}"],"path":["api","ledger","close","periods"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"periods\": [\n      {\n        \"period\": \"2026-06\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"status\": \"in_review\",\n        \"is_started\": true,\n        \"is_closable\": true,\n        \"is_reopenable\": false,\n        \"progress\": {\n          \"done\": 12,\n          \"total\": 14\n        },\n        \"blocking_failures\": 0,\n        \"warnings\": 2,\n        \"closed_at\": null,\n        \"closed_by\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Close Period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Full detail for one period (period key format YYYY-MM): the close checklist with each item's latest evaluation, lock state (active lock date plus per-connection provider lock dates), report snapshot index, and close/reopen eligibility flags. For a month that has not been started, the checklist is a live read-only preview.\n\nAuthentication: Bearer token.\n\nErrors: 422 when the period predates the accounting start date or is in the future."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period\": {\n      \"period\": \"2026-06\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"status\": \"in_review\",\n      \"status_label\": \"In Review\",\n      \"is_started\": true,\n      \"is_closable\": true,\n      \"is_reopenable\": false,\n      \"closed_at\": null,\n      \"closed_by\": null,\n      \"reopened_at\": null,\n      \"reopened_by\": null,\n      \"reopen_reason\": null,\n      \"notes\": null,\n      \"lock\": {\n        \"active_lock_date\": \"2026-05-31\",\n        \"provider_locks\": [\n          {\n            \"connection_id\": 30,\n            \"connection_name\": \"Xero\",\n            \"lock_date\": \"2026-05-31\"\n          }\n        ]\n      },\n      \"checklist\": [\n        {\n          \"id\": 41,\n          \"key\": \"entries_balanced\",\n          \"title\": \"All entries balanced\",\n          \"description\": null,\n          \"category\": \"data_completeness\",\n          \"category_label\": \"Data completeness\",\n          \"type\": \"automated\",\n          \"severity\": \"blocking\",\n          \"status\": \"pass\",\n          \"result\": {\n            \"count\": 0,\n            \"link\": {\n              \"tab\": \"transactions\",\n              \"filter\": {\n                \"balance_mismatch\": true\n              }\n            }\n          },\n          \"acknowledged\": false,\n          \"completed_by\": null,\n          \"completed_at\": null,\n          \"evaluated_at\": \"2026-07-17T10:04:00+00:00\",\n          \"sort_order\": 11\n        },\n        {\n          \"id\": 52,\n          \"key\": \"review_income_statement\",\n          \"title\": \"Review Income Statement\",\n          \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n          \"category\": \"review\",\n          \"category_label\": \"Review\",\n          \"type\": \"manual\",\n          \"severity\": null,\n          \"status\": \"done\",\n          \"result\": {\n            \"report_key\": \"income_statement\"\n          },\n          \"acknowledged\": false,\n          \"completed_by\": {\n            \"id\": 5,\n            \"name\": \"Dana Bookkeeper\"\n          },\n          \"completed_at\": \"2026-07-16T22:10:00+00:00\",\n          \"evaluated_at\": null,\n          \"sort_order\": 300\n        }\n      ],\n      \"snapshots\": []\n    }\n  }\n}"}]},{"name":"Start Period Close","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/start","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","start"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Begin the close for a month: materializes the period, seeds its checklist (automated checks, built-in review items, and any custom items configured in accounting settings), and evaluates every automated check. Returns the full period detail.\n\nAuthentication: Bearer token. Requires the accounting sync permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/start","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","start"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period\": {\n      \"period\": \"2026-06\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"status\": \"in_review\",\n      \"status_label\": \"In Review\",\n      \"is_started\": true,\n      \"is_closable\": true,\n      \"is_reopenable\": false,\n      \"closed_at\": null,\n      \"closed_by\": null,\n      \"reopened_at\": null,\n      \"reopened_by\": null,\n      \"reopen_reason\": null,\n      \"notes\": null,\n      \"lock\": {\n        \"active_lock_date\": \"2026-05-31\",\n        \"provider_locks\": [\n          {\n            \"connection_id\": 30,\n            \"connection_name\": \"Xero\",\n            \"lock_date\": \"2026-05-31\"\n          }\n        ]\n      },\n      \"checklist\": [\n        {\n          \"id\": 41,\n          \"key\": \"entries_balanced\",\n          \"title\": \"All entries balanced\",\n          \"description\": null,\n          \"category\": \"data_completeness\",\n          \"category_label\": \"Data completeness\",\n          \"type\": \"automated\",\n          \"severity\": \"blocking\",\n          \"status\": \"pass\",\n          \"result\": {\n            \"count\": 0,\n            \"link\": {\n              \"tab\": \"transactions\",\n              \"filter\": {\n                \"balance_mismatch\": true\n              }\n            }\n          },\n          \"acknowledged\": false,\n          \"completed_by\": null,\n          \"completed_at\": null,\n          \"evaluated_at\": \"2026-07-17T10:04:00+00:00\",\n          \"sort_order\": 11\n        },\n        {\n          \"id\": 52,\n          \"key\": \"review_income_statement\",\n          \"title\": \"Review Income Statement\",\n          \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n          \"category\": \"review\",\n          \"category_label\": \"Review\",\n          \"type\": \"manual\",\n          \"severity\": null,\n          \"status\": \"done\",\n          \"result\": {\n            \"report_key\": \"income_statement\"\n          },\n          \"acknowledged\": false,\n          \"completed_by\": {\n            \"id\": 5,\n            \"name\": \"Dana Bookkeeper\"\n          },\n          \"completed_at\": \"2026-07-16T22:10:00+00:00\",\n          \"evaluated_at\": null,\n          \"sort_order\": 300\n        }\n      ],\n      \"snapshots\": []\n    }\n  },\n  \"message\": \"Close started for 2026-06.\"\n}"}]},{"name":"Refresh Close Checklist","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/refresh","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","refresh"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Re-evaluate every automated check on a started, non-closed period and append any newly configured custom checklist items. Completed manual items are never reset.\n\nAuthentication: Bearer token. Requires the accounting sync permission.\n\nErrors: 422 when the period has not been started or is already closed."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/refresh","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","refresh"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period\": {\n      \"period\": \"2026-06\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"status\": \"in_review\",\n      \"status_label\": \"In Review\",\n      \"is_started\": true,\n      \"is_closable\": true,\n      \"is_reopenable\": false,\n      \"closed_at\": null,\n      \"closed_by\": null,\n      \"reopened_at\": null,\n      \"reopened_by\": null,\n      \"reopen_reason\": null,\n      \"notes\": null,\n      \"lock\": {\n        \"active_lock_date\": \"2026-05-31\",\n        \"provider_locks\": [\n          {\n            \"connection_id\": 30,\n            \"connection_name\": \"Xero\",\n            \"lock_date\": \"2026-05-31\"\n          }\n        ]\n      },\n      \"checklist\": [\n        {\n          \"id\": 41,\n          \"key\": \"entries_balanced\",\n          \"title\": \"All entries balanced\",\n          \"description\": null,\n          \"category\": \"data_completeness\",\n          \"category_label\": \"Data completeness\",\n          \"type\": \"automated\",\n          \"severity\": \"blocking\",\n          \"status\": \"pass\",\n          \"result\": {\n            \"count\": 0,\n            \"link\": {\n              \"tab\": \"transactions\",\n              \"filter\": {\n                \"balance_mismatch\": true\n              }\n            }\n          },\n          \"acknowledged\": false,\n          \"completed_by\": null,\n          \"completed_at\": null,\n          \"evaluated_at\": \"2026-07-17T10:04:00+00:00\",\n          \"sort_order\": 11\n        },\n        {\n          \"id\": 52,\n          \"key\": \"review_income_statement\",\n          \"title\": \"Review Income Statement\",\n          \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n          \"category\": \"review\",\n          \"category_label\": \"Review\",\n          \"type\": \"manual\",\n          \"severity\": null,\n          \"status\": \"done\",\n          \"result\": {\n            \"report_key\": \"income_statement\"\n          },\n          \"acknowledged\": false,\n          \"completed_by\": {\n            \"id\": 5,\n            \"name\": \"Dana Bookkeeper\"\n          },\n          \"completed_at\": \"2026-07-16T22:10:00+00:00\",\n          \"evaluated_at\": null,\n          \"sort_order\": 300\n        }\n      ],\n      \"snapshots\": []\n    }\n  },\n  \"message\": \"Checklist re-evaluated.\"\n}"}]},{"name":"Complete Checklist Item","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/checklist/{item}/complete","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","checklist",":item","complete"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"item","value":"","description":"The item ID."}]},"description":"Check a manual checklist item off, recording who completed it and when. Automated checks cannot be checked off — re-evaluate them with Refresh Close Checklist instead.\n\nAuthentication: Bearer token. Requires the accounting sync permission.\n\nErrors: 422 for automated items or when the period is closed."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/checklist/{item}/complete","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","checklist",":item","complete"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"item","value":"","description":"The item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"item\": {\n      \"id\": 52,\n      \"key\": \"review_income_statement\",\n      \"title\": \"Review Income Statement\",\n      \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n      \"category\": \"review\",\n      \"category_label\": \"Review\",\n      \"type\": \"manual\",\n      \"severity\": null,\n      \"status\": \"done\",\n      \"result\": {\n        \"report_key\": \"income_statement\"\n      },\n      \"acknowledged\": false,\n      \"completed_by\": {\n        \"id\": 5,\n        \"name\": \"Dana Bookkeeper\"\n      },\n      \"completed_at\": \"2026-07-16T22:10:00+00:00\",\n      \"evaluated_at\": null,\n      \"sort_order\": 300\n    }\n  },\n  \"message\": \"Review Income Statement checked off.\"\n}"}]},{"name":"Uncomplete Checklist Item","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/checklist/{item}/complete","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","checklist",":item","complete"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"item","value":"","description":"The item ID."}]},"description":"Undo a manual checklist item's completion on a non-closed period.\n\nAuthentication: Bearer token. Requires the accounting sync permission."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/checklist/{item}/complete","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","checklist",":item","complete"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"item","value":"","description":"The item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"item\": {\n      \"id\": 52,\n      \"key\": \"review_income_statement\",\n      \"title\": \"Review Income Statement\",\n      \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n      \"category\": \"review\",\n      \"category_label\": \"Review\",\n      \"type\": \"manual\",\n      \"severity\": null,\n      \"status\": \"open\",\n      \"result\": {\n        \"report_key\": \"income_statement\"\n      },\n      \"acknowledged\": false,\n      \"completed_by\": null,\n      \"completed_at\": null,\n      \"evaluated_at\": null,\n      \"sort_order\": 300\n    }\n  },\n  \"message\": \"Review Income Statement reopened.\"\n}"}]},{"name":"Close Period","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/close","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","close"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Close and lock the period. Only the earliest non-closed month can close (periods close strictly in order). Every failing blocking check refuses the close; every warning-level failure and incomplete manual item must be listed in acknowledged_keys. The close runs as a background job that re-validates all gates, snapshots the report pack, inserts the period lock (new entries dated on or before the period end are refused; corrections are redated to the first open day), and records the sign-off. Returns the background job id.\n\nAuthentication: Bearer token. Requires the accounting settings management permission.\n\nErrors: 422 when a blocking check fails, an acknowledgement is missing, the month is out of order, or another close is already running.","body":{"mode":"raw","raw":"{\n  \"acknowledged_keys\": [\n    \"provider_docs_reconciled\",\n    \"review_income_statement\",\n    \"review_balance_sheet\",\n    \"review_inventory_valuation\"\n  ],\n  \"notes\": \"June close complete.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/close","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","close"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9311\n  },\n  \"message\": \"Closing 2026-06 — track progress in the job tray.\"\n}"}]},{"name":"Reopen Period","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/reopen","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","reopen"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Reopen the most recently closed period (a reason is required and audit-logged). Removes the period's own lock, flags its report snapshots stale, and returns the period to review. When the accounting provider still has the month locked, residual_provider_locks lists those connections — entries stay locked provider-side until the books are reopened there too.\n\nAuthentication: Bearer token. Requires the accounting settings management permission.\n\nErrors: 422 when the period is not the most recently closed one or a close is currently running.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Client sent late invoices for June.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/reopen","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","reopen"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period\": {\n      \"period\": \"2026-06\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"status\": \"in_review\",\n      \"status_label\": \"In Review\",\n      \"is_started\": true,\n      \"is_closable\": true,\n      \"is_reopenable\": false,\n      \"closed_at\": null,\n      \"closed_by\": null,\n      \"reopened_at\": null,\n      \"reopened_by\": null,\n      \"reopen_reason\": null,\n      \"notes\": null,\n      \"lock\": {\n        \"active_lock_date\": \"2026-05-31\",\n        \"provider_locks\": [\n          {\n            \"connection_id\": 30,\n            \"connection_name\": \"Xero\",\n            \"lock_date\": \"2026-05-31\"\n          }\n        ]\n      },\n      \"checklist\": [\n        {\n          \"id\": 41,\n          \"key\": \"entries_balanced\",\n          \"title\": \"All entries balanced\",\n          \"description\": null,\n          \"category\": \"data_completeness\",\n          \"category_label\": \"Data completeness\",\n          \"type\": \"automated\",\n          \"severity\": \"blocking\",\n          \"status\": \"pass\",\n          \"result\": {\n            \"count\": 0,\n            \"link\": {\n              \"tab\": \"transactions\",\n              \"filter\": {\n                \"balance_mismatch\": true\n              }\n            }\n          },\n          \"acknowledged\": false,\n          \"completed_by\": null,\n          \"completed_at\": null,\n          \"evaluated_at\": \"2026-07-17T10:04:00+00:00\",\n          \"sort_order\": 11\n        },\n        {\n          \"id\": 52,\n          \"key\": \"review_income_statement\",\n          \"title\": \"Review Income Statement\",\n          \"description\": \"Read through the month's Income Statement for unexpected balances before sign-off.\",\n          \"category\": \"review\",\n          \"category_label\": \"Review\",\n          \"type\": \"manual\",\n          \"severity\": null,\n          \"status\": \"done\",\n          \"result\": {\n            \"report_key\": \"income_statement\"\n          },\n          \"acknowledged\": false,\n          \"completed_by\": {\n            \"id\": 5,\n            \"name\": \"Dana Bookkeeper\"\n          },\n          \"completed_at\": \"2026-07-16T22:10:00+00:00\",\n          \"evaluated_at\": null,\n          \"sort_order\": 300\n        }\n      ],\n      \"snapshots\": []\n    },\n    \"residual_provider_locks\": []\n  },\n  \"message\": \"2026-06 reopened.\"\n}"}]},{"name":"Get Close Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/reports/{report}","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","reports",":report"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"report","value":"","description":"The report ID."}]},"description":"One report of the month-end pack. Report keys: income_statement, balance_sheet, trial_balance, inventory_valuation, cogs, ginr, reconciliation_summary. On a closed period this returns the snapshot frozen at close time (source: snapshot); otherwise a live build flagged preliminary. Payloads carry statement-level rows plus a totals map of headline figures.\n\nAuthentication: Bearer token.\n\nErrors: 422 for an unknown report key."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/reports/{report}","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","reports",":report"],"variable":[{"key":"period","value":"","description":"The period ID."},{"key":"report","value":"","description":"The report ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"report\": {\n      \"report_key\": \"trial_balance\",\n      \"label\": \"Trial Balance\",\n      \"source\": \"snapshot\",\n      \"preliminary\": false,\n      \"is_stale\": false,\n      \"generated_at\": \"2026-07-05T14:22:00+00:00\",\n      \"payload\": {\n        \"totals\": {\n          \"total_opening\": 0,\n          \"total_debits\": 633597.98,\n          \"total_credits\": 633597.98,\n          \"total_closing\": 0\n        },\n        \"rows\": [\n          {\n            \"account_code\": \"1200\",\n            \"account_name\": \"Inventory\",\n            \"opening_balance\": 700000,\n            \"period_debits\": 45000,\n            \"period_credits\": 38000,\n            \"closing_balance\": 707000\n          },\n          {\n            \"account_code\": \"4000\",\n            \"account_name\": \"Sales\",\n            \"opening_balance\": 0,\n            \"period_debits\": 0,\n            \"period_credits\": 80095.74,\n            \"closing_balance\": -80095.74\n          }\n        ]\n      }\n    }\n  }\n}"}]},{"name":"Verify Closed Period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/verify","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","verify"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Drift check for a closed period: recomputes each snapshotted report live and diffs the totals against the snapshot with a $0.01 tolerance. Any difference means the closed month's numbers moved after close (for example via data repairs) and lists the changed figures. The reconciliation summary is informational — it legitimately changes as reconciliation work continues and never trips the period-level verdict.\n\nAuthentication: Bearer token.\n\nErrors: 422 when the period is not closed."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/verify","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","verify"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"verification\": {\n      \"period\": \"2026-06\",\n      \"has_drift\": false,\n      \"reports\": [\n        {\n          \"report_key\": \"trial_balance\",\n          \"label\": \"Trial Balance\",\n          \"matches\": true,\n          \"informational\": false,\n          \"is_stale\": false,\n          \"snapshot_generated_at\": \"2026-07-05T14:22:00+00:00\",\n          \"drift\": []\n        },\n        {\n          \"report_key\": \"reconciliation_summary\",\n          \"label\": \"Reconciliation Summary\",\n          \"matches\": false,\n          \"informational\": true,\n          \"is_stale\": false,\n          \"snapshot_generated_at\": \"2026-07-05T14:22:00+00:00\",\n          \"drift\": [\n            {\n              \"field\": \"provider_variance\",\n              \"snapshot\": 13891.46,\n              \"live\": 12100.02\n            }\n          ]\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Capture Provider Trial Balances","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/capture-provider-balances","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","capture-provider-balances"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Capture the accounting provider's trial balance as of the period end (period key format YYYY-MM), for every connected accounting integration. This is the one metered provider pull behind the Trial Balance Reconciliation report and the trial_balance_reconciled close check — both read only the cached snapshot this produces. Synchronous: one trial-balance call per connection; connections whose provider exposes no trial-balance report are skipped, not failed. Re-running re-captures in place so provider-side edits are picked up.\n\nAuthentication: Bearer token. Requires the accounting sync permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/capture-provider-balances","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","capture-provider-balances"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"captured\": 1,\n    \"unsupported\": 0\n  },\n  \"message\": \"1 provider trial balance captured. Re-check the close to reconcile.\"\n}"}]},{"name":"Sync Breakdown (why not synced)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/sync-breakdown","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","sync-breakdown"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"The why-not-synced breakdown. For the period (key format YYYY-MM), returns every journal entry that has NOT reached the accounting provider, grouped by reason (display status), with an entry count, a dollar total, and a per-reason deep-link filter that lands the entries list on exactly those rows. The synced total rides along as context (how much DID sync). Read-only and entirely local — no provider call.\n\nEach row's `disposition` is one of: `excluded` (unsynced by design), `in_flight` (queued/syncing/retrying), `needs_attention` (failed/conflict/removed-in-provider/needs-attention). `link` is a checklist-style deep link ({tab, filter}) for the entries list.\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/sync-breakdown","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","sync-breakdown"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"breakdown\": {\n      \"synced\": {\n        \"entry_count\": 128,\n        \"total\": 84250\n      },\n      \"rows\": [\n        {\n          \"entry_display_status\": \"excluded\",\n          \"label\": \"Disabled\",\n          \"disposition\": \"excluded\",\n          \"reason\": \"Excluded by design — not configured to sync to the provider.\",\n          \"entry_count\": 12,\n          \"total\": 3400,\n          \"link\": {\n            \"tab\": \"all\",\n            \"filter\": {\n              \"entry_display_status\": \"excluded\"\n            }\n          }\n        },\n        {\n          \"entry_display_status\": \"failed\",\n          \"label\": \"Failed\",\n          \"disposition\": \"needs_attention\",\n          \"reason\": \"Failed — the provider rejected the push.\",\n          \"entry_count\": 2,\n          \"total\": 560,\n          \"link\": {\n            \"tab\": \"all\",\n            \"filter\": {\n              \"entry_display_status\": \"failed\"\n            }\n          }\n        }\n      ],\n      \"totals\": {\n        \"unsynced_count\": 14,\n        \"unsynced_total\": 3960\n      }\n    }\n  }\n}"}]},{"name":"Export Close Pack","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/export","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","export"],"variable":[{"key":"period","value":"","description":"The period ID."}]},"description":"Generate the month-end close pack workbook (XLSX) as a background job: a cover sheet with the period's status, sign-off and checklist outcomes, plus one sheet per report of the pack. Closed periods export their frozen snapshots; open periods export live figures flagged PRELIMINARY. The finished file is delivered as a download from the job result.\n\nAuthentication: Bearer token. Requires the accounting sync permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ledger/close/periods/{period}/export","host":["{{baseUrl}}"],"path":["api","ledger","close","periods",":period","export"],"variable":[{"key":"period","value":"","description":"The period ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9312\n  },\n  \"message\": \"Close pack export started — the download will appear in the job tray.\"\n}"}]},{"name":"List Lock Date Exceptions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reports/lock-date-exceptions","host":["{{baseUrl}}"],"path":["api","ledger","reports","lock-date-exceptions"]},"description":"Paginated journal entries displaced out of a locked accounting period (booked on the first open day, source date on `original_effective_at`).\n\n**Filters:** type, source_type, original_from/original_to (m/d/Y). **Sort:** original_effective_at (default), effective_at, id, document_total. **Pagination:** page, per_page (default 15, max 100)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reports/lock-date-exceptions","host":["{{baseUrl}}"],"path":["api","ledger","reports","lock-date-exceptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8891,\n      \"type\": {\n        \"value\": \"customer_return\",\n        \"label\": \"Customer Return\"\n      },\n      \"status\": \"posted\",\n      \"effective_at\": \"2026-07-01T00:00:00+00:00\",\n      \"original_effective_at\": \"2026-05-12T00:00:00+00:00\",\n      \"posted_at\": \"2026-07-01T00:00:00+00:00\",\n      \"reference\": \"CR-1042/R1\",\n      \"document_total\": \"210.55\",\n      \"currency_code\": \"USD\",\n      \"display_status\": {\n        \"key\": \"synced\",\n        \"label\": \"Synced\",\n        \"color\": \"success\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Lock Date Exceptions Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ledger/reports/lock-date-exceptions/summary","host":["{{baseUrl}}"],"path":["api","ledger","reports","lock-date-exceptions","summary"]},"description":"Displaced-entry counts and net document-total impact grouped by entry type, plus grand totals. Honours the same original_from/original_to + type/source_type filters as the list."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ledger/reports/lock-date-exceptions/summary","host":["{{baseUrl}}"],"path":["api","ledger","reports","lock-date-exceptions","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"total_count\": 14,\n      \"total_amount\": \"3412.88\",\n      \"by_type\": [\n        {\n          \"type\": \"customer_return\",\n          \"type_label\": \"Customer Return\",\n          \"count\": 6,\n          \"amount\": \"-1204.10\"\n        },\n        {\n          \"type\": \"bill\",\n          \"type_label\": \"Bill\",\n          \"count\": 5,\n          \"amount\": \"4102.33\"\n        },\n        {\n          \"type\": \"fba_customer_returns\",\n          \"type_label\": \"FBA Customer Returns\",\n          \"count\": 3,\n          \"amount\": \"514.65\"\n        }\n      ]\n    }\n  }\n}"}]}]},{"name":"Inventory","item":[{"name":"Get Inventory Movement Tallies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-movements/tallies?product_id=42&warehouse_id=1&inventory_status=active","host":["{{baseUrl}}"],"path":["api","inventory-movements","tallies"],"query":[{"key":"product_id","value":"42","description":"(Required) Product ID to tally. 404 if not found.","disabled":true},{"key":"warehouse_id","value":"1","description":"(Required) Warehouse ID to tally within.","disabled":true},{"key":"inventory_status","value":"active","description":"(Required) Stock ledger to tally: active or in_transit.","disabled":true}]},"description":"Get running inventory tallies for a single product in a single warehouse. Returns a map keyed by inventory movement ID where each value is the cumulative on-hand quantity (running balance) after that movement was applied, computed in movement-date order (oldest first).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAll three query parameters are required:\n- `product_id` — the product to tally. Returns 404 if the product does not exist.\n- `warehouse_id` — the warehouse to tally within.\n- `inventory_status` — which stock ledger to tally: `active` (on-hand stock) or `in_transit` (stock moving between warehouses).\n\nUse this to reconstruct the balance history of a product at a warehouse, movement by movement.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-movements/tallies?product_id=42&warehouse_id=1&inventory_status=active","host":["{{baseUrl}}"],"path":["api","inventory-movements","tallies"],"query":[{"key":"product_id","value":"42","description":"(Required) Product ID to tally. 404 if not found.","disabled":true},{"key":"warehouse_id","value":"1","description":"(Required) Warehouse ID to tally within.","disabled":true},{"key":"inventory_status","value":"active","description":"(Required) Stock ledger to tally: active or in_transit.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"18234\": 100,\n    \"18240\": 88,\n    \"18255\": 63,\n    \"18291\": 113\n  }\n}"}]},{"name":"Get Inventory Movement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-movements/{inventoryMovement}","host":["{{baseUrl}}"],"path":["api","inventory-movements",":inventoryMovement"],"variable":[{"key":"inventoryMovement","value":"18234","description":"Inventory movement ID"}]},"description":"Get a single inventory movement with its product and warehouse details.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAn inventory movement is one immutable ledger entry: a positive quantity adds stock (purchase receipt, return, adjustment up, assembly output) and a negative quantity removes stock (sale, transfer out, adjustment down). Movement `type` values include: purchase_receipt, transfer, sale, adjustment, stock_take, assembly, return, purchase_return, reclassification, manufacturing_consumption, manufacturing_scrap, manufacturing_output. `inventory_status` is `active` (on-hand) or `in_transit` (between warehouses).\n\nThe `type` object also carries the polymorphic source document link (`link_type` + `link_id`) that created the movement, and `layer` identifies the FIFO cost layer the movement consumed or created.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-movements/{inventoryMovement}","host":["{{baseUrl}}"],"path":["api","inventory-movements",":inventoryMovement"],"variable":[{"key":"inventoryMovement","value":"18234","description":"Inventory movement ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 18234,\n    \"inventory_movement_date\": \"2026-05-12T14:30:00.000000Z\",\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"barcode\": 123456789012,\n    \"product_name\": \"Blue Widget\",\n    \"stock_uom_code\": \"EA\",\n    \"type\": {\n      \"name\": \"purchase_receipt\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceiptLine\",\n      \"link_id\": 5121,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"manufacturing_order\": null\n    },\n    \"inventory_status\": \"active\",\n    \"quantity\": 100,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"layer\": {\n      \"fifo_layer_id\": 3311,\n      \"name\": \"PO-1042\"\n    },\n    \"fifo_layer_id\": 3311,\n    \"reference\": \"PO-1042\",\n    \"created_at\": \"2026-05-12T14:30:05.000000Z\",\n    \"updated_at\": \"2026-05-12T14:30:05.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Inventory Movement Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-movements/{inventoryMovement}/activity-log","host":["{{baseUrl}}"],"path":["api","inventory-movements",":inventoryMovement","activity-log"],"variable":[{"key":"inventoryMovement","value":"18234","description":"Inventory movement ID"}]},"description":"Get the paginated change history (activity log) for an inventory movement, newest first. Each entry records what changed (`properties` holds the new and old attribute values plus the change source), the event type, and who made the change (`causer_name`).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFilters:\n- `filter[search]` — matches against the causing user's name, the event, the changed properties, and the subject type.\n- `filter[event]` — exact event match: created, updated, deleted, bulk_upsert.\n- `filter[source]` — matches the change source recorded in properties (e.g. manual, amazon_sync, inventory_allocation).\n- `filter[batch_uuid]` — all entries written by one bulk operation.\n\nPagination: `page` and `per_page` (default 15).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-movements/{inventoryMovement}/activity-log","host":["{{baseUrl}}"],"path":["api","inventory-movements",":inventoryMovement","activity-log"],"variable":[{"key":"inventoryMovement","value":"18234","description":"Inventory movement ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"InventoryMovement\",\n      \"subject_id\": 18234,\n      \"properties\": {\n        \"attributes\": {\n          \"quantity\": 100\n        },\n        \"old\": {\n          \"quantity\": 90\n        },\n        \"source\": \"manual\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-05-12T15:02:11.000000Z\"\n    },\n    {\n      \"id\": 90180,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"InventoryMovement\",\n      \"subject_id\": 18234,\n      \"properties\": {\n        \"attributes\": {\n          \"quantity\": 90,\n          \"inventory_status\": \"active\",\n          \"warehouse_id\": 1\n        },\n        \"source\": \"manual\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-05-12T14:30:05.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://sku3.test/api/inventory-movements/18234/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku3.test/api/inventory-movements/18234/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku3.test/api/inventory-movements/18234/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://sku3.test/api/inventory-movements/18234/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"List Forecast Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations"]},"description":"Lists all forecast configurations (no pagination). Each item includes a `schedules_count` field for the number of automation schedules referencing it.\nAuthentication: Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Weekly Sales History — Main Warehouse\",\n      \"description\": \"Standard 90-day sales history forecast for our primary warehouse.\",\n      \"supplier_ids\": [\n        5,\n        12\n      ],\n      \"forecast_type\": \"sales_history\",\n      \"target_quantity\": null,\n      \"use_min_stock_level_as_target\": false,\n      \"sales_history_days\": 90,\n      \"sales_start_date\": null,\n      \"sales_end_date\": null,\n      \"target_stock_days\": 30,\n      \"use_leadtime\": true,\n      \"use_measured_lead_time\": false,\n      \"use_moq\": true,\n      \"enforce_minimum_order_value\": false,\n      \"enforce_minimum_order_quantity\": false,\n      \"use_case_pack\": false,\n      \"case_pack_rounding\": null,\n      \"ignore_min_stock_level\": false,\n      \"rounding_method\": \"round_half_up\",\n      \"destination_warehouse_id\": 1,\n      \"pricing_tier_id\": null,\n      \"product_filters\": [],\n      \"sales_filters\": [],\n      \"demand_modifiers\": [],\n      \"schedules_count\": 2,\n      \"created_at\": \"2024-01-15T10:30:00Z\",\n      \"updated_at\": \"2024-01-15T10:30:00Z\"\n    }\n  ]\n}"}]},{"name":"Create Forecast Configuration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations"]},"description":"Creates a new forecast configuration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Required fields:**\n- `name` (string, max 255, unique among non-deleted configurations)\n- `supplier_ids` (array of integers, min 1, must exist in suppliers table)\n- `forecast_type` (enum: `with_sales_history`, `target_stock_level`, `fill_backorders`)\n- `target_stock_days` (integer 0-365) — required for `with_sales_history`. Optional for `target_stock_level` (allows 0 when `use_min_stock_level_as_target` is true) and `fill_backorders` (ignored)\n\n**Optional fields:**\n- `description` (string, max 1000)\n- `target_quantity` (integer, min 0) — fixed target quantity used by `target_stock_level` forecast type\n- `use_min_stock_level_as_target` (boolean) — when true, `target_stock_level` forecasts use each product's minimum stock level as the target instead of a fixed `target_quantity`. Persisted on both create and update.\n- `sales_history_days` (integer 1-365) — used by `with_sales_history` forecast type\n- `sales_start_date` / `sales_end_date` (Y-m-d) — alternative date range for sales history\n- `use_leadtime` (boolean)\n- `use_moq` (boolean)\n- `enforce_minimum_order_value` (boolean) — enforces supplier minimum order value when generating POs\n- `enforce_minimum_order_quantity` (boolean) — enforces supplier minimum order quantity when generating POs\n- `use_case_pack` (boolean) — round order quantities to supplier case-pack multiples\n- `case_pack_rounding` (enum: `always_round_up`, `always_round_down`, `round_nearest`) — how to round to the case-pack multiple\n- `ignore_min_stock_level` (boolean) — skip the per-product minimum stock level constraint when computing demand\n- `rounding_method` (enum: `round_half_up`, `round_half_down`, `always_round_up`, `always_round_down`, `no_rounding`)\n- `destination_warehouse_id` (integer, must exist in warehouses table)\n- `pricing_tier_id` (integer, must exist in supplier_pricing_tiers table)\n- `product_filters` (array) — filter criteria applied to candidate products\n- `sales_filters` (array) — filter criteria applied to sales history\n- `demand_modifiers` (array) — adjustments to projected demand\n\nAuthentication: Requires Bearer token.\n\n**Baseline decomposition fields (persist onto the saved configuration and drive scheduled runs):**\n- `baseline_method` (enum: `flat` default, `recency_weighted`, `damped_trend`) — how the daily velocity baseline is derived from sales history.\n- `trend_damping_factor` (number 0..1, default 0.85) — damping factor phi for `damped_trend`; lower = more damping.\n- `trend_max_growth_pct` (number >= 0, default 100) — caps how far the trend may lift the baseline above the flat mean (100 = may at most double it). When the cap binds a line reports `trend_capped: true`.\n- `trend_half_life_days` (integer >= 1, nullable, default 21) — reserved tuning for `recency_weighted`.\n- `exclude_detected_anomalies` (boolean, default false) — when true, days resolved as excluded or smoothed anomalies are dropped/replaced before the baseline is computed, de-contaminating promo spikes and stockout gaps.\n\nThese persist onto the configuration, so a schedule attached to it re-applies the same trend and anomaly-cleansing settings on every run. Baseline settings are ignored for `fill_backorders`.","body":{"mode":"raw","raw":"{\n  \"name\": \"Min Stock Replenishment — Main Warehouse\",\n  \"description\": \"Target stock level forecast using each product's minimum stock level as the target quantity.\",\n  \"supplier_ids\": [\n    5,\n    12\n  ],\n  \"forecast_type\": \"target_stock_level\",\n  \"target_quantity\": null,\n  \"use_min_stock_level_as_target\": true,\n  \"sales_history_days\": null,\n  \"sales_start_date\": null,\n  \"sales_end_date\": null,\n  \"target_stock_days\": 0,\n  \"use_leadtime\": true,\n  \"use_measured_lead_time\": false,\n  \"use_moq\": true,\n  \"enforce_minimum_order_value\": false,\n  \"enforce_minimum_order_quantity\": false,\n  \"use_case_pack\": true,\n  \"case_pack_rounding\": \"always_round_up\",\n  \"ignore_min_stock_level\": false,\n  \"rounding_method\": \"always_round_up\",\n  \"destination_warehouse_id\": 1,\n  \"pricing_tier_id\": null,\n  \"product_filters\": [],\n  \"sales_filters\": [],\n  \"demand_modifiers\": [],\n  \"baseline_method\": \"damped_trend\",\n  \"trend_damping_factor\": 0.85,\n  \"trend_max_growth_pct\": 100,\n  \"trend_half_life_days\": 21,\n  \"exclude_detected_anomalies\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Weekly Sales History — Main Warehouse\",\n    \"description\": \"Standard 90-day sales history forecast for our primary warehouse.\",\n    \"supplier_ids\": [\n      5,\n      12\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_quantity\": null,\n    \"use_min_stock_level_as_target\": false,\n    \"sales_history_days\": 90,\n    \"sales_start_date\": null,\n    \"sales_end_date\": null,\n    \"target_stock_days\": 30,\n    \"use_leadtime\": true,\n    \"use_measured_lead_time\": false,\n    \"use_moq\": true,\n    \"enforce_minimum_order_value\": false,\n    \"enforce_minimum_order_quantity\": false,\n    \"use_case_pack\": false,\n    \"case_pack_rounding\": null,\n    \"ignore_min_stock_level\": false,\n    \"rounding_method\": \"round_half_up\",\n    \"destination_warehouse_id\": 1,\n    \"pricing_tier_id\": null,\n    \"product_filters\": [],\n    \"sales_filters\": [],\n    \"demand_modifiers\": [],\n    \"created_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"created_at\": \"2024-01-15T10:30:00Z\",\n    \"updated_at\": \"2024-01-15T10:30:00Z\"\n  }\n}"}]},{"name":"List Forecast Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/paginated?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","paginated"],"query":[{"key":"page","value":"1","description":"Page number. Defaults to 1.","disabled":true},{"key":"per_page","value":"10","description":"Items per page. Defaults to 10.","disabled":true}]},"description":"Returns paginated forecast configurations.\nAuthentication: Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/paginated?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","paginated"],"query":[{"key":"page","value":"1","description":"Page number. Defaults to 1.","disabled":true},{"key":"per_page","value":"10","description":"Items per page. Defaults to 10.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Weekly Sales History — Main Warehouse\",\n      \"description\": \"Standard 90-day sales history forecast.\",\n      \"supplier_ids\": [\n        5,\n        12\n      ],\n      \"forecast_type\": \"sales_history\",\n      \"target_quantity\": null,\n      \"use_min_stock_level_as_target\": false,\n      \"sales_history_days\": 90,\n      \"sales_start_date\": null,\n      \"sales_end_date\": null,\n      \"target_stock_days\": 30,\n      \"use_leadtime\": true,\n      \"use_measured_lead_time\": false,\n      \"use_moq\": true,\n      \"enforce_minimum_order_value\": false,\n      \"enforce_minimum_order_quantity\": false,\n      \"use_case_pack\": false,\n      \"case_pack_rounding\": null,\n      \"ignore_min_stock_level\": false,\n      \"rounding_method\": \"round_half_up\",\n      \"destination_warehouse_id\": 1,\n      \"pricing_tier_id\": null,\n      \"product_filters\": [],\n      \"sales_filters\": [],\n      \"demand_modifiers\": [],\n      \"schedules_count\": 2,\n      \"created_at\": \"2024-01-15T10:30:00Z\",\n      \"updated_at\": \"2024-01-15T10:30:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 25,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Forecast Configuration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]},"description":"Returns a single forecast configuration with `created_by`, `updated_by`, and `pricing_tier` relationships eager-loaded, plus the `schedules_count` of automation schedules referencing it.\nAuthentication: Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Weekly Sales History — Main Warehouse\",\n    \"description\": \"Standard 90-day sales history forecast.\",\n    \"supplier_ids\": [\n      5,\n      12\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_quantity\": null,\n    \"use_min_stock_level_as_target\": false,\n    \"sales_history_days\": 90,\n    \"sales_start_date\": null,\n    \"sales_end_date\": null,\n    \"target_stock_days\": 30,\n    \"use_leadtime\": true,\n    \"use_measured_lead_time\": false,\n    \"use_moq\": true,\n    \"enforce_minimum_order_value\": true,\n    \"enforce_minimum_order_quantity\": true,\n    \"use_case_pack\": false,\n    \"case_pack_rounding\": null,\n    \"ignore_min_stock_level\": false,\n    \"rounding_method\": \"round_half_up\",\n    \"destination_warehouse_id\": 1,\n    \"pricing_tier_id\": null,\n    \"product_filters\": [],\n    \"sales_filters\": [],\n    \"demand_modifiers\": [],\n    \"created_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"updated_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"schedules_count\": 2,\n    \"created_at\": \"2024-01-15T10:30:00Z\",\n    \"updated_at\": \"2024-01-15T10:30:00Z\"\n  }\n}"}]},{"name":"Update Forecast Configuration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]},"description":"Updates an existing forecast configuration. All fields use `sometimes` validation — only send the fields you want to change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe controller merges the incoming payload over the existing configuration data via `ForecastConfigurationData::fromModel($configuration)`, so omitted fields retain their current values. **Any field you want to change must be present in the validation rules — otherwise `validated()` strips it and the merge silently reverts it to the stored value.**\n\nAccepts the same fields as Create, including `use_min_stock_level_as_target`, `use_case_pack`, `case_pack_rounding`, and `ignore_min_stock_level`. The `name` uniqueness rule excludes the current record (so unchanged names pass validation).\n\nAuthentication: Requires Bearer token.\n\n**Baseline decomposition fields** (`baseline_method`, `trend_damping_factor`, `trend_max_growth_pct`, `trend_half_life_days`, `exclude_detected_anomalies`) persist onto the configuration and can be changed here; the new values apply to the next on-demand build and to any schedule attached to this configuration. `baseline_method` is `flat` (default), `recency_weighted`, or `damped_trend`; `trend_damping_factor` (0..1, default 0.85) is the damping factor phi (lower = more damping); `trend_max_growth_pct` (>= 0, default 100) caps the trend lift above the flat mean; `trend_half_life_days` (>= 1, nullable, default 21) tunes `recency_weighted`; `exclude_detected_anomalies` (default false) drops/replaces resolved anomaly days before the baseline is computed. Baseline settings are ignored for `fill_backorders`.","body":{"mode":"raw","raw":"{\n  \"name\": \"Min Stock Replenishment — Main Warehouse (v2)\",\n  \"forecast_type\": \"target_stock_level\",\n  \"use_min_stock_level_as_target\": true,\n  \"use_case_pack\": true,\n  \"case_pack_rounding\": \"always_round_up\",\n  \"ignore_min_stock_level\": false,\n  \"baseline_method\": \"damped_trend\",\n  \"trend_damping_factor\": 0.8,\n  \"trend_max_growth_pct\": 75,\n  \"trend_half_life_days\": 28,\n  \"exclude_detected_anomalies\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Weekly Sales History — Main Warehouse (v2)\",\n    \"description\": \"Updated to enforce supplier minimums.\",\n    \"supplier_ids\": [\n      5,\n      12\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_quantity\": null,\n    \"use_min_stock_level_as_target\": false,\n    \"sales_history_days\": 90,\n    \"sales_start_date\": null,\n    \"sales_end_date\": null,\n    \"target_stock_days\": 45,\n    \"use_leadtime\": true,\n    \"use_measured_lead_time\": false,\n    \"use_moq\": true,\n    \"enforce_minimum_order_value\": true,\n    \"enforce_minimum_order_quantity\": true,\n    \"use_case_pack\": false,\n    \"case_pack_rounding\": null,\n    \"ignore_min_stock_level\": false,\n    \"rounding_method\": \"round_half_up\",\n    \"destination_warehouse_id\": 1,\n    \"pricing_tier_id\": null,\n    \"product_filters\": [],\n    \"sales_filters\": [],\n    \"demand_modifiers\": [],\n    \"created_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"updated_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"created_at\": \"2024-01-15T10:30:00Z\",\n    \"updated_at\": \"2024-01-20T14:22:00Z\"\n  }\n}"}]},{"name":"Delete Forecast Configuration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]},"description":"Soft-deletes a forecast configuration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf the configuration is in use by any automation schedule, returns 422 unless `force=true` is passed.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Duplicate Forecast Configuration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/duplicate","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","duplicate"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID to duplicate."}]},"description":"Creates a copy of an existing forecast configuration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Optional body field:**\n- `name` (string, max 255) — name for the new copy. If omitted, defaults to `\"<Original Name> (Copy)\"`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Weekly Sales History — Copy\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/duplicate","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","duplicate"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID to duplicate."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"name\": \"Weekly Sales History — Copy\",\n    \"description\": \"Standard 90-day sales history forecast.\",\n    \"supplier_ids\": [\n      5,\n      12\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_quantity\": null,\n    \"use_min_stock_level_as_target\": false,\n    \"sales_history_days\": 90,\n    \"sales_start_date\": null,\n    \"sales_end_date\": null,\n    \"target_stock_days\": 30,\n    \"use_leadtime\": true,\n    \"use_measured_lead_time\": false,\n    \"use_moq\": true,\n    \"enforce_minimum_order_value\": false,\n    \"enforce_minimum_order_quantity\": false,\n    \"use_case_pack\": false,\n    \"case_pack_rounding\": null,\n    \"ignore_min_stock_level\": false,\n    \"rounding_method\": \"round_half_up\",\n    \"destination_warehouse_id\": 1,\n    \"pricing_tier_id\": null,\n    \"product_filters\": [],\n    \"sales_filters\": [],\n    \"demand_modifiers\": [],\n    \"created_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Doe\"\n    },\n    \"created_at\": \"2024-01-20T14:22:00Z\",\n    \"updated_at\": \"2024-01-20T14:22:00Z\"\n  }\n}"}]},{"name":"Check Forecast Configuration Usage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/usage","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","usage"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]},"description":"Returns whether the configuration is referenced by any automation schedules and the count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUse this before showing a delete confirmation in the UI.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/usage","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","usage"],"variable":[{"key":"configuration","value":"1","description":"Forecast configuration ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"in_use\": true,\n    \"schedules_count\": 2\n  }\n}"}]},{"name":"Get Fulfillment Debt Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}]},"description":"Returns a paginated list of fulfillment debt lines — sales order lines where fulfilled quantity is less than what was originally ordered.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 500,\n      \"sales_order_id\": 12,\n      \"order_number\": \"SO-2024-0042\",\n      \"order_date\": \"2024-01-10T00:00:00Z\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"partial\",\n      \"integration_instance_name\": \"Shopify Store\",\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"product_title\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"line_quantity\": 10,\n      \"canceled_quantity\": 0,\n      \"externally_fulfilled_quantity\": 0,\n      \"processable_quantity\": 10,\n      \"fulfilled_quantity\": 6,\n      \"allocated_quantity\": 4,\n      \"reserved_quantity\": 4,\n      \"debt_quantity\": 4,\n      \"created_at\": \"2024-01-10T08:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 25,\n  \"total\": 38\n}"}]},{"name":"Get Fulfillment Debt Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report/summary","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report","summary"]},"description":"Returns aggregated summary totals for the fulfillment debt report header cards.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report/summary","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_debt_quantity\": 142,\n    \"affected_orders\": 38,\n    \"affected_products\": 25,\n    \"total_debt_value\": 5230\n  }\n}"}]},{"name":"Create Catch-Up Stock Takes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report/create-stock-take","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report","create-stock-take"]},"description":"Creates adjustment stock takes in DRAFT status to catch up fulfillment debt.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- warehouse_id (nullable): Specific warehouse to create stock takes for. If omitted, creates for all warehouses.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory/fulfillment-debt-report/create-stock-take","host":["{{baseUrl}}"],"path":["api","inventory","fulfillment-debt-report","create-stock-take"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"stock_takes\": [\n      {\n        \"id\": 55,\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"item_count\": 12,\n        \"status\": \"draft\"\n      }\n    ],\n    \"message\": \"1 adjustment stock take(s) created in DRAFT status. Review and finalize to apply.\"\n  }\n}"}]},{"name":"List Inventory Holds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]},"description":"Returns paginated inventory holds (reservations). By default shows active holds (not released, not expired).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus filter (resolved from filter_groups, filter[status], or top-level status param):\n- active: Not released and not expired (default)\n- partially_released: Has released_quantity > 0 but not fully released yet\n- released: Fully released holds\n- expired: Expired holds\n- expiring_soon: Expiring within the next 7 days\n- all: All holds regardless of status\n\nAvailable sorts: id, quantity, released_quantity, created_at, expires_at, released_at (default: -created_at)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"product_id\": 42,\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"quantity\": 50,\n      \"released_quantity\": 0,\n      \"reason\": \"quality_hold\",\n      \"reason_label\": \"Quality Hold\",\n      \"notes\": \"Pending QA inspection\",\n      \"expires_at\": \"2024-02-01T00:00:00.000000Z\",\n      \"released_at\": null,\n      \"released_by\": null,\n      \"release_reason\": null,\n      \"created_by\": {\n        \"id\": 5,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Inventory Hold","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds"]},"description":"Creates a single inventory hold (reservation) for a product in a specific warehouse. Deducts from available inventory.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- product_id (required, integer): Product to hold\n- warehouse_id (required, integer): Warehouse where inventory is held\n- quantity (required, numeric, min 0.0001): Quantity to hold\n- reason (required, string, max 255): Reason for the hold\n- notes (optional, string): Additional notes\n- expires_at (optional, date, must be future): Expiration date for the hold\n\n**Requires permission:** `inventory.adjust`\n\n`notes` is **required** when `reason` is `other`; optional otherwise.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"warehouse_id\": 1,\n  \"quantity\": 50,\n  \"reason\": \"quality_hold\",\n  \"notes\": \"Pending QA inspection\",\n  \"expires_at\": \"2024-02-01T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"product_id\": 42,\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\"\n    },\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"quantity\": 50,\n    \"released_quantity\": 0,\n    \"reason\": \"quality_hold\",\n    \"reason_label\": \"Quality Hold\",\n    \"notes\": \"Pending QA inspection\",\n    \"expires_at\": \"2024-02-01T00:00:00.000000Z\",\n    \"released_at\": null,\n    \"created_by\": {\n      \"id\": 5,\n      \"name\": \"Jane Smith\"\n    },\n    \"created_at\": \"2024-01-20T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-20T10:00:00.000000Z\"\n  },\n  \"message\": \"Inventory reservation created successfully.\"\n}"}]},{"name":"Bulk Create Inventory Holds","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk"]},"description":"Creates inventory holds for multiple products in the same warehouse in a single request. Up to 100 items per request.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- warehouse_id (required, integer): Warehouse where all items are held\n- reason (required, string, max 255): Reason applied to all holds\n- notes (optional, string): Notes applied to all holds\n- expires_at (optional, date, must be future): Expiration applied to all holds\n- items (required, array, 1-100): Array of items to hold\n  - items.*.product_id (required, integer): Product ID\n  - items.*.quantity (required, numeric, min 0.0001): Quantity to hold\n\n**Requires permission:** `inventory.adjust`\n\n`notes` is **required** when `reason` is `other`; optional otherwise.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"reason\": \"quality_hold\",\n  \"notes\": \"Batch QA hold\",\n  \"expires_at\": \"2024-03-01T00:00:00Z\",\n  \"items\": [\n    {\n      \"product_id\": 42,\n      \"quantity\": 10\n    },\n    {\n      \"product_id\": 43,\n      \"quantity\": 5\n    },\n    {\n      \"product_id\": 44,\n      \"quantity\": 20\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 6,\n      \"product_id\": 42,\n      \"warehouse_id\": 1,\n      \"quantity\": 10,\n      \"reason\": \"quality_hold\",\n      \"created_at\": \"2024-01-20T10:00:00.000000Z\"\n    }\n  ],\n  \"errors\": [],\n  \"message\": \"1 reservation(s) created.\"\n}"}]},{"name":"Get Inventory Hold","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]},"description":"Returns a single inventory hold with full product, warehouse, creator, and releaser details.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\"\n    },\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"quantity\": 30,\n    \"released_quantity\": 20,\n    \"reason\": \"quality_hold\",\n    \"reason_label\": \"Quality Hold\",\n    \"notes\": \"Pending QA inspection\",\n    \"expires_at\": \"2024-02-01T00:00:00.000000Z\",\n    \"released_at\": null,\n    \"released_by\": null,\n    \"release_reason\": null,\n    \"created_by\": {\n      \"id\": 5,\n      \"name\": \"Jane Smith\"\n    },\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Inventory Hold","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]},"description":"Updates an inventory hold's quantity, notes, or expiration date.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- quantity (sometimes, numeric, min 0.0001): New quantity\n- notes (nullable, string): Updated notes\n- expires_at (nullable, date, must be future): New expiration date\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"quantity\": 30,\n  \"notes\": \"Updated notes\",\n  \"expires_at\": \"2024-03-01T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"quantity\": 30,\n    \"reason\": \"quality_hold\",\n    \"notes\": \"Updated notes\"\n  },\n  \"message\": \"Inventory reservation updated successfully.\"\n}"}]},{"name":"Delete Inventory Hold","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]},"description":"Permanently deletes an inventory hold and returns the quantity to available inventory.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Release Inventory Hold","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}/release","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation","release"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]},"description":"Releases inventory from a hold. Supports both partial and full release.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nPartial release (quantity provided AND less than current held quantity):\n- The hold's `quantity` is reduced by the released amount\n- `released_quantity` accumulates the cumulative total released across all release events\n- `released_at` remains null — the hold is still active\n\nFull release (quantity omitted, null, 0, or equal to current held quantity):\n- `released_at`, `released_by`, and `release_reason` are populated\n- The remaining `quantity` is added to `released_quantity` so it reflects the cumulative total released\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- quantity (nullable, numeric, min 0.0001, max=current held quantity): Quantity to release. Omit, send null, or send 0 to fully release. Cannot exceed the current held quantity (returns 422)\n- release_reason (nullable, string, max 500): Reason for the release\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"quantity\": 20,\n  \"release_reason\": \"QA inspection passed for partial batch\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/{reservation}/release","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds",":reservation","release"],"variable":[{"key":"reservation","value":"1","description":"Inventory hold ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"quantity\": 30,\n    \"released_quantity\": 20,\n    \"released_at\": null,\n    \"released_by\": null,\n    \"release_reason\": \"QA passed for partial batch\"\n  },\n  \"message\": \"Inventory reservation released successfully.\"\n}"}]},{"name":"Bulk Release Inventory Holds","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk-release","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk-release"]},"description":"Releases multiple inventory holds at once.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (required, array): Array of inventory hold IDs to release\n- ids.* (integer): Must exist in inventory_holds table\n- release_reason (nullable, string, max 500): Reason applied to all released holds\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"release_reason\": \"Batch QA pass\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk-release","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk-release"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 hold(s) released successfully.\",\n  \"released\": 3,\n  \"skipped\": 0\n}"}]},{"name":"Bulk Delete Inventory Holds","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk-delete","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk-delete"]},"description":"Permanently deletes multiple inventory holds.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (required, array): Array of inventory hold IDs to delete\n- ids.* (integer): Must exist in inventory_holds table\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4,\n    5,\n    6\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/bulk-delete","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 hold(s) deleted successfully.\",\n  \"deleted\": 2\n}"}]},{"name":"Export Inventory Holds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/export?format=xlsx&scope=filtered","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default) or selected","disabled":true}]},"description":"Exports inventory holds as XLSX or CSV file. Columns include: ID, SKU, Product Name, Warehouse, Quantity, Reason, Notes, Created By, Created At, Expires At, Released At, Archived At.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: File download (binary), not JSON.\n\n**Requires permission:** `inventory.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/export?format=xlsx&scope=filtered","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default) or selected","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[Binary XLSX file download]"}]},{"name":"Get Hold Reasons","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/reasons","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","reasons"]},"description":"Returns all distinct non-null reasons used across inventory holds, sorted alphabetically. Useful for populating filter dropdowns.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/reasons","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","reasons"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"damaged\",\n    \"other\",\n    \"quality_hold\",\n    \"reserved_for_event\"\n  ]\n}"}]},{"name":"Get Holds Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/summary","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","summary"]},"description":"Returns aggregated summary statistics for inventory holds.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/summary","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_active\": 24,\n    \"total_quantity_held\": 1250,\n    \"expiring_soon\": 3,\n    \"expired\": 1\n  }\n}"}]},{"name":"Check Warehouse Availability","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/warehouse-availability","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","warehouse-availability"]},"description":"Returns the available inventory for a batch of products in a specific warehouse. Used by the Reserve Stock modal browse drawer.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- product_ids (required, array, max 100): Product IDs to check availability for\n- product_ids.* (integer): Product ID\n- warehouse_id (required, integer): Warehouse to check availability in","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    42,\n    43,\n    44\n  ],\n  \"warehouse_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory/holds/warehouse-availability","host":["{{baseUrl}}"],"path":["api","v2","inventory","holds","warehouse-availability"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"42\": {\n      \"available\": 150\n    },\n    \"43\": {\n      \"available\": 0\n    }\n  }\n}"}]},{"name":"List Location Quantities","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/location-quantities?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","inventory","location-quantities"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10, max: 100)","disabled":true}]},"description":"Paginated per-(product, warehouse, location) on-hand balances from the incrementally-maintained inventory_location_quantities cache (stock by location).\n\nAuthentication: Requires Bearer token.\nScope: inventory (read/write).\nRequires the tenant to have warehouse locations enabled.\n\nFilters (Spatie QueryBuilder `filter[...]`):\n- warehouse_id (exact)\n- warehouse_location_id (exact)\n- product_id (exact)\n- location_type (exact or comma-separated; one of: staging, primary_pick, reserve, storage, shipping, returns, quarantine, damaged)\n- search (product sku/name + location code)\n\nAvailable sorts: id, quantity, product_id, warehouse_id, warehouse_location_id, updated_at (default: -quantity).\nper_page is clamped to a max of 100 (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/location-quantities?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","inventory","location-quantities"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10, max: 100)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"location\": {\n        \"id\": 12,\n        \"code\": \"A1-B2-S3-BIN4\",\n        \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\"\n      },\n      \"quantity\": 42\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Export Location Quantities","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory/location-quantities/export?filter[warehouse_id]=1","host":["{{baseUrl}}"],"path":["api","v2","inventory","location-quantities","export"],"query":[{"key":"filter[warehouse_id]","value":"1","description":"Warehouse ID to export. Required unless filter[product_id] is supplied — the export must be scoped to a warehouse or a product.","disabled":true}]},"description":"Export the filtered per-location balances as a CSV or XLSX file download (columns: SKU, Product Name, Warehouse, Location Code, Location Name, Location Type, Quantity). Applies the same filter pipeline as the index endpoint. Returns a binary file, NOT JSON.\n\nThe export must be scoped to a warehouse or a product: supply filter[warehouse_id] or filter[product_id] (either one satisfies the requirement). A request with neither returns 422 Unprocessable Entity.\n\nAuthentication: Requires Bearer token.\nScope: inventory (read/write).\nAdditional permission required: `inventory.export`.\n\nQuery params:\n- filter[warehouse_id] (required unless filter[product_id] given)\n- filter[product_id] (required unless filter[warehouse_id] given)\n- format (optional: csv | xlsx, default csv)\n- plus any other filter[...] accepted by the index endpoint\n\n**Requires permission:** `inventory.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory/location-quantities/export?filter[warehouse_id]=1","host":["{{baseUrl}}"],"path":["api","v2","inventory","location-quantities","export"],"query":[{"key":"filter[warehouse_id]","value":"1","description":"Warehouse ID to export. Required unless filter[product_id] is supplied — the export must be scoped to a warehouse or a product.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[Binary CSV file download: location-quantities-YYYY-MM-DD-HH-mm-ss.csv]"}]}]},{"name":"Discount Codes","item":[{"name":"List Discount Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/discount-codes","host":["{{baseUrl}}"],"path":["api","discount-codes"]},"description":"List all discount codes. Uses standard list query parameters supporting search, sort, and pagination.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nAllowed sorts: code, type, scope, is_active, created_at, updated_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/discount-codes","host":["{{baseUrl}}"],"path":["api","discount-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"SUMMER10\",\n      \"description\": \"10% off for summer sale\",\n      \"type\": \"percentage\",\n      \"rate\": 10,\n      \"amount\": null,\n      \"scope\": \"order\",\n      \"apply_before_tax\": false,\n      \"is_active\": true,\n      \"created_at\": \"2024-06-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T00:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"code\": \"FLAT5\",\n      \"description\": \"$5 off any order\",\n      \"type\": \"fixed_amount\",\n      \"rate\": null,\n      \"amount\": 5,\n      \"scope\": \"order\",\n      \"apply_before_tax\": true,\n      \"is_active\": true,\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ],\n  \"total\": 2,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Create Discount Code","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/discount-codes","host":["{{baseUrl}}"],"path":["api","discount-codes"]},"description":"Create a new discount code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- code (required): Unique discount code string (max 255 chars)\n- description (optional): Description of the discount (max 500 chars)\n- type (required): Discount value type. One of: percentage, fixed_amount\n- rate (optional): Percentage rate (0–100). Used when type is 'percentage'\n- amount (optional): Fixed amount. Used when type is 'fixed_amount'\n- scope (required): What the discount applies to. One of: line, order, both\n- apply_before_tax (optional): Whether discount is applied before tax calculation\n- is_active (optional): Whether the code is active\n\n**Requires permission:** `discount_codes.create`","body":{"mode":"raw","raw":"{\n  \"code\": \"SUMMER10\",\n  \"description\": \"10% off for summer sale\",\n  \"type\": \"percentage\",\n  \"rate\": 10,\n  \"amount\": null,\n  \"scope\": \"order\",\n  \"apply_before_tax\": false,\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/discount-codes","host":["{{baseUrl}}"],"path":["api","discount-codes"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"code\": \"SUMMER10\",\n    \"description\": \"10% off for summer sale\",\n    \"type\": \"percentage\",\n    \"rate\": 10,\n    \"amount\": null,\n    \"scope\": \"order\",\n    \"apply_before_tax\": false,\n    \"is_active\": true,\n    \"created_at\": \"2024-06-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T00:00:00.000000Z\"\n  },\n  \"message\": \"discount code created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Discount Code","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]},"description":"Retrieve a single discount code by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"code\": \"SUMMER10\",\n    \"description\": \"10% off for summer sale\",\n    \"type\": \"percentage\",\n    \"rate\": 10,\n    \"amount\": null,\n    \"scope\": \"order\",\n    \"apply_before_tax\": false,\n    \"is_active\": true,\n    \"created_at\": \"2024-06-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T00:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Discount Code","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]},"description":"Update an existing discount code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nSame fields as create. Unique code validation ignores the current record.\n\n**Requires permission:** `discount_codes.update`","body":{"mode":"raw","raw":"{\n  \"code\": \"SUMMER15\",\n  \"description\": \"15% off for summer sale\",\n  \"type\": \"percentage\",\n  \"rate\": 15,\n  \"scope\": \"order\",\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"code\": \"SUMMER15\",\n    \"description\": \"15% off for summer sale\",\n    \"type\": \"percentage\",\n    \"rate\": 15,\n    \"amount\": null,\n    \"scope\": \"order\",\n    \"apply_before_tax\": false,\n    \"is_active\": true,\n    \"created_at\": \"2024-06-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-06-15T00:00:00.000000Z\"\n  },\n  \"message\": \"discount code SUMMER15 updated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Discount Code","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]},"description":"Soft-delete a discount code. Soft-deleted codes are excluded from the unique code constraint for future codes with the same name.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `discount_codes.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/discount-codes/{discountCode}","host":["{{baseUrl}}"],"path":["api","discount-codes",":discountCode"],"variable":[{"key":"discountCode","value":"","description":"The discountCode identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"discount code SUMMER10 deleted successfully.\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Custom Fields","item":[{"name":"List Custom Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/custom-fields?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","custom-fields"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]},"description":"Returns a paginated list of custom fields. Custom fields can be attached to different entity types (link_type).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- page — Page number (default: 1)\n- limit — Results per page (default: 15)\n- search — Full-text search by name\n- sort — Sort field, prefix with - for descending\n- archived — 0 = active, 1 = archived (soft-deleted)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/custom-fields?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","custom-fields"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Purchase Order Notes\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Supplier Rating\",\n      \"link_type\": \"App\\\\Models\\\\Supplier\",\n      \"archived_at\": null,\n      \"created_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"updated_at\": \"2024-02-01T09:00:00.000000Z\"\n    }\n  ],\n  \"total\": 12,\n  \"per_page\": 15,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Create Custom Field","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/custom-fields","host":["{{baseUrl}}"],"path":["api","custom-fields"]},"description":"Creates a new custom field definition. Custom fields are then attached to records via the custom-field-values API.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required) — Display name of the custom field. Must be unique within the same link_type.\n- link_type (required) — Fully qualified model class name the field applies to (e.g., App\\Models\\PurchaseOrder)\n\nUniqueness: The (name, link_type) combination must be unique. Attempting to create a duplicate returns 422 with a friendly error message instead of a 500.","body":{"mode":"raw","raw":"{\n  \"name\": \"Internal Reference\",\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/custom-fields","host":["{{baseUrl}}"],"path":["api","custom-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 3,\n  \"name\": \"Internal Reference\",\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"archived_at\": null,\n  \"created_at\": \"2024-06-01T09:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T09:00:00.000000Z\"\n}"}]},{"name":"Get Custom Field","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]},"description":"Returns a single custom field by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Purchase Order Notes\",\n    \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Custom Field","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]},"description":"Updates an existing custom field. All fields are optional.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields (all optional):\n- name (optional) — Display name of the custom field. Must be unique within the same link_type (the record's own existing name is allowed).\n- link_type (optional) — Fully qualified model class name\n- archived_at (optional, nullable, date) — Set to a date to archive, null to unarchive\n\nUniqueness: The (name, link_type) combination must be unique. Renaming to a name that already exists for the same link_type returns 422 with a friendly error message instead of a 500.","body":{"mode":"raw","raw":"{\n  \"name\": \"Purchase Order Internal Notes\",\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"archived_at\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"name\": \"Purchase Order Internal Notes\",\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"archived_at\": null,\n  \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T11:00:00.000000Z\"\n}"}]},{"name":"Delete Custom Field","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]},"description":"Deletes a custom field definition by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/custom-fields/{customField}","host":["{{baseUrl}}"],"path":["api","custom-fields",":customField"],"variable":[{"key":"customField","value":"","description":"The customField identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"customField Purchase Order Notes was successfully deleted\"\n}"}]},{"name":"List Custom Field Values","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/custom-field-values","host":["{{baseUrl}}"],"path":["api","custom-field-values"]},"description":"Returns all custom field values. Each value links a custom field definition to a specific record (link_type + link_id).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/custom-field-values","host":["{{baseUrl}}"],"path":["api","custom-field-values"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 1,\n    \"custom_field_id\": 1,\n    \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"link_id\": 45,\n    \"value\": \"Please ship with fragile label\",\n    \"created_at\": \"2024-03-10T14:00:00.000000Z\",\n    \"updated_at\": \"2024-03-10T14:00:00.000000Z\"\n  },\n  {\n    \"id\": 2,\n    \"custom_field_id\": 2,\n    \"link_type\": \"App\\\\Models\\\\Supplier\",\n    \"link_id\": 12,\n    \"value\": \"5 stars\",\n    \"created_at\": \"2024-04-01T09:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T09:00:00.000000Z\"\n  }\n]"}]},{"name":"Create Custom Field Value","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/custom-field-values","host":["{{baseUrl}}"],"path":["api","custom-field-values"]},"description":"Creates a new custom field value, attaching a custom field to a specific record. The link_type is automatically inferred from the custom field definition.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- custom_field_id (required, integer, exists:custom_fields,id) — ID of the custom field definition\n- link_id (required, integer) — ID of the record to attach the value to\n- value (required) — The value to store","body":{"mode":"raw","raw":"{\n  \"custom_field_id\": 1,\n  \"link_id\": 45,\n  \"value\": \"Please ship with fragile label\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/custom-field-values","host":["{{baseUrl}}"],"path":["api","custom-field-values"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 3,\n  \"custom_field_id\": 1,\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"link_id\": 45,\n  \"value\": \"Please ship with fragile label\",\n  \"created_at\": \"2024-06-01T10:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T10:00:00.000000Z\"\n}"}]},{"name":"Get Custom Field Value","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]},"description":"Returns a single custom field value by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"custom_field_id\": 1,\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"link_id\": 45,\n  \"value\": \"Please ship with fragile label\",\n  \"created_at\": \"2024-03-10T14:00:00.000000Z\",\n  \"updated_at\": \"2024-03-10T14:00:00.000000Z\"\n}"}]},{"name":"Update Custom Field Value","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]},"description":"Updates the value of an existing custom field value. The custom_field_id, link_id, and link_type are preserved from the existing record.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- value (required) — The new value to store","body":{"mode":"raw","raw":"{\n  \"value\": \"Handle with extreme care — fragile electronics\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"custom_field_id\": 1,\n  \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n  \"link_id\": 45,\n  \"value\": \"Handle with extreme care — fragile electronics\",\n  \"created_at\": \"2024-03-10T14:00:00.000000Z\",\n  \"updated_at\": \"2024-06-01T12:00:00.000000Z\"\n}"}]},{"name":"Delete Custom Field Value","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]},"description":"Deletes a custom field value by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/custom-field-values/{custom_field_value}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":custom_field_value"],"variable":[{"key":"custom_field_value","value":"1","description":"Custom field value ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]}]},{"name":"Sales Reps","item":[{"name":"List Sales Reps","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-reps","host":["{{baseUrl}}"],"path":["api","sales-reps"]},"description":"List all sales reps with pagination, filtering, and sorting via Spatie QueryBuilder.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nAllowed sorts: name, email, phone, active, created_at, updated_at (default: name)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-reps","host":["{{baseUrl}}"],"path":["api","sales-reps"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Jane Smith\",\n      \"email\": \"jane@example.com\",\n      \"active\": true,\n      \"sales_orders_count\": 42\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28\n}"}]},{"name":"Create Sales Rep","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-reps","host":["{{baseUrl}}"],"path":["api","sales-reps"]},"description":"Create a new sales rep. Defaults active to true if not provided.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Sales rep display name (max 255 chars)\n- email (optional): Unique email address\n- phone (optional): Phone number\n- user_id (optional): Link to a user account\n- active (optional): Whether the sales rep is active (default: true)","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"555-123-4567\",\n  \"user_id\": 5,\n  \"active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-reps","host":["{{baseUrl}}"],"path":["api","sales-reps"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Jane Smith\",\n    \"active\": true\n  },\n  \"message\": \"Sales rep created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Sales Rep","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a single sales rep by ID, including their linked user account and sales order count.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Jane Smith\",\n    \"active\": true,\n    \"sales_orders_count\": 42\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Sales Rep","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update an existing sales rep.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Smith-Johnson\",\n  \"email\": \"jane.johnson@example.com\",\n  \"phone\": \"555-999-0000\",\n  \"active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Jane Smith-Johnson\",\n    \"active\": true\n  },\n  \"message\": \"Sales rep updated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Sales Rep Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-reps/{salesRep}/activity-log","host":["{{baseUrl}}"],"path":["api","sales-reps",":salesRep","activity-log"],"variable":[{"key":"salesRep","value":"1","description":"Sales rep ID"}]},"description":"Get the activity log for a specific sales rep. Returns a paginated list of audit events with the causer and changed properties.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-reps/{salesRep}/activity-log","host":["{{baseUrl}}"],"path":["api","sales-reps",":salesRep","activity-log"],"variable":[{"key":"salesRep","value":"1","description":"Sales rep ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"event\": \"updated\",\n      \"causer_name\": \"Admin User\",\n      \"created_at\": \"2024-06-15T10:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 22\n}"}]},{"name":"Get Sales Reps for Dropdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-reps/list","host":["{{baseUrl}}"],"path":["api","sales-reps","list"]},"description":"Get a simplified list of all sales reps (id and name only) for use in dropdown/combo box lookups. Returns all reps ordered by name without pagination.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-reps/list","host":["{{baseUrl}}"],"path":["api","sales-reps","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Jane Smith\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Bob Johnson\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]}]},{"name":"Warehouses","item":[{"name":"List Warehouse Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouse-locations/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouse-locations",":warehouse"],"variable":[{"key":"warehouse","value":"3","description":"Warehouse ID whose locations to list"}]},"description":"List all storage locations defined for a warehouse. The path parameter is the WAREHOUSE ID (not a location ID).\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA location is a physical slot addressed by aisle / bay / shelf / bin. At most one location per warehouse is flagged `is_default` — new stock is placed there unless a location is specified.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouse-locations/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouse-locations",":warehouse"],"variable":[{"key":"warehouse","value":"3","description":"Warehouse ID whose locations to list"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"warehouse_id\": 3,\n      \"aisle\": \"A\",\n      \"bay\": \"1\",\n      \"shelf\": \"2\",\n      \"bin\": \"B\",\n      \"is_default\": true\n    },\n    {\n      \"id\": 2,\n      \"warehouse_id\": 3,\n      \"aisle\": \"B\",\n      \"bay\": \"4\",\n      \"shelf\": null,\n      \"bin\": null,\n      \"is_default\": false\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Update Warehouse Location","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouse-locations/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouse-locations",":warehouse"],"variable":[{"key":"warehouse","value":"","description":"The warehouse identifier"}]},"description":"Update a storage location. All fields are optional — send only the fields to change.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- `aisle`, `bay`, `shelf`, `bin` (max 255 each).\n- `is_default` (boolean) — when true, this location becomes the warehouse's default and the flag is cleared from every other location in that warehouse.\n\nNote: empty, null, and false values are ignored by this endpoint — it only applies non-empty values. To clear a location's default flag, set `is_default: true` on another location in the same warehouse instead of sending false here.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"aisle\": \"C\",\n  \"bay\": \"3\",\n  \"shelf\": \"1\",\n  \"bin\": \"A\",\n  \"is_default\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouse-locations/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouse-locations",":warehouse"],"variable":[{"key":"warehouse","value":"","description":"The warehouse identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The warehouse location '7' updated successfully\",\n  \"data\": {\n    \"id\": 7,\n    \"warehouse_id\": 3,\n    \"aisle\": \"C\",\n    \"bay\": \"3\",\n    \"shelf\": \"1\",\n    \"bin\": \"A\",\n    \"is_default\": true\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Create Warehouse Location","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouse-locations","host":["{{baseUrl}}"],"path":["api","warehouse-locations"]},"description":"Create a storage location inside a warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- `warehouse_id` (required) — must be an existing warehouse.\n- `aisle` (required, max 255).\n- `bay`, `shelf`, `bin` (optional, max 255 each).\n- `is_default` (optional boolean) — when true, this location becomes the warehouse's default and the default flag is automatically cleared from every other location in that warehouse.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"aisle\": \"C\",\n  \"bay\": \"2\",\n  \"shelf\": \"1\",\n  \"bin\": \"A\",\n  \"is_default\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouse-locations","host":["{{baseUrl}}"],"path":["api","warehouse-locations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The warehouse location created successfully\",\n  \"data\": {\n    \"warehouse_id\": 3,\n    \"aisle\": \"C\",\n    \"bay\": \"2\",\n    \"shelf\": \"1\",\n    \"bin\": \"A\",\n    \"is_default\": false,\n    \"id\": 7\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouses","host":["{{baseUrl}}"],"path":["api","v2","warehouses"]},"description":"Returns all warehouses.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContract-manufacturer warehouses are direct warehouses with subtype = \"contractor\" and a non-null contractor_supplier_id (the linked supplier). Their stock is real owned inventory, but they are excluded from channel available-to-sell and are never auto-routed for fulfillment (auto_routing_enabled is always false)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouses","host":["{{baseUrl}}"],"path":["api","v2","warehouses"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"display_name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"subtype\": null,\n      \"contractor_supplier_id\": null,\n      \"supplier_id\": null,\n      \"supplier_name\": null,\n      \"integration_instance_id\": null,\n      \"country_code\": \"US\",\n      \"address_id\": 14,\n      \"order_fulfillment\": \"auto\",\n      \"nominal_code_id\": null,\n      \"nominal_code_name\": null,\n      \"dropship_enabled\": false,\n      \"direct_returns\": true,\n      \"customer_returns\": true,\n      \"auto_routing_enabled\": true,\n      \"auto_dispatch_enabled\": false,\n      \"partial_dispatch_enabled\": false,\n      \"archived_at\": null,\n      \"is_archivable\": true,\n      \"archive_blocked_reason\": null,\n      \"created_at\": \"2026-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2026-06-01T00:00:00.000000Z\",\n      \"city\": \"Austin\",\n      \"province\": \"Texas\",\n      \"country\": \"United States\",\n      \"zip\": \"78701\"\n    },\n    {\n      \"id\": 9,\n      \"name\": \"Acme Assembly Co (Contractor)\",\n      \"display_name\": \"Acme Assembly Co (Contractor)\",\n      \"type\": \"direct\",\n      \"subtype\": \"contractor\",\n      \"contractor_supplier_id\": 12,\n      \"supplier_id\": null,\n      \"supplier_name\": null,\n      \"integration_instance_id\": null,\n      \"country_code\": \"US\",\n      \"address_id\": 31,\n      \"order_fulfillment\": \"manual\",\n      \"nominal_code_id\": null,\n      \"nominal_code_name\": null,\n      \"dropship_enabled\": false,\n      \"direct_returns\": false,\n      \"customer_returns\": false,\n      \"auto_routing_enabled\": false,\n      \"auto_dispatch_enabled\": false,\n      \"partial_dispatch_enabled\": false,\n      \"archived_at\": null,\n      \"is_archivable\": true,\n      \"archive_blocked_reason\": null,\n      \"created_at\": \"2026-03-15T00:00:00.000000Z\",\n      \"updated_at\": \"2026-06-01T00:00:00.000000Z\",\n      \"city\": null,\n      \"province\": null,\n      \"country\": null,\n      \"zip\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.test/api/v2/warehouses?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.test/api/v2/warehouses?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://example.test/api/v2/warehouses\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Show Warehouse","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","v2","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"2","description":"Warehouse ID"}]},"description":"Returns a single warehouse.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContract-manufacturer warehouses are direct warehouses with subtype = \"contractor\" and a non-null contractor_supplier_id (the linked supplier). Their stock is real owned inventory, but they are excluded from channel available-to-sell and are never auto-routed for fulfillment (auto_routing_enabled is always false)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","v2","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"2","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Main Warehouse\",\n    \"display_name\": \"Main Warehouse\",\n    \"type\": \"direct\",\n    \"subtype\": null,\n    \"contractor_supplier_id\": null,\n    \"supplier_id\": null,\n    \"supplier_name\": null,\n    \"integration_instance_id\": null,\n    \"country_code\": \"US\",\n    \"address_id\": 14,\n    \"order_fulfillment\": \"auto\",\n    \"nominal_code_id\": null,\n    \"nominal_code_name\": null,\n    \"dropship_enabled\": false,\n    \"direct_returns\": true,\n    \"customer_returns\": true,\n    \"auto_routing_enabled\": true,\n    \"auto_dispatch_enabled\": false,\n    \"partial_dispatch_enabled\": false,\n    \"archived_at\": null,\n    \"is_archivable\": true,\n    \"archive_blocked_reason\": null,\n    \"created_at\": \"2026-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T00:00:00.000000Z\",\n    \"city\": \"Austin\",\n    \"province\": \"Texas\",\n    \"country\": \"United States\",\n    \"zip\": \"78701\"\n  }\n}"}]},{"name":"Create Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses","host":["{{baseUrl}}"],"path":["api","warehouses"]},"description":"Creates a new warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields: name (unique, max 255), type (one of: direct, 3pl, supplier, amazon_fba, virtual, amazon_awd, walmart_wfs).\n\nOptional fields: subtype (only \"decorator\" may be set here; integration-managed subtypes are assigned automatically), address_name, company, email, phone, fax, address1, address2, address3, city, province, province_code, zip, country, country_code, supplier_id (links a supplier-owned warehouse), order_fulfillment, dropship_enabled, direct_returns, customer_returns, auto_routing_enabled, auto_dispatch_enabled, partial_dispatch_enabled, is_default, default_location (object with aisle, bay, shelf, bin), nominal_code_id, transfer_destination_warehouse_id.\n\nThe warehouse name must be unique (per supplier for supplier warehouses).\n\nAuthentication: Requires Bearer token.\n\nAlso accepts (3PL warehouses): fba_inbound_reminders_enabled (boolean) and fba_inbound_reminder_days (array of positive integer day-offsets, e.g. [3,7,14]) — controls automatic FBA-inbound turnaround reminders to this 3PL.\n\nWFS inbound-reminder settings (opt-in turnaround nudges for WFS inbound shipments sourced from this 3PL/warehouse):\n- wfs_inbound_reminders_enabled (boolean, optional): enable per-warehouse WFS inbound turnaround reminders.\n- wfs_inbound_reminder_days (int[], optional, nullable, each 1–365): days-after-send cadence to remind on (default [3, 7, 14] when reminders are enabled and none provided).\n\n`negative_bin_policy` (optional; one of `block`, `warn`, `allow`; default `warn`) controls how the warehouse reacts when an outbound movement would drive a specific bin's on-hand below zero: `block` rejects the movement, `warn` permits it but flags the shortfall, and `allow` permits it silently. The warehouse's default catch-all location is always exempt.","body":{"mode":"raw","raw":"{\n  \"name\": \"Main Warehouse\",\n  \"type\": \"direct\",\n  \"company\": \"Acme Corp\",\n  \"email\": \"warehouse@example.com\",\n  \"phone\": \"+1 555 0100\",\n  \"address1\": \"100 Commerce Way\",\n  \"address2\": null,\n  \"city\": \"Austin\",\n  \"province\": \"Texas\",\n  \"province_code\": \"TX\",\n  \"zip\": \"78701\",\n  \"country\": \"United States\",\n  \"country_code\": \"US\",\n  \"order_fulfillment\": \"manual\",\n  \"dropship_enabled\": false,\n  \"direct_returns\": false,\n  \"customer_returns\": true,\n  \"auto_routing_enabled\": true,\n  \"auto_dispatch_enabled\": false,\n  \"partial_dispatch_enabled\": false,\n  \"negative_bin_policy\": \"warn\",\n  \"default_location\": {\n    \"aisle\": \"Default\",\n    \"bay\": null,\n    \"shelf\": null,\n    \"bin\": null\n  },\n  \"nominal_code_id\": null,\n  \"transfer_destination_warehouse_id\": null,\n  \"wfs_inbound_reminders_enabled\": true,\n  \"wfs_inbound_reminder_days\": [\n    3,\n    7,\n    14\n  ],\n  \"exclude_from_planning\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses","host":["{{baseUrl}}"],"path":["api","warehouses"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse created successfully.\",\n  \"data\": {\n    \"name\": \"Main Warehouse\",\n    \"display_name\": \"Main Warehouse\",\n    \"id\": 12,\n    \"type\": \"direct\",\n    \"subtype\": null,\n    \"supplier_id\": null,\n    \"contractor_supplier_id\": null,\n    \"dropship_enabled\": false,\n    \"created_at\": \"2026-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T14:30:00.000000Z\",\n    \"archived_at\": null,\n    \"address_name\": \"Main Warehouse\",\n    \"order_fulfillment\": \"manual\",\n    \"address_id\": 301,\n    \"label\": null,\n    \"email\": \"warehouse@example.com\",\n    \"phone\": \"+1 555 0100\",\n    \"fax\": null,\n    \"company\": \"Acme Corp\",\n    \"address1\": \"100 Commerce Way\",\n    \"address2\": null,\n    \"address3\": null,\n    \"city\": \"Austin\",\n    \"province\": \"Texas\",\n    \"province_code\": \"TX\",\n    \"zip\": \"78701\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\",\n    \"address_redacted\": false,\n    \"warehouse_locations\": [\n      {\n        \"id\": 55,\n        \"warehouse_id\": 12,\n        \"aisle\": \"Default\",\n        \"bay\": null,\n        \"shelf\": null,\n        \"bin\": null,\n        \"is_default\": true\n      }\n    ],\n    \"shipping_automated\": null,\n    \"is_archivable\": true,\n    \"archive_blocked_reason\": null,\n    \"auto_routing_enabled\": true,\n    \"auto_dispatch_enabled\": false,\n    \"partial_dispatch_enabled\": false,\n    \"negative_bin_policy\": \"warn\",\n    \"integration_instance_id\": null,\n    \"nominal_code_id\": null,\n    \"transfer_destination_warehouse_id\": null,\n    \"is_amazon_fba_warehouse\": false,\n    \"externally_managed\": false\n  }\n}"}]},{"name":"Bulk Delete Warehouses","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses","host":["{{baseUrl}}"],"path":["api","warehouses"]},"description":"Deletes multiple warehouses. Provide either ids (array of warehouse IDs) or apply_to_all=true with an optional filters object. Warehouses referenced by other records are skipped and counted in failCount. Use Check Warehouses Deletable first to verify which records can be removed.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses","host":["{{baseUrl}}"],"path":["api","warehouses"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 3,\n    \"failCount\": 0\n  },\n  \"message\": \"3 records processed successfully.\"\n}"}]},{"name":"Update Warehouse","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]},"description":"Updates an existing warehouse. Accepts the same fields as Create Warehouse; all fields are optional on update.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAddress fields (address1, city, zip, country_code, etc.) update the warehouse's address record. Setting is_default on a supplier warehouse makes it that supplier's default warehouse. Toggling auto_routing_enabled adds or removes the warehouse from the automatic order-routing priority list.\n\nReturns 400 when disabling dropshipping on a warehouse that still has open dropship orders.\n\nAuthentication: Requires Bearer token.\n\nAlso accepts (3PL warehouses): fba_inbound_reminders_enabled (boolean) and fba_inbound_reminder_days (array of positive integer day-offsets, e.g. [3,7,14]) — controls automatic FBA-inbound turnaround reminders to this 3PL.\n\nWFS inbound-reminder settings (opt-in turnaround nudges for WFS inbound shipments sourced from this 3PL/warehouse):\n- wfs_inbound_reminders_enabled (boolean, optional): enable per-warehouse WFS inbound turnaround reminders.\n- wfs_inbound_reminder_days (int[], optional, nullable, each 1–365): days-after-send cadence to remind on (default [3, 7, 14] when reminders are enabled and none provided).\n\n`negative_bin_policy` (optional; one of `block`, `warn`, `allow`; default `warn`) controls how the warehouse reacts when an outbound movement would drive a specific bin's on-hand below zero: `block` rejects the movement, `warn` permits it but flags the shortfall, and `allow` permits it silently. The warehouse's default catch-all location is always exempt.","body":{"mode":"raw","raw":"{\n  \"name\": \"Main Warehouse East\",\n  \"auto_routing_enabled\": false,\n  \"order_fulfillment\": \"manual\",\n  \"wfs_inbound_reminders_enabled\": true,\n  \"wfs_inbound_reminder_days\": [\n    3,\n    7,\n    14\n  ],\n  \"negative_bin_policy\": \"block\",\n  \"exclude_from_planning\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse Main Warehouse East updated successfully.\",\n  \"data\": {\n    \"name\": \"Main Warehouse\",\n    \"display_name\": \"Main Warehouse\",\n    \"id\": 12,\n    \"type\": \"direct\",\n    \"subtype\": null,\n    \"supplier_id\": null,\n    \"contractor_supplier_id\": null,\n    \"dropship_enabled\": false,\n    \"created_at\": \"2026-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T14:30:00.000000Z\",\n    \"archived_at\": null,\n    \"address_name\": \"Main Warehouse\",\n    \"order_fulfillment\": \"manual\",\n    \"address_id\": 301,\n    \"label\": null,\n    \"email\": \"warehouse@example.com\",\n    \"phone\": \"+1 555 0100\",\n    \"fax\": null,\n    \"company\": \"Acme Corp\",\n    \"address1\": \"100 Commerce Way\",\n    \"address2\": null,\n    \"address3\": null,\n    \"city\": \"Austin\",\n    \"province\": \"Texas\",\n    \"province_code\": \"TX\",\n    \"zip\": \"78701\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\",\n    \"address_redacted\": false,\n    \"warehouse_locations\": [\n      {\n        \"id\": 55,\n        \"warehouse_id\": 12,\n        \"aisle\": \"Default\",\n        \"bay\": null,\n        \"shelf\": null,\n        \"bin\": null,\n        \"is_default\": true\n      }\n    ],\n    \"shipping_automated\": null,\n    \"is_archivable\": true,\n    \"archive_blocked_reason\": null,\n    \"auto_routing_enabled\": true,\n    \"auto_dispatch_enabled\": false,\n    \"partial_dispatch_enabled\": false,\n    \"negative_bin_policy\": \"block\",\n    \"integration_instance_id\": null,\n    \"nominal_code_id\": null,\n    \"transfer_destination_warehouse_id\": null,\n    \"is_amazon_fba_warehouse\": false,\n    \"externally_managed\": false\n  }\n}"}]},{"name":"Delete Warehouse","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]},"description":"Deletes a warehouse. A warehouse that is referenced by inventory, orders, or other records cannot be deleted; the response lists the linked record types blocking deletion. Use Check Warehouses Deletable first to verify deletability.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse Main Warehouse deleted successfully.\"\n}"}]},{"name":"Archive Warehouse","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}/archive","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse","archive"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]},"description":"Archives a warehouse, hiding it from active listings. Integration-managed warehouses (e.g. Amazon FBA) and warehouses that still hold available stock cannot be archived.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}/archive","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse","archive"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse Main Warehouse archived successfully.\",\n  \"data\": {\n    \"name\": \"Main Warehouse\",\n    \"display_name\": \"Main Warehouse\",\n    \"id\": 12,\n    \"type\": \"direct\",\n    \"subtype\": null,\n    \"supplier_id\": null,\n    \"contractor_supplier_id\": null,\n    \"dropship_enabled\": false,\n    \"created_at\": \"2026-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T14:30:00.000000Z\",\n    \"archived_at\": null,\n    \"address_name\": \"Main Warehouse\",\n    \"order_fulfillment\": \"manual\",\n    \"address_id\": 301,\n    \"label\": null,\n    \"email\": \"warehouse@example.com\",\n    \"phone\": \"+1 555 0100\",\n    \"fax\": null,\n    \"company\": \"Acme Corp\",\n    \"address1\": \"100 Commerce Way\",\n    \"address2\": null,\n    \"address3\": null,\n    \"city\": \"Austin\",\n    \"province\": \"Texas\",\n    \"province_code\": \"TX\",\n    \"zip\": \"78701\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\",\n    \"address_redacted\": false,\n    \"warehouse_locations\": [\n      {\n        \"id\": 55,\n        \"warehouse_id\": 12,\n        \"aisle\": \"Default\",\n        \"bay\": null,\n        \"shelf\": null,\n        \"bin\": null,\n        \"is_default\": true\n      }\n    ],\n    \"shipping_automated\": null,\n    \"is_archivable\": true,\n    \"archive_blocked_reason\": null,\n    \"auto_routing_enabled\": true,\n    \"auto_dispatch_enabled\": false,\n    \"partial_dispatch_enabled\": false,\n    \"integration_instance_id\": null,\n    \"nominal_code_id\": null,\n    \"transfer_destination_warehouse_id\": null,\n    \"is_amazon_fba_warehouse\": false,\n    \"externally_managed\": false\n  }\n}"}]},{"name":"Unarchive Warehouse","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}/unarchived","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse","unarchived"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]},"description":"Restores an archived warehouse to active status. Integration-managed warehouses (e.g. Amazon FBA) cannot be modified through this endpoint.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/{warehouse}/unarchived","host":["{{baseUrl}}"],"path":["api","warehouses",":warehouse","unarchived"],"variable":[{"key":"warehouse","value":"12","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse Main Warehouse unarchived successfully.\",\n  \"data\": {\n    \"name\": \"Main Warehouse\",\n    \"display_name\": \"Main Warehouse\",\n    \"id\": 12,\n    \"type\": \"direct\",\n    \"subtype\": null,\n    \"supplier_id\": null,\n    \"contractor_supplier_id\": null,\n    \"dropship_enabled\": false,\n    \"created_at\": \"2026-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T14:30:00.000000Z\",\n    \"archived_at\": null,\n    \"address_name\": \"Main Warehouse\",\n    \"order_fulfillment\": \"manual\",\n    \"address_id\": 301,\n    \"label\": null,\n    \"email\": \"warehouse@example.com\",\n    \"phone\": \"+1 555 0100\",\n    \"fax\": null,\n    \"company\": \"Acme Corp\",\n    \"address1\": \"100 Commerce Way\",\n    \"address2\": null,\n    \"address3\": null,\n    \"city\": \"Austin\",\n    \"province\": \"Texas\",\n    \"province_code\": \"TX\",\n    \"zip\": \"78701\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\",\n    \"address_redacted\": false,\n    \"warehouse_locations\": [\n      {\n        \"id\": 55,\n        \"warehouse_id\": 12,\n        \"aisle\": \"Default\",\n        \"bay\": null,\n        \"shelf\": null,\n        \"bin\": null,\n        \"is_default\": true\n      }\n    ],\n    \"shipping_automated\": null,\n    \"is_archivable\": true,\n    \"archive_blocked_reason\": null,\n    \"auto_routing_enabled\": true,\n    \"auto_dispatch_enabled\": false,\n    \"partial_dispatch_enabled\": false,\n    \"integration_instance_id\": null,\n    \"nominal_code_id\": null,\n    \"transfer_destination_warehouse_id\": null,\n    \"is_amazon_fba_warehouse\": false,\n    \"externally_managed\": false\n  }\n}"}]},{"name":"Bulk Archive Warehouses","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/archive","host":["{{baseUrl}}"],"path":["api","warehouses","archive"]},"description":"Archives multiple warehouses. Provide either ids (array of warehouse IDs) or apply_to_all=true with an optional filters object to target all warehouses matching the current listing filters.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWarehouses that cannot be archived (integration-managed, or holding stock) are skipped and counted in failCount, with a per-record warning in the response.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/archive","host":["{{baseUrl}}"],"path":["api","warehouses","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 3,\n    \"failCount\": 0\n  },\n  \"message\": \"3 records processed successfully.\"\n}"}]},{"name":"Bulk Unarchive Warehouses","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/unarchive","host":["{{baseUrl}}"],"path":["api","warehouses","unarchive"]},"description":"Restores multiple archived warehouses. Provide either ids (array of warehouse IDs) or apply_to_all=true with an optional filters object.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/unarchive","host":["{{baseUrl}}"],"path":["api","warehouses","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 3,\n    \"failCount\": 0\n  },\n  \"message\": \"3 records processed successfully.\"\n}"}]},{"name":"Check Warehouses Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/deletable","host":["{{baseUrl}}"],"path":["api","warehouses","deletable"]},"description":"Checks whether the given warehouses can be deleted. Provide ids (array of warehouse IDs), or scope=\"all\" to check every warehouse matching the current listing filters.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach result includes deletable (boolean), reason (why deletion is blocked, or null) and reason_details (linked record breakdown, or null).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/deletable","host":["{{baseUrl}}"],"path":["api","warehouses","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"deletable\": false,\n      \"reason\": \"Warehouse is in use\",\n      \"reason_details\": [\n        {\n          \"type\": \"purchase_orders\",\n          \"count\": 4\n        }\n      ]\n    },\n    {\n      \"id\": 13,\n      \"name\": \"Overflow Warehouse\",\n      \"deletable\": true,\n      \"reason\": null,\n      \"reason_details\": null\n    }\n  ]\n}"}]},{"name":"Check Warehouses Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/is-archivable","host":["{{baseUrl}}"],"path":["api","warehouses","is-archivable"]},"description":"Checks whether the given warehouses can be archived. Each result includes archivable (boolean) and reason (why archiving is blocked, or null). Integration-managed warehouses and warehouses holding stock are not archivable.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/is-archivable","host":["{{baseUrl}}"],"path":["api","warehouses","is-archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"archivable\": false,\n      \"reason\": \"Warehouse has stock available\"\n    },\n    {\n      \"id\": 13,\n      \"name\": \"Overflow Warehouse\",\n      \"archivable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Preview Warehouse Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/import/preview","host":["{{baseUrl}}"],"path":["api","warehouses","import","preview"]},"description":"Parses an uploaded CSV file and returns a preview before importing: parsed records, detected file headers, the list of importable fields, unmatched columns (difference), missing required columns (required_difference) and columns that cannot be imported (not_importable).\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields: original_name (the file's original name), stored_name (the stored upload reference returned by the file upload). Optional: mapping (array of {file_field, expected_field} pairs to map CSV columns to warehouse fields), separator, escape, meta, task_id.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"warehouses.csv\",\n  \"stored_name\": \"uploads/abc123-warehouses.csv\",\n  \"separator\": \",\",\n  \"escape\": \"\\\"\",\n  \"mapping\": [\n    {\n      \"file_field\": \"Warehouse Name\",\n      \"expected_field\": \"name\"\n    },\n    {\n      \"file_field\": \"Type\",\n      \"expected_field\": \"type\"\n    },\n    {\n      \"file_field\": \"City\",\n      \"expected_field\": \"city\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/import/preview","host":["{{baseUrl}}"],"path":["api","warehouses","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"records\": [\n      {\n        \"name\": \"Main Warehouse\",\n        \"type\": \"direct\",\n        \"city\": \"Austin\"\n      }\n    ],\n    \"file_headers\": [\n      \"Warehouse Name\",\n      \"Type\",\n      \"City\"\n    ],\n    \"importable_fields\": [\n      \"name\",\n      \"type\",\n      \"city\",\n      \"province\",\n      \"country_code\",\n      \"zip\"\n    ],\n    \"difference\": [],\n    \"required_difference\": [],\n    \"not_importable\": [],\n    \"task_id\": null\n  }\n}"}]},{"name":"Import Warehouses","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/import","host":["{{baseUrl}}"],"path":["api","warehouses","import"]},"description":"Imports warehouses from an uploaded CSV file. Accepts the same payload as Preview Warehouse Import. If required columns are missing, the preview payload is returned instead so the mapping can be corrected. Large files are processed in the background and the response indicates the import will complete shortly.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"warehouses.csv\",\n  \"stored_name\": \"uploads/abc123-warehouses.csv\",\n  \"separator\": \",\",\n  \"escape\": \"\\\"\",\n  \"mapping\": [\n    {\n      \"file_field\": \"Warehouse Name\",\n      \"expected_field\": \"name\"\n    },\n    {\n      \"file_field\": \"Type\",\n      \"expected_field\": \"type\"\n    },\n    {\n      \"file_field\": \"City\",\n      \"expected_field\": \"city\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/import","host":["{{baseUrl}}"],"path":["api","warehouses","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Data import was successful.\"\n}"}]},{"name":"Export Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouses/export","host":["{{baseUrl}}"],"path":["api","v2","warehouses","export"]},"description":"Exports warehouses matching the current filters as a CSV or XLSX file download.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nColumns: Sr No., id, name, type, city, province, province_code, country, country_code, zip, created_at, updated_at. Archived warehouses are excluded unless filter[archived] is provided (values: only, all).\n\nColumn filters accept operator suffixes in the form filter[column.operator], e.g. filter[name.contains]=main or filter[created_at.between]=2026-01-01,2026-06-30. Text operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of. Numeric operators: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. Date operators: is, is_not, on_or_before, on_or_after, between, is_empty, is_not_empty.\n\nAuthentication: Requires Bearer token.\n\nOptional. When `include_contacts=1`, the export flattens to one row per contact with the parent columns repeated (parent-only row when a record has no contacts), appending Contact ID/Name/Email/Phone/Role/Title/Primary/Notes columns."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouses/export","host":["{{baseUrl}}"],"path":["api","v2","warehouses","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Sr No.,id,name,type,city,province,province_code,country,country_code,zip,created_at,updated_at\n1,12,Main Warehouse,direct,Austin,Texas,TX,United States,US,78701,2026-01-10T09:00:00.000000Z,2026-06-01T14:30:00.000000Z\n"}]},{"name":"List Fulfillment Dispatch Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/fulfillment-dispatch-settings","host":["{{baseUrl}}"],"path":["api","warehouses","fulfillment-dispatch-settings"]},"description":"Returns the fulfillment dispatch configuration for every non-supplier warehouse: the fulfillment channel (order_fulfillment), whether fulfillments are automatically dispatched to the connected shipping provider (auto_dispatch_enabled) and whether partial dispatch is allowed (partial_dispatch_enabled).\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response also includes shippingProviders (the available order_fulfillment values: \"manual\" plus the names of connected shipping-provider integrations) and shippingProviderDispatchEnabled (whether real provider dispatch is on for this account) and shippingProviderDispatchEditable (whether that setting can be toggled here — true outside production, where dispatch is a per-account opt-in; false in production, where it is always on).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouses/fulfillment-dispatch-settings","host":["{{baseUrl}}"],"path":["api","warehouses","fulfillment-dispatch-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"order_fulfillment\": \"manual\",\n      \"auto_dispatch_enabled\": false,\n      \"partial_dispatch_enabled\": false,\n      \"type\": \"direct\",\n      \"integration_instance_id\": null,\n      \"integration_name\": null,\n      \"integration_sub_type\": null\n    },\n    {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"order_fulfillment\": \"shipstation\",\n      \"auto_dispatch_enabled\": true,\n      \"partial_dispatch_enabled\": true,\n      \"type\": \"3pl\",\n      \"integration_instance_id\": 9,\n      \"integration_name\": \"ShipStation\",\n      \"integration_sub_type\": \"shipping_provider\"\n    }\n  ],\n  \"shippingProviders\": [\n    \"manual\",\n    \"shipstation\"\n  ],\n  \"shippingProviderDispatchEnabled\": true,\n  \"shippingProviderDispatchEditable\": false\n}"}]},{"name":"Bulk Update Warehouse Dispatch Settings","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/bulk-update","host":["{{baseUrl}}"],"path":["api","warehouses","bulk-update"]},"description":"Updates fulfillment dispatch settings for multiple warehouses in one request.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach entry requires id, auto_dispatch_enabled and partial_dispatch_enabled; order_fulfillment (the fulfillment channel, \"manual\" or a connected shipping-provider name) is optional.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouses\": [\n    {\n      \"id\": 12,\n      \"auto_dispatch_enabled\": true,\n      \"partial_dispatch_enabled\": false,\n      \"order_fulfillment\": \"shipstation\"\n    },\n    {\n      \"id\": 5,\n      \"auto_dispatch_enabled\": true,\n      \"partial_dispatch_enabled\": true,\n      \"order_fulfillment\": \"shipstation\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/warehouses/bulk-update","host":["{{baseUrl}}"],"path":["api","warehouses","bulk-update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Success\"\n}"}]},{"name":"List Product Warehouse Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]},"description":"Paginated preferred-location (bin) assignments for products, with the location, warehouse and product relations loaded for display. Filter by product_id + warehouse_id to fetch a single product's ordered bin list.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nAvailable sorts: id, created_at, is_default, priority (default: -is_default, then priority, then id — i.e. resolution order)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"product_id\": 42,\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 12,\n      \"is_default\": true,\n      \"priority\": 0,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse_location\": {\n        \"id\": 12,\n        \"code\": \"A1-B2-S3-BIN4\",\n        \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\",\n        \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n        \"deprecated_at\": null\n      },\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Product Warehouse Location","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations"]},"description":"Assign a preferred storage bin to a product in a warehouse. The location must be an active put-away destination. The first assignment for a product+warehouse automatically becomes the default; new assignments append to the end of the ordered list unless `priority` is given.\n\nBody fields:\n- product_id (required) — product to assign.\n- warehouse_id (required) — warehouse the bin lives in.\n- warehouse_location_id (required) — the bin; must belong to the warehouse and be a put-away destination.\n- is_default (optional, boolean) — mark as the product+warehouse default.\n- priority (optional, integer ≥ 0) — explicit position in the ordered list; omitted assignments append to the end.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write). Requires the warehouses.manage_locations permission.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"warehouse_id\": 1,\n  \"warehouse_location_id\": 12,\n  \"is_default\": true,\n  \"priority\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"product_id\": 42,\n    \"warehouse_id\": 1,\n    \"warehouse_location_id\": 12,\n    \"is_default\": true,\n    \"priority\": 0,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\"\n    },\n    \"warehouse_location\": {\n      \"id\": 12,\n      \"code\": \"A1-B2-S3-BIN4\",\n      \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"type\": \"storage\",\n      \"type_label\": \"Storage\",\n      \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"deprecated_at\": null\n    },\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Preferred location assigned.\"\n}"}]},{"name":"Update Product Warehouse Location","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]},"description":"Update a preferred-bin assignment. All fields optional (`sometimes`).\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody fields (all optional):\n- warehouse_location_id (integer, exists, must be a put-away destination (is_putaway_destination enabled), unique per product+warehouse)\n- is_default (boolean)\n\n**Requires permission:** `warehouses.manage_locations`","body":{"mode":"raw","raw":"{\n  \"warehouse_location_id\": 13,\n  \"is_default\": true,\n  \"priority\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"product_id\": 42,\n    \"warehouse_id\": 1,\n    \"warehouse_location_id\": 12,\n    \"is_default\": true,\n    \"priority\": 0,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\"\n    },\n    \"warehouse_location\": {\n      \"id\": 12,\n      \"code\": \"A1-B2-S3-BIN4\",\n      \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"type\": \"storage\",\n      \"type_label\": \"Storage\",\n      \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"deprecated_at\": null\n    },\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Preferred location updated.\"\n}"}]},{"name":"Delete Product Warehouse Location","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]},"description":"Remove a preferred-bin assignment.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\n**Requires permission:** `warehouses.manage_locations`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Set Default Preferred Bin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}/set-default","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation","set-default"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]},"description":"Promote a preferred-bin assignment to the product+warehouse default. The swap is atomic — the previous default for the same product+warehouse is unset.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\n**Requires permission:** `warehouses.manage_locations`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/{productWarehouseLocation}/set-default","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations",":productWarehouseLocation","set-default"],"variable":[{"key":"productWarehouseLocation","value":"7","description":"Product warehouse location (preferred bin) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"product_id\": 42,\n    \"warehouse_id\": 1,\n    \"warehouse_location_id\": 12,\n    \"is_default\": true,\n    \"priority\": 0,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\"\n    },\n    \"warehouse_location\": {\n      \"id\": 12,\n      \"code\": \"A1-B2-S3-BIN4\",\n      \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"type\": \"storage\",\n      \"type_label\": \"Storage\",\n      \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"deprecated_at\": null\n    },\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Default preferred location updated.\"\n}"}]},{"name":"Reorder Preferred Bins","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/reorder","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations","reorder"]},"description":"Reorder a product's preferred bins in a warehouse to match the given id order (top to bottom) and return the fresh ordered list. Priorities are rewritten 0-based and the new top bin becomes the default, so the ordered list matches the resolution order used by put-away and receiving.\n\nBody fields:\n- product_id (required) — product whose bins are reordered.\n- warehouse_id (required) — warehouse the bins live in.\n- ids (required, array of integers) — assignment ids in the desired order; must be exactly the product+warehouse's current assignments.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write). Requires the warehouses.manage_locations permission.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"warehouse_id\": 1,\n  \"ids\": [\n    9,\n    7,\n    8\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/product-warehouse-locations/reorder","host":["{{baseUrl}}"],"path":["api","v2","product-warehouse-locations","reorder"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9,\n      \"product_id\": 42,\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 15,\n      \"is_default\": true,\n      \"priority\": 0,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse_location\": {\n        \"id\": 15,\n        \"code\": \"C1-B1-S1-BIN1\",\n        \"name\": null,\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\",\n        \"display_name\": \"C1-B1-S1-BIN1\",\n        \"deprecated_at\": null\n      },\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n    },\n    {\n      \"id\": 7,\n      \"product_id\": 42,\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 12,\n      \"is_default\": false,\n      \"priority\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse_location\": {\n        \"id\": 12,\n        \"code\": \"A1-B2-S3-BIN4\",\n        \"name\": null,\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\",\n        \"display_name\": \"A1-B2-S3-BIN4\",\n        \"deprecated_at\": null\n      },\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n    },\n    {\n      \"id\": 8,\n      \"product_id\": 42,\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 13,\n      \"is_default\": false,\n      \"priority\": 2,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse_location\": {\n        \"id\": 13,\n        \"code\": \"B1-B1-S1-BIN1\",\n        \"name\": null,\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\",\n        \"display_name\": \"B1-B1-S1-BIN1\",\n        \"deprecated_at\": null\n      },\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"message\": \"Preferred bins reordered.\"\n}"}]},{"name":"List LPNs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/lpns","host":["{{baseUrl}}"],"path":["api","v2","lpns"]},"description":"Paginated pallets/totes (LPNs) with their bin and content count.\n\nAuthentication: Requires Bearer token.\nFilters: filter[status] (open|closed), filter[warehouse_id], filter[warehouse_location_id], filter[search] (number or barcode). Sorts: id, number, status, created_at. Pagination: page, per_page (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/lpns","host":["{{baseUrl}}"],"path":["api","v2","lpns"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"number\": \"LPN-000003\",\n      \"barcode\": \"PLT-123\",\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"warehouse_location_id\": 15,\n      \"location\": {\n        \"id\": 15,\n        \"code\": \"ST-01\",\n        \"name\": \"Storage 1\"\n      },\n      \"status\": \"open\",\n      \"status_label\": \"Open\",\n      \"notes\": null,\n      \"contents_count\": 1,\n      \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Create LPN","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/lpns","host":["{{baseUrl}}"],"path":["api","v2","lpns"]},"description":"Create an open LPN (pallet/tote), optionally placed in a bin.\n\nAuthentication: Requires Bearer token. Only on warehouses with locations enabled.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"warehouse_location_id\": 15,\n  \"barcode\": \"PLT-123\",\n  \"notes\": \"Pallet A\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/lpns","host":["{{baseUrl}}"],"path":["api","v2","lpns"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"LPN-000003\",\n    \"barcode\": \"PLT-123\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"warehouse_location_id\": 15,\n    \"location\": {\n      \"id\": 15,\n      \"code\": \"ST-01\",\n      \"name\": \"Storage 1\"\n    },\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"notes\": null,\n    \"contents_count\": 1,\n    \"contents\": [\n      {\n        \"id\": 8,\n        \"product_id\": 42,\n        \"sku\": \"WIDGET-1\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 20\n      }\n    ],\n    \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n  },\n  \"message\": \"LPN created.\"\n}"}]},{"name":"Get LPN","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]},"description":"A single LPN with its full content manifest.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"LPN-000003\",\n    \"barcode\": \"PLT-123\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"warehouse_location_id\": 15,\n    \"location\": {\n      \"id\": 15,\n      \"code\": \"ST-01\",\n      \"name\": \"Storage 1\"\n    },\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"notes\": null,\n    \"contents_count\": 1,\n    \"contents\": [\n      {\n        \"id\": 8,\n        \"product_id\": 42,\n        \"sku\": \"WIDGET-1\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 20\n      }\n    ],\n    \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n  }\n}"}]},{"name":"Add Stock to LPN","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/contents","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","contents"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]},"description":"Nest stock onto an open LPN. The LPN's bin must physically hold at least the resulting quantity of the product.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"quantity\": 20\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/contents","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","contents"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"LPN-000003\",\n    \"barcode\": \"PLT-123\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"warehouse_location_id\": 15,\n    \"location\": {\n      \"id\": 15,\n      \"code\": \"ST-01\",\n      \"name\": \"Storage 1\"\n    },\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"notes\": null,\n    \"contents_count\": 1,\n    \"contents\": [\n      {\n        \"id\": 8,\n        \"product_id\": 42,\n        \"sku\": \"WIDGET-1\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 20\n      }\n    ],\n    \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n  },\n  \"message\": \"Stock added to the LPN.\"\n}"}]},{"name":"Bulk Import Stock to LPN","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/contents/bulk","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","contents","bulk"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]},"description":"Nest many products onto an open LPN in one call. Each item is matched by SKU (or barcode) or product id, aggregated per product, and checked against the on-hand quantity in the LPN's bin. Returns a per-row report (status: ok, insufficient, not_found, invalid) plus a summary. Set dry_run=true to validate without persisting; dry_run=false nests every valid product in a single transaction and returns the updated LPN. Items referencing the same product are combined.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"dry_run\": false,\n  \"items\": [\n    {\n      \"sku\": \"WIDGET-1\",\n      \"quantity\": 20\n    },\n    {\n      \"sku\": \"WIDGET-2\",\n      \"quantity\": 5\n    },\n    {\n      \"product_id\": 99,\n      \"quantity\": 12\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/contents/bulk","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","contents","bulk"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"results\": [\n    {\n      \"row\": 1,\n      \"input\": \"WIDGET-1\",\n      \"quantity\": 20,\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-1\",\n      \"name\": \"Blue Widget\",\n      \"status\": \"ok\",\n      \"message\": null\n    },\n    {\n      \"row\": 2,\n      \"input\": \"WIDGET-2\",\n      \"quantity\": 5,\n      \"product_id\": 43,\n      \"sku\": \"WIDGET-2\",\n      \"name\": \"Red Widget\",\n      \"status\": \"insufficient\",\n      \"message\": \"The bin holds 2 of this product — not enough to nest 5.\"\n    },\n    {\n      \"row\": 3,\n      \"input\": \"NOPE-1\",\n      \"quantity\": 1,\n      \"product_id\": null,\n      \"sku\": null,\n      \"name\": null,\n      \"status\": \"not_found\",\n      \"message\": \"No product matches this SKU or barcode.\"\n    }\n  ],\n  \"summary\": {\n    \"ok\": 1,\n    \"not_found\": 1,\n    \"insufficient\": 1,\n    \"invalid\": 0,\n    \"units\": 20\n  },\n  \"lpn\": null,\n  \"message\": \"Validated import.\"\n}"}]},{"name":"Move LPN","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/move","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","move"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]},"description":"Move the whole LPN to another bin — relocating every content line's stock in one transfer.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_location_id\": 16\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/move","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","move"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"LPN-000003\",\n    \"barcode\": \"PLT-123\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"warehouse_location_id\": 16,\n    \"location\": {\n      \"id\": 16,\n      \"code\": \"ST-02\",\n      \"name\": \"Storage 2\"\n    },\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"notes\": null,\n    \"contents_count\": 1,\n    \"contents\": [\n      {\n        \"id\": 8,\n        \"product_id\": 42,\n        \"sku\": \"WIDGET-1\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 20\n      }\n    ],\n    \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n  },\n  \"message\": \"LPN moved.\"\n}"}]},{"name":"Close LPN","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/close","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","close"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]},"description":"Close an LPN — it can no longer take stock or move.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/lpns/{warehouseLpn}/close","host":["{{baseUrl}}"],"path":["api","v2","lpns",":warehouseLpn","close"],"variable":[{"key":"warehouseLpn","value":"","description":"The warehouse lpn ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"LPN-000003\",\n    \"barcode\": \"PLT-123\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"warehouse_location_id\": 15,\n    \"location\": {\n      \"id\": 15,\n      \"code\": \"ST-01\",\n      \"name\": \"Storage 1\"\n    },\n    \"status\": \"closed\",\n    \"status_label\": \"Closed\",\n    \"notes\": null,\n    \"contents_count\": 1,\n    \"contents\": [\n      {\n        \"id\": 8,\n        \"product_id\": 42,\n        \"sku\": \"WIDGET-1\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 20\n      }\n    ],\n    \"created_at\": \"2026-07-10T09:00:00.000000Z\"\n  },\n  \"message\": \"LPN closed.\"\n}"}]},{"name":"List Warehouse Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]},"description":"Paginated warehouse locations (bins) with the cached per-location on-hand units (`on_hand`). Deprecated locations are hidden unless `include_deprecated` (top-level or inside `filter[]`) is truthy.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\nRequires the tenant to have warehouse locations enabled (`warehouse.locations` middleware).\n\nLocation types: staging, primary_pick, reserve, storage, shipping, returns, quarantine, damaged.\nAvailable sorts: code (default), type, created_at (prefix with - for descending)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"code\": \"A1-B2-S3-BIN4\",\n      \"zone\": \"A\",\n      \"aisle\": \"1\",\n      \"bay\": \"2\",\n      \"shelf\": \"3\",\n      \"bin\": \"4\",\n      \"type\": \"storage\",\n      \"type_label\": \"Storage\",\n      \"is_receivable\": true,\n      \"is_pickable\": true,\n      \"is_putaway_source\": false,\n      \"is_putaway_destination\": true,\n      \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n      \"sort_order\": 100,\n      \"is_default\": false,\n      \"deprecated_at\": null,\n      \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"on_hand\": 42,\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Warehouse Location","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations"]},"description":"Create a single warehouse location (bin). Provide either an explicit `code` or at least one of the segment fields (`zone`, `aisle`, `bay`, `shelf`, `bin`) from which a code is derived.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody fields:\n- warehouse_id (required, integer, exists) — parent warehouse\n- code (string max 64, required_without_all:zone,aisle,bay,shelf,bin)\n- name (nullable, string max 255)\n- zone (nullable, string max 32)\n- aisle / bay / shelf / bin (nullable, string max 255)\n- type (required, enum: staging, primary_pick, reserve, storage, shipping, returns, quarantine, damaged)\n- is_receivable (optional, boolean) — bin can receive stock on inbound receipts\n- is_pickable (optional, boolean) — bin is eligible for order picking\n- is_putaway_source (optional, boolean) — stock can be drawn from this bin during put-away\n- is_putaway_destination (optional, boolean) — stock can be put away into this bin\n  When a capability flag is omitted it is seeded from the location `type` defaults; once set, receiving, picking and put-away routing follow the flags, not the type.\n- barcode (nullable, string max 64)\n- sort_order (nullable, integer min 0)\n- is_default (boolean)\n\nReturns 201 with the created location; 422 if the tenant does not have locations enabled or the code/barcode conflicts.\n\n**Requires permission:** `warehouses.manage_locations`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"code\": \"A1-B2-S3-BIN4\",\n  \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n  \"zone\": \"A\",\n  \"aisle\": \"1\",\n  \"bay\": \"2\",\n  \"shelf\": \"3\",\n  \"bin\": \"4\",\n  \"type\": \"storage\",\n  \"is_receivable\": true,\n  \"is_pickable\": true,\n  \"is_putaway_source\": false,\n  \"is_putaway_destination\": true,\n  \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n  \"sort_order\": 100,\n  \"is_default\": false,\n  \"is_sellable\": true,\n  \"capacity_qty\": 100,\n  \"abc_class\": \"A\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"code\": \"A1-B2-S3-BIN4\",\n    \"zone\": \"A\",\n    \"aisle\": \"1\",\n    \"bay\": \"2\",\n    \"shelf\": \"3\",\n    \"bin\": \"4\",\n    \"type\": \"storage\",\n    \"type_label\": \"Storage\",\n    \"is_receivable\": true,\n    \"is_pickable\": true,\n    \"is_putaway_source\": false,\n    \"is_putaway_destination\": true,\n    \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n    \"sort_order\": 100,\n    \"is_default\": false,\n    \"deprecated_at\": null,\n    \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"on_hand\": 42,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Location created successfully.\"\n}"}]},{"name":"Bulk Generate Warehouse Locations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/bulk-generate","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","bulk-generate"]},"description":"Generate a range of locations from segment patterns. With `preview: true` the response returns `{codes_sample, total, conflicts}` without persisting; otherwise the non-conflicting codes are inserted and the response returns `{created, skipped_codes}`.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody fields:\n- warehouse_id (required, integer, exists)\n- type (required, enum: staging, primary_pick, reserve, storage, shipping, returns, quarantine, damaged)\n- Generated bins seed their capability flags (is_receivable, is_pickable, is_putaway_source, is_putaway_destination) from the chosen `type`; adjust per bin afterwards via Update.\n- zone (nullable, string max 32)\n- segments (required array, 1-6 items). Each segment:\n    - kind (required, one of: literal | letters | numbers)\n    - value (required when kind=literal, string max 32)\n    - from / to (required unless kind=literal) — range bounds\n    - pad (boolean) — zero/left pad range values to equal width\n- preview (boolean) — dry-run without persisting\n\n**Requires permission:** `warehouses.manage_locations`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"type\": \"storage\",\n  \"zone\": \"A\",\n  \"segments\": [\n    {\n      \"kind\": \"literal\",\n      \"value\": \"A\"\n    },\n    {\n      \"kind\": \"numbers\",\n      \"from\": 1,\n      \"to\": 10,\n      \"pad\": true\n    },\n    {\n      \"kind\": \"letters\",\n      \"from\": \"A\",\n      \"to\": \"C\"\n    }\n  ],\n  \"preview\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/bulk-generate","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","bulk-generate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"codes_sample\": [\n      \"A-01-A\",\n      \"A-01-B\",\n      \"A-01-C\",\n      \"A-02-A\"\n    ],\n    \"total\": 30,\n    \"conflicts\": [\n      \"A-01-A\"\n    ]\n  }\n}"}]},{"name":"Import Warehouse Locations","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/import","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","import"]},"description":"CSV import of locations, upserting by the (warehouse, code) natural key. Small files run synchronously and return `{created, updated, skipped}`; large files are queued and return `{queued: true, tracked_job_log_id}` for the job list.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody (multipart/form-data):\n- warehouse_id (required, integer, exists)\n- file (required, CSV/TXT upload, max 10 MB)\n\n**Requires permission:** `warehouses.manage_locations`","body":{"mode":"formdata","formdata":[{"key":"warehouse_id","type":"text","value":""},{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/import","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"queued\": false,\n    \"created\": 12,\n    \"updated\": 3,\n    \"skipped\": []\n  },\n  \"message\": \"Imported 12 new, updated 3.\"\n}"}]},{"name":"Generate Location Labels","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/labels","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","labels"]},"description":"Generate a printable labels PDF (Code-128 barcode + code + type) for the selected locations. Returns a PDF/HTML label sheet as a binary download, NOT JSON.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody fields:\n- ids (required array, 1-500 items) — warehouse_location IDs to print","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/labels","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","labels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[Binary PDF label sheet download]"}]},{"name":"Get Warehouse Location","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]},"description":"Single warehouse location with its warehouse and the cached on-hand summary (`on_hand`).\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"code\": \"A1-B2-S3-BIN4\",\n    \"zone\": \"A\",\n    \"aisle\": \"1\",\n    \"bay\": \"2\",\n    \"shelf\": \"3\",\n    \"bin\": \"4\",\n    \"type\": \"storage\",\n    \"type_label\": \"Storage\",\n    \"is_receivable\": true,\n    \"is_pickable\": true,\n    \"is_putaway_source\": false,\n    \"is_putaway_destination\": true,\n    \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n    \"sort_order\": 100,\n    \"is_default\": false,\n    \"deprecated_at\": null,\n    \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"on_hand\": 42,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Warehouse Location","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]},"description":"Update a warehouse location. All fields are optional (`sometimes`); only provided fields are changed.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\nBody fields (all optional):\n- code (nullable, string max 64)\n- name (nullable, string max 255)\n- zone (nullable, string max 32)\n- aisle / bay / shelf / bin (nullable, string max 255)\n- type (enum: staging, primary_pick, reserve, storage, shipping, returns, quarantine, damaged)\n- is_receivable (optional, boolean) — bin can receive stock on inbound receipts\n- is_pickable (optional, boolean) — bin is eligible for order picking\n- is_putaway_source (optional, boolean) — stock can be drawn from this bin during put-away\n- is_putaway_destination (optional, boolean) — stock can be put away into this bin\n  When a capability flag is omitted it is seeded from the location `type` defaults; once set, receiving, picking and put-away routing follow the flags, not the type.\n- barcode (nullable, string max 64)\n- sort_order (nullable, integer min 0)\n- is_default (boolean)\n\n**Requires permission:** `warehouses.manage_locations`","body":{"mode":"raw","raw":"{\n  \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4 (renamed)\",\n  \"sort_order\": 120,\n  \"is_pickable\": false,\n  \"is_default\": true,\n  \"is_sellable\": true,\n  \"capacity_qty\": 100,\n  \"abc_class\": \"A\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"code\": \"A1-B2-S3-BIN4\",\n    \"zone\": \"A\",\n    \"aisle\": \"1\",\n    \"bay\": \"2\",\n    \"shelf\": \"3\",\n    \"bin\": \"4\",\n    \"type\": \"storage\",\n    \"type_label\": \"Storage\",\n    \"is_receivable\": true,\n    \"is_pickable\": true,\n    \"is_putaway_source\": false,\n    \"is_putaway_destination\": true,\n    \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n    \"sort_order\": 100,\n    \"is_default\": false,\n    \"deprecated_at\": null,\n    \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"on_hand\": 42,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Location updated successfully.\"\n}"}]},{"name":"Delete Warehouse Location","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]},"description":"Hard delete a warehouse location. Only allowed when the location has never been referenced by an inventory movement; otherwise a 422 is returned suggesting deprecation instead.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\n**Requires permission:** `warehouses.manage_locations`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Deprecate Warehouse Location","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}/deprecate","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation","deprecate"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]},"description":"Deprecate (soft-retire) a location so it is hidden from pickers and datatables but retains its history. Returns 422 if it is the last active storage location in the warehouse.\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\n**Requires permission:** `warehouses.manage_locations`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}/deprecate","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation","deprecate"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"code\": \"A1-B2-S3-BIN4\",\n    \"zone\": \"A\",\n    \"aisle\": \"1\",\n    \"bay\": \"2\",\n    \"shelf\": \"3\",\n    \"bin\": \"4\",\n    \"type\": \"storage\",\n    \"type_label\": \"Storage\",\n    \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n    \"sort_order\": 100,\n    \"is_default\": false,\n    \"deprecated_at\": \"2026-01-20T12:00:00.000000Z\",\n    \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"on_hand\": 42,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Location deprecated.\"\n}"}]},{"name":"Restore Warehouse Location","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}/restore","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation","restore"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]},"description":"Restore a previously deprecated location (clears `deprecated_at`).\n\nAuthentication: Requires Bearer token.\nScope: warehouses (read/write).\n\n**Requires permission:** `warehouses.manage_locations`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/{warehouseLocation}/restore","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations",":warehouseLocation","restore"],"variable":[{"key":"warehouseLocation","value":"12","description":"Warehouse location ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"code\": \"A1-B2-S3-BIN4\",\n    \"zone\": \"A\",\n    \"aisle\": \"1\",\n    \"bay\": \"2\",\n    \"shelf\": \"3\",\n    \"bin\": \"4\",\n    \"type\": \"storage\",\n    \"type_label\": \"Storage\",\n    \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n    \"sort_order\": 100,\n    \"is_default\": false,\n    \"deprecated_at\": null,\n    \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n    \"on_hand\": 42,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Location restored.\"\n}"}]},{"name":"Lookup Warehouse Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/lookup/warehouse-locations?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","lookup","warehouse-locations"],"query":[{"key":"warehouse_id","value":"1","description":"Required. Warehouse to list locations for.","disabled":true}]},"description":"Decorated location options for select/autocomplete components. Returns active (non-deprecated) locations of a warehouse in pick-path order (sort_order nulls-last, then code). Returns an empty list when the warehouse does not have locations enabled.\n\nWhen `product_id` is supplied each option is decorated with the live `available_quantity` from the location-quantity cache and a `display_text` (\"CODE (Type) — N units\").\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- warehouse_id (required, integer, exists)\n- capability (optional: receivable | pickable | put-away-to | put-away-from) — filters types via the capability matrix\n- type / type[] (optional, comma-separated or array) — explicit type filter, intersected with capability\n- search (optional, string max 255) — matches code, name or barcode\n- product_id (optional, integer, exists) — decorate options with available_quantity + display_text\n- limit (optional, integer 1-500, default 50)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/lookup/warehouse-locations?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","lookup","warehouse-locations"],"query":[{"key":"warehouse_id","value":"1","description":"Required. Warehouse to list locations for.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"code\": \"A1-B2-S3-BIN4\",\n      \"name\": \"Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"type\": \"storage\",\n      \"type_label\": \"Storage\",\n      \"display_name\": \"A1-B2-S3-BIN4 — Aisle 1 Bay 2 Shelf 3 Bin 4\",\n      \"barcode\": \"LOC-A1-B2-S3-BIN4\",\n      \"is_default\": false,\n      \"available_quantity\": 42,\n      \"display_text\": \"A1-B2-S3-BIN4 (Storage) — 42 units\"\n    }\n  ]\n}"}]},{"name":"Get Slotting Suggestions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/slotting-suggestions?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","slotting-suggestions"],"query":[{"key":"warehouse_id","value":"1","description":"Warehouse to analyse (required).","disabled":true}]},"description":"Velocity-aware slotting suggestions for a warehouse: stock whose bin doesn't match its ABC sales-velocity class, or that overfills a bin's capacity. Read-only — proposes moves, never makes them.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-locations/slotting-suggestions?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","v2","warehouse-locations","slotting-suggestions"],"query":[{"key":"warehouse_id","value":"1","description":"Warehouse to analyse (required).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-1\",\n      \"product_name\": \"Blue Widget\",\n      \"abc_classification\": \"A\",\n      \"warehouse_location_id\": 15,\n      \"bin_code\": \"ST-01\",\n      \"bin_type\": \"storage\",\n      \"quantity\": 80,\n      \"kind\": \"promote_to_pick_face\",\n      \"severity\": \"info\",\n      \"message\": \"Fast mover (class A) is not on a Primary Pick face — move it forward to speed picking.\"\n    },\n    {\n      \"product_id\": 57,\n      \"sku\": \"SLOW-9\",\n      \"product_name\": \"Slow Mover\",\n      \"abc_classification\": \"C\",\n      \"warehouse_location_id\": 9,\n      \"bin_code\": \"PP-02\",\n      \"bin_type\": \"primary_pick\",\n      \"quantity\": 4,\n      \"kind\": \"demote_from_pick_face\",\n      \"severity\": \"info\",\n      \"message\": \"Slow mover (class C) is on a Primary Pick face — free the face for a faster mover.\"\n    }\n  ]\n}"}]}]},{"name":"FIFO Layers","item":[{"name":"List FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers?sort=-fifo_layer_date&per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers"],"query":[{"key":"sort","value":"-fifo_layer_date","description":"Sort field. Prefix with - for descending. Options: id, fifo_layer_date, original_quantity, fulfilled_quantity, available_quantity, avg_cost, total_cost, condition, created_at, updated_at, warehouse_name, sku, product_name","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of FIFO inventory layers. Supports GroupedFilterSupport filter trees and sorting.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort options: id, fifo_layer_date, original_quantity, fulfilled_quantity, available_quantity, avg_cost, total_cost, condition, created_at, updated_at, warehouse_name, sku, product_name\n\nArchived layers are excluded by default."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers?sort=-fifo_layer_date&per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers"],"query":[{"key":"sort","value":"-fifo_layer_date","description":"Sort field. Prefix with - for descending. Options: id, fifo_layer_date, original_quantity, fulfilled_quantity, available_quantity, avg_cost, total_cost, condition, created_at, updated_at, warehouse_name, sku, product_name","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"product_id\": 15,\n      \"fifo_layer_date\": \"2024-03-01\",\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"product_barcode\": \"123456789\",\n      \"original_quantity\": 100,\n      \"fulfilled_quantity\": 35,\n      \"avg_cost\": \"4.5000\",\n      \"total_cost\": \"450.0000\",\n      \"origin\": {\n        \"link_type\": \"purchase_order\",\n        \"link_id\": 8,\n        \"name\": \"PO-0008\",\n        \"parent_link_id\": null,\n        \"detail_link_id\": null,\n        \"reference\": \"REF-123\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_fba\": false,\n      \"condition\": \"new\",\n      \"integration_unique_id\": null,\n      \"allocated_quantity\": 10,\n      \"available_quantity\": 55,\n      \"archived_at\": null,\n      \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n      \"updated_at\": \"2024-03-15T14:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Search FIFO Layers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers"]},"description":"Returns the same paginated list of FIFO cost layers as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against layer id, SKU, product name, and warehouse.\n\nText columns (`batch_number`, `product_name`, `sku`, `condition`, `source_type`, `link_type`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `original_quantity`, `fulfilled_quantity`, `avg_cost`, `total_cost`, `fifo_layer_date`, `created_at`, `updated_at`, `manufacture_date`, `expiry_date`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. Additional filters include `warehouse`, `availability`, `expiring_within_days`, and `archived`.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, fifo_layer_date, original_quantity, fulfilled_quantity, available_quantity, avg_cost, total_cost, condition, batch_number, manufacture_date, expiry_date, created_at, updated_at, warehouse_name, sku, product_name. Results default to `-fifo_layer_date`.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-fifo_layer_date\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"sku\",\n          \"operator\": \"is_one_of\",\n          \"value\": [\n            \"WIDGET-BLUE-01\",\n            \"WIDGET-RED-02\"\n          ]\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"avg_cost\",\n          \"operator\": \"between\",\n          \"value\": [\n            5,\n            20\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90312,\n      \"product_id\": 3312,\n      \"fifo_layer_date\": \"2026-05-01T00:00:00.000000Z\",\n      \"sku\": \"WIDGET-BLUE-01\",\n      \"product_name\": \"Blue Widget\",\n      \"product_barcode\": \"8801234567890\",\n      \"stock_uom_code\": \"EA\",\n      \"batch_number\": \"LOT-2026-05\",\n      \"manufacture_date\": \"2026-04-20\",\n      \"expiry_date\": \"2027-04-20\",\n      \"days_to_expiry\": 288,\n      \"lot_notes\": null,\n      \"original_quantity\": 20,\n      \"fulfilled_quantity\": 0,\n      \"avg_cost\": 13.75,\n      \"total_cost\": 275,\n      \"origin\": {\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceiptLine\",\n        \"link_id\": 55210,\n        \"name\": \"PO-1042\",\n        \"parent_link_id\": 1042,\n        \"detail_link_id\": null,\n        \"reference\": \"PO-1042\",\n        \"parent_reference\": \"PO-1042\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_fba\": false,\n      \"condition\": \"new\",\n      \"allocated_quantity\": 0,\n      \"available_quantity\": 20,\n      \"archived_at\": null,\n      \"created_at\": \"2026-05-01T10:22:00.000000Z\",\n      \"updated_at\": \"2026-05-01T10:22:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 40,\n  \"total\": 987,\n  \"next_page_url\": \"https://api.example.com/api/v2/fifo-layers?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Show FIFO Layer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]},"description":"Returns a single FIFO layer with product, warehouse, source-document link, and origin-movement relations loaded.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe `origin` block identifies the source document that created the layer and now includes `origin.movement` — the metadata of the inventory movement that created the layer (id, date, type, source link, quantity, unit_cost, inventory_status, reference, batch_number, expiry_date, warehouse, and warehouse_location). That origin movement is excluded from the layer's usage-movements listing by default, so its details are surfaced here instead.\n\nLot fields (`batch_number`, `manufacture_date`, `expiry_date`, `days_to_expiry`, `lot_notes`) are always included; `days_to_expiry` is a signed whole-day countdown (negative = already expired, null when the lot has no expiry).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"product_id\": 15,\n    \"fifo_layer_date\": \"2024-03-01\",\n    \"sku\": \"WIDGET-001\",\n    \"product_name\": \"Blue Widget\",\n    \"product_barcode\": \"123456789\",\n    \"stock_uom_code\": \"EA\",\n    \"batch_number\": \"LOT-2024-03-001\",\n    \"manufacture_date\": \"2024-02-28\",\n    \"expiry_date\": \"2025-02-28\",\n    \"days_to_expiry\": 226,\n    \"lot_notes\": null,\n    \"original_quantity\": 100,\n    \"fulfilled_quantity\": 35,\n    \"avg_cost\": \"4.5000\",\n    \"total_cost\": \"450.0000\",\n    \"cost_breakdown\": null,\n    \"origin\": {\n      \"link_type\": \"purchase_order\",\n      \"link_id\": 8,\n      \"name\": \"PO-0008\",\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"reference\": \"REF-123\",\n      \"parent_reference\": null,\n      \"movement\": {\n        \"id\": 187,\n        \"date\": \"2024-03-01T10:00:00.000000Z\",\n        \"type\": \"purchase_order_received\",\n        \"link_type\": \"purchase_order_shipment_item\",\n        \"link_id\": 91,\n        \"quantity\": 100,\n        \"unit_cost\": \"4.5000\",\n        \"inventory_status\": \"active\",\n        \"reference\": \"REF-123\",\n        \"batch_number\": \"LOT-2024-03-001\",\n        \"expiry_date\": \"2025-02-28\",\n        \"warehouse\": {\n          \"id\": 2,\n          \"name\": \"Main Warehouse\"\n        },\n        \"warehouse_location\": {\n          \"id\": 7,\n          \"code\": \"A-01-02\",\n          \"name\": \"Aisle A Bay 1 Shelf 2\"\n        }\n      }\n    },\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"is_fba\": false,\n    \"is_consignment\": false,\n    \"condition\": \"new\",\n    \"integration_unique_id\": null,\n    \"allocated_quantity\": 10,\n    \"available_quantity\": 65,\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-15T14:30:00.000000Z\"\n  }\n}"}]},{"name":"FIFO Layer Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/allocations","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","allocations"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]},"description":"Returns sales order line allocations for this FIFO layer — which sales orders have reserved quantity from this layer.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/allocations","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","allocations"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"quantity\": 10,\n      \"sales_order_line_id\": 55,\n      \"sales_order\": {\n        \"id\": 30,\n        \"order_number\": \"SO-0030\",\n        \"customer_id\": 7,\n        \"customer_name\": \"Acme Corp\",\n        \"order_status\": \"processing\"\n      },\n      \"product\": {\n        \"id\": 15,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Blue Widget\"\n      },\n      \"allocation_status\": \"allocated\",\n      \"created_at\": \"2024-03-10T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"FIFO Layer Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/inventory-movements","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","inventory-movements"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]},"description":"Paginated usage movements for a FIFO layer (standard paginated response: `data[]` plus `current_page`, `last_page`, `per_page`, `total`, ...).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe movement that originally created the layer is **excluded by default** — it is presented in the layer's `origin` block on the single-layer endpoint instead of as a usage. Pass `exclude_origin=0` to include it (e.g. to tally the layer's full movement history).\n\nFilters (server-side):\n- `filter[type]` — exact movement type match. Dotted operator variants are also available (`filter[type.is]`, `filter[type.contains]`, ...).\n- `filter[link_type]` — exact source-document type match.\n- `filter[inventory_status]` — defaults to `active`; pass `all` for no status restriction. Dotted operator variants (`filter[inventory_status.is]`, ...) are also available.\n- `filter[reference]` — text operator filters (`filter[reference.contains]`, ...).\n- `filter[quantity]` — numeric operator filters (`filter[quantity.gte]`, ...).\n- `filter[inventory_movement_date]`, `filter[created_at]` — date operator filters (`.on`, `.before`, `.after`, `.between`).\n- `filter[search]` — searches ID (exact), Reference, SKU, and Product Name.\n\nAllowed sorts: id, inventory_movement_date, type, inventory_status, quantity, reference, created_at (prefix with - for descending; default: -inventory_movement_date).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/inventory-movements","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","inventory-movements"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"inventory_movement_date\": \"2024-03-12T11:00:00.000000Z\",\n      \"product_id\": 15,\n      \"sku\": \"WIDGET-001\",\n      \"barcode\": \"123456789\",\n      \"product_name\": \"Blue Widget\",\n      \"stock_uom_code\": \"EA\",\n      \"type\": {\n        \"name\": \"fulfillment\",\n        \"link_type\": \"sales_order_fulfillment_line\",\n        \"link_id\": 3411,\n        \"parent_link_id\": 812,\n        \"detail_link_id\": null\n      },\n      \"inventory_status\": \"active\",\n      \"quantity\": -5,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"layer\": {\n        \"fifo_layer_id\": 42,\n        \"name\": \"PO-0008\"\n      },\n      \"fifo_layer_id\": 42,\n      \"reference\": \"SO-1042\",\n      \"created_at\": \"2024-03-12T11:00:00.000000Z\",\n      \"updated_at\": \"2024-03-12T11:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 35,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Archive FIFO Layer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/archive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","archive"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]},"description":"Archives a single FIFO layer. Only fully utilized layers (available_quantity = 0) can be archived.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/archive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","archive"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FIFO Layer 42 has been archived.\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": \"2024-03-20T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive FIFO Layer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/unarchive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","unarchive"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]},"description":"Unarchives a previously archived FIFO layer.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/{fifoLayer}/unarchive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers",":fifoLayer","unarchive"],"variable":[{"key":"fifoLayer","value":"42","description":"FIFO Layer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FIFO Layer 42 has been unarchived.\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive FIFO Layers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/archive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers","archive"]},"description":"Archives multiple FIFO layers. Only fully utilized layers (available_quantity = 0) can be archived. Use apply_to_all with filters to archive all matching layers.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (required_without:apply_to_all, array): Array of FIFO layer IDs\n- apply_to_all (nullable, boolean): If true, archive all layers matching filters\n- filters (nullable, array): Filter criteria when using apply_to_all","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/archive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 of 2 fifo layers have been archived successfully.\"\n}"}]},{"name":"Bulk Unarchive FIFO Layers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/unarchive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers","unarchive"]},"description":"Unarchives multiple FIFO layers.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (required_without:apply_to_all, array): Array of FIFO layer IDs\n- apply_to_all (nullable, boolean): If true, unarchive all matching layers\n- filters (nullable, array): Filter criteria when using apply_to_all","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/fifo-layers/unarchive","host":["{{baseUrl}}"],"path":["api","v2","fifo-layers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 of 2 fifo layers have been un-archived successfully.\"\n}"}]}]},{"name":"Customers","item":[{"name":"List Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","customers"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of customers.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","customers"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"name\": \"Acme Corp\",\n      \"email\": \"orders@acme.com\",\n      \"phone\": \"+1-555-0100\",\n      \"created_at\": \"2023-06-15T08:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T12:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 25\n}"}]},{"name":"Show Customer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer"],"variable":[{"key":"customer","value":"7","description":"Customer ID"}]},"description":"Returns a single customer.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse the `with` query parameter (comma-separated) to include relations: `salesChannelOrigin`, `productPricingTier`, `store`, `shippingMethodDomestic`, `shippingMethodInternational`, `warehouse`, `defaultSalesRep`, `defaultIncoterm`, `integrationInstance`, `shippingAddress`, `billingAddress`, `addresses`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer"],"variable":[{"key":"customer","value":"7","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Acme Corp\",\n    \"email\": \"orders@acme.com\",\n    \"phone\": \"+1-555-0100\",\n    \"created_at\": \"2023-06-15T08:00:00.000000Z\",\n    \"updated_at\": \"2024-01-10T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Customer Lookup (Quick Search)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/lookup","host":["{{baseUrl}}"],"path":["api","customers","lookup"]},"description":"Lightweight customer quick-search used by the POS register to attach a customer at checkout. Returns a compact card per customer including the live store-credit wallet balance (summed in one join, N+1-safe), the assigned pricing tier, and tax-exemption status. Archived customers are excluded.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nQuery params: `q` (optional; matches name/company/email/phone), `limit` (optional; 1–50, default 15).\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/lookup","host":["{{baseUrl}}"],"path":["api","customers","lookup"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"name\": \"Ada Lovelace\",\n      \"company\": \"Analytical Engines\",\n      \"email\": \"ada@example.com\",\n      \"phone\": \"5550100\",\n      \"tax_exempt\": false,\n      \"tax_exemption_reference\": null,\n      \"product_pricing_tier_id\": 3,\n      \"pricing_tier_name\": \"Wholesale\",\n      \"store_credit_balance\": 42.5,\n      \"loyalty_points_balance\": 250,\n      \"house_account_enabled\": true,\n      \"credit_limit\": 5000,\n      \"house_account_balance\": 1200.5,\n      \"billing_email\": \"ap@acme-wholesale.com\",\n      \"payment_terms_days\": 30\n    },\n    {\n      \"id\": 502,\n      \"name\": \"Ada Byron\",\n      \"company\": null,\n      \"email\": \"byron@example.com\",\n      \"phone\": \"5550111\",\n      \"tax_exempt\": true,\n      \"tax_exemption_reference\": \"RESALE-12345\",\n      \"product_pricing_tier_id\": null,\n      \"pricing_tier_name\": null,\n      \"store_credit_balance\": 0,\n      \"loyalty_points_balance\": 250,\n      \"house_account_enabled\": true,\n      \"credit_limit\": 5000,\n      \"house_account_balance\": 1200.5,\n      \"billing_email\": \"ap@acme-wholesale.com\",\n      \"payment_terms_days\": 30\n    }\n  ]\n}"}]},{"name":"List Duplicate Customer Pairs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/duplicate-runs/{trackedJobLog}/pairs","host":["{{baseUrl}}"],"path":["api","v2","customers","duplicate-runs",":trackedJobLog","pairs"],"variable":[{"key":"trackedJobLog","value":"9451","description":"Detection run ID - the tracked_job_log_id returned when the run was started"}]},"description":"List the candidate duplicate pairs produced by a completed detection run, hydrated with each customer's identifying details for side-by-side comparison. Pairs are ordered by match score (highest first) and paginated; pairs that have since been marked 'not a duplicate' are excluded from the results.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach pair contains: customer_a and customer_b detail cards, the 0-100 match score, a bucket ('auto' = score of 90 or higher, 'review' = 60 or higher, 'hidden' otherwise), and the per-field scoring signals (field, score, weight, contribution, note).\n\nFor runs with scope 'sku' the cards include the sales order count and last order date. For scope 'qbo' the cards include the QuickBooks customer details (display name, company, given/family name, linked customer ID, active flag).\n\nIf the run has not completed or produced no results, an empty list is returned with meta.total = 0.\n\nPagination: page (default 1) and per_page (default 25).\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers/duplicate-runs/{trackedJobLog}/pairs","host":["{{baseUrl}}"],"path":["api","v2","customers","duplicate-runs",":trackedJobLog","pairs"],"variable":[{"key":"trackedJobLog","value":"9451","description":"Detection run ID - the tracked_job_log_id returned when the run was started"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"customer_a\": {\n        \"id\": 101,\n        \"name\": \"John Smith\",\n        \"company\": \"Acme Corp\",\n        \"email\": \"john@acmecorp.com\",\n        \"phone\": \"+1-555-0101\",\n        \"address\": \"500 Industrial Way, 91201\",\n        \"archived_at\": null,\n        \"sales_orders_count\": 14,\n        \"last_order_date\": \"2026-06-12\"\n      },\n      \"customer_b\": {\n        \"id\": 2384,\n        \"name\": \"John A. Smith\",\n        \"company\": \"Acme Corporation\",\n        \"email\": \"john@acmecorp.com\",\n        \"phone\": null,\n        \"address\": null,\n        \"archived_at\": null,\n        \"sales_orders_count\": 2,\n        \"last_order_date\": \"2025-11-03\"\n      },\n      \"score\": 91,\n      \"bucket\": \"auto\",\n      \"signals\": [\n        {\n          \"field\": \"email\",\n          \"score\": 1,\n          \"weight\": 50,\n          \"contribution\": 50,\n          \"note\": null\n        },\n        {\n          \"field\": \"company\",\n          \"score\": 0.97,\n          \"weight\": 30,\n          \"contribution\": 29.1,\n          \"note\": \"fuzzy_company_high\"\n        },\n        {\n          \"field\": \"name\",\n          \"score\": 0.8,\n          \"weight\": 15,\n          \"contribution\": 12,\n          \"note\": null\n        },\n        {\n          \"field\": \"address\",\n          \"score\": 0,\n          \"weight\": 3,\n          \"contribution\": 0,\n          \"note\": null\n        },\n        {\n          \"field\": \"phone\",\n          \"score\": 0,\n          \"weight\": 2,\n          \"contribution\": 0,\n          \"note\": null\n        }\n      ]\n    }\n  ],\n  \"meta\": {\n    \"total\": 37,\n    \"pairs_count\": 40,\n    \"page\": 1,\n    \"per_page\": 25,\n    \"last_page\": 2,\n    \"scope\": \"sku\",\n    \"integration_instance_id\": null\n  }\n}"}]},{"name":"Export Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/export","host":["{{baseUrl}}"],"path":["api","v2","customers","export"]},"description":"Download all customers matching the current filters as a spreadsheet file (CSV by default, XLSX when format=xlsx). The file contains the columns: Sr No., id, name, company, email, sales_channel_origin_name, integration_instance_name, created_at, updated_at. Rows are ordered by customer ID ascending and the export is not paginated - every matching customer is included.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nPrivacy: customers originating from Amazon are redacted - the row keeps its serial number but every other column is blank.\n\nTimestamps in the file are converted to the account's local timezone (matching on-screen values).\n\nFiltering uses operator-style parameters: filter[column.operator]=value. A bare filter[column]=value acts as the 'is' operator.\n\nText columns (name, email, company, phone, city, province, country) support: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty. The city, province, and country filters match the customer's default shipping address.\n\nDate columns (created_at, updated_at, archived_at) support: is, is_not, before, after, on_or_before, on_or_after, between (two comma-separated dates), is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days. Dates use YYYY-MM-DD format and are interpreted in the account's local timezone.\n\nArchived customers are excluded unless filter[archived] is provided ('only' = archived customers only, 'all' = archived and active).\n\nThe response is a file download (Content-Type: text/csv or the XLSX MIME type), not JSON.\n\nAuthentication: Requires Bearer token with the customers read/write scope.\n\nOptional. When `include_contacts=1`, the export flattens to one row per contact with the parent columns repeated (parent-only row when a record has no contacts), appending Contact ID/Name/Email/Phone/Role/Title/Primary/Notes columns."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers/export","host":["{{baseUrl}}"],"path":["api","v2","customers","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Sr No.,id,name,company,email,sales_channel_origin_name,integration_instance_name,created_at,updated_at\n1,101,John Smith,Acme Corp,john@acmecorp.com,Shopify,Acme Shopify Store,2026-01-14 09:32:11,2026-06-02 15:04:27\n2,,,,,,,,\n3,214,Jane Rivera,Rivera Trading,jane@riveratrading.com,,,2026-02-20 11:05:44,2026-02-20 11:05:44\n\n(CSV file download named customers-2026-07-07-14-21-05.csv. Row 2 is an Amazon-origin customer redacted for privacy.)"}]},{"name":"Mark Customer Pair as Not Duplicate","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/dedup-decisions","host":["{{baseUrl}}"],"path":["api","v2","customers","dedup-decisions"]},"description":"Record a decision that two customers are not duplicates of each other, so the pair stops appearing in duplicate detection results. The decision is order-independent (the pair is stored with the lower ID first) and idempotent - repeating the call for the same pair returns the existing decision.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFor scope 'qbo', the IDs refer to customer records synced from the connected QuickBooks Online instance identified by integration_instance_id.\n\nBody fields:\n- customer_id_a (integer, required): first customer of the pair.\n- customer_id_b (integer, required): second customer of the pair; must differ from customer_id_a.\n- scope (string, required): 'sku' or 'qbo'.\n- integration_instance_id (integer, optional): the connected integration instance the decision applies to (used with scope 'qbo'); must reference an existing integration instance.\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission.","body":{"mode":"raw","raw":"{\n  \"customer_id_a\": 101,\n  \"customer_id_b\": 2384,\n  \"scope\": \"sku\",\n  \"integration_instance_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/dedup-decisions","host":["{{baseUrl}}"],"path":["api","v2","customers","dedup-decisions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"scope\": \"sku\"\n  },\n  \"message\": \"Marked as not duplicate.\"\n}"}]},{"name":"Start Customer Duplicate Detection Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/duplicate-runs","host":["{{baseUrl}}"],"path":["api","v2","customers","duplicate-runs"]},"description":"Start an asynchronous duplicate-detection run over customer records. The work is dispatched to a background job and the endpoint returns immediately with a tracked_job_log_id. Once the run completes, fetch the scored candidate pairs from the List Duplicate Customer Pairs endpoint using that ID.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nScopes:\n- sku - scans the account's own customer records.\n- qbo - scans customer records synced from a connected QuickBooks Online instance (integration_instance_id is required for this scope).\n\nCandidates are grouped by normalized email and company, then each pair is scored 0-100 across weighted signals (email, company, name, address, phone). Only pairs scoring at or above the threshold (default 80) are kept, and pairs previously marked 'not a duplicate' are excluded.\n\nBody fields:\n- scope (string, required): 'sku' or 'qbo'.\n- integration_instance_id (integer, optional): required when scope is 'qbo'; must reference a connected integration instance.\n- threshold (integer, optional): minimum match score (0-100) for a pair to be included. Default: 80.\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission.","body":{"mode":"raw","raw":"{\n  \"scope\": \"sku\",\n  \"integration_instance_id\": null,\n  \"threshold\": 80\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/duplicate-runs","host":["{{baseUrl}}"],"path":["api","v2","customers","duplicate-runs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9451\n  },\n  \"message\": \"Duplicate detection started\"\n}"}]},{"name":"Merge Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/merge","host":["{{baseUrl}}"],"path":["api","v2","customers","merge"]},"description":"Merge the secondary customer into the primary customer. This is a destructive operation performed in a single transaction:\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n- All related records - sales orders, sales credits, customer SKU mappings, order document extractions, and linked QuickBooks customer records - are reassigned from the secondary to the primary customer.\n- Contact fields (email, company, phone, fax, tax number, default shipping/billing address) are copied from the secondary onto the primary only where the primary's value is empty; existing primary data is never overwritten.\n- The secondary customer is archived.\n- A merge log is written capturing a snapshot of both customers and the per-table reassignment counts (fk_moves).\n\nThe returned merge_log_id can be used to reverse the merge within 30 days via Undo Customer Merge. The request fails if the secondary customer is already archived.\n\nBody fields:\n- primary_customer_id (integer, required): the customer to keep; must reference an existing customer.\n- secondary_customer_id (integer, required): the customer to merge away; must reference an existing customer and differ from primary_customer_id.\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission.","body":{"mode":"raw","raw":"{\n  \"primary_customer_id\": 101,\n  \"secondary_customer_id\": 2384\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/merge","host":["{{baseUrl}}"],"path":["api","v2","customers","merge"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"merge_log_id\": 12,\n    \"fk_moves\": {\n      \"sales_orders\": 14,\n      \"sales_credits\": 2,\n      \"customer_sku_mappings\": 0,\n      \"sales_order_ocr_extractions\": 1,\n      \"qbo_customers\": 1\n    }\n  },\n  \"message\": \"Customers merged successfully.\"\n}"}]},{"name":"Undo Customer Merge","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/merge-logs/{mergeLog}/undo","host":["{{baseUrl}}"],"path":["api","v2","customers","merge-logs",":mergeLog","undo"],"variable":[{"key":"mergeLog","value":"12","description":"Merge log ID returned by the merge endpoint"}]},"description":"Reverse a previous customer merge: un-archives the secondary customer and moves the records that were reassigned during the merge back to it.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA merge can only be reversed once, and only within 30 days of the original merge; attempting to reverse an already-reversed or expired merge fails. Use the merge_log_id returned by Merge Customers as the path parameter.\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/merge-logs/{mergeLog}/undo","host":["{{baseUrl}}"],"path":["api","v2","customers","merge-logs",":mergeLog","undo"],"variable":[{"key":"mergeLog","value":"12","description":"Merge log ID returned by the merge endpoint"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"merge_log_id\": 12,\n    \"reversed_at\": \"2026-07-07T14:21:05+00:00\"\n  },\n  \"message\": \"Merge reversed.\"\n}"}]},{"name":"Preview Customer Merge","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/merge/preview","host":["{{baseUrl}}"],"path":["api","v2","customers","merge","preview"]},"description":"Preview the effect of merging one customer (secondary) into another (primary) without changing any data. Returns, per related record type, the number of records currently attached to the secondary customer that would be reassigned to the primary: sales orders (sales_orders), sales credits (sales_credits), customer SKU mappings (customer_sku_mappings), order document extractions (sales_order_ocr_extractions), and linked QuickBooks customer records (qbo_customers).\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse this before calling Merge Customers so the operator can review what will move.\n\nBody fields:\n- primary_customer_id (integer, required): the customer that will be kept; must reference an existing customer.\n- secondary_customer_id (integer, required): the customer that will be merged away; must reference an existing customer and differ from primary_customer_id.\n\nAuthentication: Requires Bearer token with the customers read/write scope and the customer merge permission.","body":{"mode":"raw","raw":"{\n  \"primary_customer_id\": 101,\n  \"secondary_customer_id\": 2384\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/merge/preview","host":["{{baseUrl}}"],"path":["api","v2","customers","merge","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fk_moves\": {\n      \"sales_orders\": 14,\n      \"sales_credits\": 2,\n      \"customer_sku_mappings\": 0,\n      \"sales_order_ocr_extractions\": 1,\n      \"qbo_customers\": 1\n    }\n  }\n}"}]},{"name":"Create Customer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers","host":["{{baseUrl}}"],"path":["api","customers"]},"description":"Create a new customer. Automatically creates a default shipping address from the root address fields. Optionally provide a separate billing address.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOptional fields:\n- tags: Customer tags (array of tag names, max 64 chars each). Omit to leave existing tags unchanged; send an array to replace them. Unknown names are created automatically.\n\nValidation notes:\n- Email must be unique across all customer addresses\n- If a customer with the same name/zip/address1 already exists, returns a 422 with CODE_CUSTOMER_EXISTS","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Smith\",\n  \"company\": \"Smith Industries\",\n  \"email\": \"jane.smith@smithindustries.com\",\n  \"phone\": \"+1-555-0200\",\n  \"fax\": null,\n  \"address1\": \"456 Commerce Ave\",\n  \"address2\": \"Suite 100\",\n  \"address3\": null,\n  \"city\": \"Los Angeles\",\n  \"province\": \"California\",\n  \"province_code\": \"CA\",\n  \"zip\": \"90001\",\n  \"country\": \"United States\",\n  \"country_code\": \"US\",\n  \"integration_instance_id\": null,\n  \"default_sales_rep_id\": null,\n  \"default_billing_address\": {\n    \"name\": \"Jane Smith\",\n    \"company\": \"Smith Industries\",\n    \"email\": \"billing@smithindustries.com\",\n    \"phone\": \"+1-555-0201\",\n    \"address1\": \"789 Billing Blvd\",\n    \"city\": \"Los Angeles\",\n    \"province\": \"California\",\n    \"province_code\": \"CA\",\n    \"zip\": \"90002\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\"\n  },\n  \"billing_email\": \"ap@acme-wholesale.com\",\n  \"payment_terms_days\": 30,\n  \"tags\": [\n    \"VIP\",\n    \"Wholesale\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers","host":["{{baseUrl}}"],"path":["api","customers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Smith\",\n    \"email\": \"jane.smith@smithindustries.com\",\n    \"company\": \"Smith Industries\"\n  },\n  \"message\": \"customer created successfully\"\n}"}]},{"name":"Bulk Delete Customers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers","host":["{{baseUrl}}"],"path":["api","customers"]},"description":"Bulk delete customers by IDs or by applying to all filtered results.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/customers","host":["{{baseUrl}}"],"path":["api","customers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 customers deleted successfully.\"\n}"}]},{"name":"Get Customer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Get a single customer with all related data including addresses, billing/shipping addresses, default settings, and lifetime value.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"John Doe\",\n    \"email\": \"john.doe@example.com\",\n    \"lifetime_value\": 12500,\n    \"tags\": [\n      \"VIP\",\n      \"Wholesale\"\n    ]\n  }\n}"}]},{"name":"Update Customer","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Update an existing customer. All fields are optional. Default settings (pricing tier, store, shipping methods, warehouse) can only be set on update.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOptional fields:\n- tags: Customer tags (array of tag names, max 64 chars each). Omit to leave existing tags unchanged; send an array to replace them. Unknown names are created automatically.","body":{"mode":"raw","raw":"{\n  \"name\": \"John Doe Updated\",\n  \"company\": \"Acme Corp International\",\n  \"email\": \"john.doe@acmecorp.com\",\n  \"phone\": \"+1-555-0101\",\n  \"product_pricing_tier_id\": 2,\n  \"store_id\": 1,\n  \"shipping_method_domestic_id\": 3,\n  \"shipping_method_international_id\": 5,\n  \"warehouse_id\": 1,\n  \"billing_email\": \"ap@acme-wholesale.com\",\n  \"payment_terms_days\": 30,\n  \"tags\": [\n    \"VIP\",\n    \"Wholesale\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"John Doe Updated\"\n  },\n  \"message\": \"customer John Doe Updated updated successfully\"\n}"}]},{"name":"Delete Customer","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Delete a customer. Returns 400 if the customer is linked to sales orders or other records.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/customers/{customer}","host":["{{baseUrl}}"],"path":["api","customers",":customer"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"customer deleted successfully\"\n}"}]},{"name":"Get Customer Addresses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Retrieve all addresses associated with a customer including default shipping, billing, and other addresses.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"John Doe\",\n    \"addresses\": []\n  }\n}"}]},{"name":"Add Customer Address","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Add a new address to a customer. Address deduplication is applied.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"raw","raw":"{\n  \"label\": \"Warehouse Address\",\n  \"name\": \"John Doe\",\n  \"company\": \"Acme Corp\",\n  \"email\": \"warehouse@acmecorp.com\",\n  \"phone\": \"+1-555-0102\",\n  \"address1\": \"500 Industrial Way\",\n  \"city\": \"Glendale\",\n  \"province\": \"California\",\n  \"province_code\": \"CA\",\n  \"zip\": \"91201\",\n  \"country\": \"United States\",\n  \"country_code\": \"US\",\n  \"is_default_shipping\": false,\n  \"is_default_billing\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"John Doe\",\n    \"addresses\": []\n  }\n}"}]},{"name":"Set Default Shipping Address","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/set-default-shipping-address/{address_id}","host":["{{baseUrl}}"],"path":["api","customers",":customer","set-default-shipping-address",":address_id"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address_id","value":"2","description":"Address ID"}]},"description":"Set a specific address as the customer's default shipping address.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}/set-default-shipping-address/{address_id}","host":["{{baseUrl}}"],"path":["api","customers",":customer","set-default-shipping-address",":address_id"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address_id","value":"2","description":"Address ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Default shipping address set.\"\n}"}]},{"name":"Set Default Billing Address","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/set-default-billing-address/{address_id}","host":["{{baseUrl}}"],"path":["api","customers",":customer","set-default-billing-address",":address_id"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address_id","value":"2","description":"Address ID"}]},"description":"Set a specific address as the customer's default billing address.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}/set-default-billing-address/{address_id}","host":["{{baseUrl}}"],"path":["api","customers",":customer","set-default-billing-address",":address_id"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address_id","value":"2","description":"Address ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Default billing address set.\"\n}"}]},{"name":"Delete Customer Address","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses/{address}","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses",":address"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address","value":"10","description":"Address ID to remove from the customer"}]},"description":"Remove an address from a customer's address book. If the removed address was the customer's default shipping or billing address, the most recently added remaining address is automatically promoted as the new default (or the default is cleared when no other address exists). The underlying address record is permanently deleted only when no other records (other customers, sales orders, etc.) still reference it; otherwise only the customer's link to it is removed.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the customer's refreshed address book.\n\nAuthentication: Requires Bearer token with the customers read/write scope."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/customers/{customer}/addresses/{address}","host":["{{baseUrl}}"],"path":["api","customers",":customer","addresses",":address"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"address","value":"10","description":"Address ID to remove from the customer"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"John Doe\",\n    \"email\": \"john.doe@acmecorp.com\",\n    \"zip\": \"91201\",\n    \"address1\": \"500 Industrial Way\",\n    \"addresses\": [\n      {\n        \"id\": 12,\n        \"label\": \"Head Office\",\n        \"name\": \"John Doe\",\n        \"company\": \"Acme Corp\",\n        \"email\": \"john.doe@acmecorp.com\",\n        \"phone\": \"+1-555-0102\",\n        \"address1\": \"500 Industrial Way\",\n        \"address2\": null,\n        \"city\": \"Glendale\",\n        \"province\": \"California\",\n        \"province_code\": \"CA\",\n        \"zip\": \"91201\",\n        \"country\": \"United States\",\n        \"country_code\": \"US\",\n        \"is_default_shipping\": true,\n        \"is_default_billing\": true\n      }\n    ]\n  },\n  \"message\": \"The address Warehouse Address deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Customers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/archive","host":["{{baseUrl}}"],"path":["api","customers","archive"]},"description":"Bulk archive customers by IDs or by applying to all filtered results.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4,\n    5,\n    6\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/archive","host":["{{baseUrl}}"],"path":["api","customers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 customers archived successfully.\"\n}"}]},{"name":"Bulk Unarchive Customers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/unarchive","host":["{{baseUrl}}"],"path":["api","customers","unarchive"]},"description":"Bulk unarchive customers by IDs or by applying to all filtered results.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4,\n    5,\n    6\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/unarchive","host":["{{baseUrl}}"],"path":["api","customers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 customers unarchived successfully.\"\n}"}]},{"name":"Check Deletable Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/deletable","host":["{{baseUrl}}"],"path":["api","customers","deletable"]},"description":"Check which customers can be deleted. Returns deletability status for each customer.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"scope\": \"ids\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/deletable","host":["{{baseUrl}}"],"path":["api","customers","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"John Doe\",\n      \"deletable\": false,\n      \"reason\": \"Linked to sales orders\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Jane Smith\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Archive Customer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/archive","host":["{{baseUrl}}"],"path":["api","customers",":customer","archive"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Archive a single customer.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}/archive","host":["{{baseUrl}}"],"path":["api","customers",":customer","archive"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"customer John Doe archived successfully\"\n}"}]},{"name":"Unarchive Customer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/unarchived","host":["{{baseUrl}}"],"path":["api","customers",":customer","unarchived"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Unarchive a previously archived customer.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}/unarchived","host":["{{baseUrl}}"],"path":["api","customers",":customer","unarchived"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"customer John Doe unarchived successfully\"\n}"}]},{"name":"Preview Customers Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/customers/import/preview","host":["{{baseUrl}}"],"path":["api","customers","import","preview"]},"description":"Preview a customer import from a CSV file before committing.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/import/preview","host":["{{baseUrl}}"],"path":["api","customers","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 50,\n    \"valid\": 48,\n    \"errors\": 2\n  }\n}"}]},{"name":"Import Customers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/customers/import","host":["{{baseUrl}}"],"path":["api","customers","import"]},"description":"Import customers from a CSV file.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/import","host":["{{baseUrl}}"],"path":["api","customers","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 48,\n    \"skipped\": 2,\n    \"errors\": []\n  },\n  \"message\": \"Import completed successfully\"\n}"}]},{"name":"Find Customer Match","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/find-match?name=John Doe&zip=90210&address1=123 Main St","host":["{{baseUrl}}"],"path":["api","customers","find-match"],"query":[{"key":"name","value":"John Doe","description":"Customer name (required)","disabled":true},{"key":"zip","value":"90210","description":"ZIP code (required)","disabled":true},{"key":"address1","value":"123 Main St","description":"Address line 1 (required) — uses 90% fuzzy match","disabled":true}]},"description":"Find customer matches based on name, ZIP code, and address. Uses approximate matching (90% match on address1).\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/find-match?name=John Doe&zip=90210&address1=123 Main St","host":["{{baseUrl}}"],"path":["api","customers","find-match"],"query":[{"key":"name","value":"John Doe","description":"Customer name (required)","disabled":true},{"key":"zip","value":"90210","description":"ZIP code (required)","disabled":true},{"key":"address1","value":"123 Main St","description":"Address line 1 (required) — uses 90% fuzzy match","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"John Doe\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Open Sales Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/open-sales-credits","host":["{{baseUrl}}"],"path":["api","customers",":customer","open-sales-credits"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Get all open (un-fully-allocated) sales credits for a customer.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/open-sales-credits","host":["{{baseUrl}}"],"path":["api","customers",":customer","open-sales-credits"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"sales_credit_number\": \"SC-0005\",\n      \"total_credit\": 250,\n      \"status\": \"open\"\n    }\n  ]\n}"}]},{"name":"Get Unpaid Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/unpaid-orders","host":["{{baseUrl}}"],"path":["api","customers",":customer","unpaid-orders"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Get all unpaid sales orders for a customer.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/unpaid-orders","host":["{{baseUrl}}"],"path":["api","customers",":customer","unpaid-orders"],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"sales_order_number\": \"SO-0010\",\n      \"total\": 500,\n      \"total_paid\": 0\n    }\n  ]\n}"}]},{"name":"Allocate Sales Credit to Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/sales-credits/{salesCredit}/allocate","host":["{{baseUrl}}"],"path":["api","customers",":customer","sales-credits",":salesCredit","allocate"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"salesCredit","value":"5","description":"Sales Credit ID"}]},"description":"Allocate an open sales credit to one or more sales orders.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sales_orders\": [\n    {\n      \"id\": 10,\n      \"amount\": 250\n    },\n    {\n      \"id\": 11,\n      \"amount\": 100\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/sales-credits/{salesCredit}/allocate","host":["{{baseUrl}}"],"path":["api","customers",":customer","sales-credits",":salesCredit","allocate"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"salesCredit","value":"5","description":"Sales Credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sales credit allocated successfully.\"\n}"}]},{"name":"Unallocate Sales Credit from Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/sales-credits/{salesCredit}/allocations/{allocation}","host":["{{baseUrl}}"],"path":["api","customers",":customer","sales-credits",":salesCredit","allocations",":allocation"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"salesCredit","value":"5","description":"Sales Credit ID"},{"key":"allocation","value":"12","description":"Sales Credit Allocation ID"}]},"description":"Reverse a single sales credit allocation. Deletes the allocation row, reverses the corresponding Credit-type Payment recorded against the sales order, and recalculates the credit's payment_status (paid → partially_paid or open).\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIf the allocation was previously synced to QuickBooks Online, a background job is dispatched after the local DB transaction commits to delete the paired QBO Payment.\n\nScoping behavior:\n- Returns 404 if the credit does not belong to the customer in the URL\n- Returns 404 if the allocation does not belong to the credit in the URL\n\nValidation:\n- Returns 422 if the sales credit is archived (unarchive before reversing allocations)\n- Returns 422 if the allocation has already been synced to Xero (Xero CreditNote Allocations are functionally immutable once accepted — unallocate in Xero first, then refresh)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/customers/{customer}/sales-credits/{salesCredit}/allocations/{allocation}","host":["{{baseUrl}}"],"path":["api","customers",":customer","sales-credits",":salesCredit","allocations",":allocation"],"variable":[{"key":"customer","value":"1","description":"Customer ID"},{"key":"salesCredit","value":"5","description":"Sales Credit ID"},{"key":"allocation","value":"12","description":"Sales Credit Allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credit allocation 12 was deleted.\"\n}"}]},{"name":"Submit Orders to Starshipit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/starshipit/submit-orders","host":["{{baseUrl}}"],"path":["api","customers","starshipit","submit-orders"]},"description":"**This GET dispatches a background job** (queues a bulk submit of every open Starshipit fulfillment).\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSubmit pending orders to Starshipit shipping integration.\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/starshipit/submit-orders","host":["{{baseUrl}}"],"path":["api","customers","starshipit","submit-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"submitted\": 5,\n    \"failed\": 0\n  },\n  \"message\": \"Orders submitted to Starshipit.\"\n}"}]},{"name":"Update Starshipit Order from Fulfillment","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/starshipit/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","customers","starshipit","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"1","description":"Sales Order Fulfillment ID"}]},"description":"Update an existing order in Starshipit from a sales order fulfillment.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/starshipit/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","customers","starshipit","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"1","description":"Sales Order Fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Starshipit order updated.\"\n}"}]},{"name":"View Starshipit Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/starshipit/view-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","customers","starshipit","view-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"1","description":"Sales Order Fulfillment ID"}]},"description":"View the Starshipit order for a sales order fulfillment.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/starshipit/view-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","customers","starshipit","view-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"1","description":"Sales Order Fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order_number\": \"SF-1001\",\n    \"status\": \"pending\",\n    \"carrier\": \"Australia Post\"\n  }\n}"}]},{"name":"List SKU Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer_id}/sku-mappings","host":["{{baseUrl}}"],"path":["api","customers",":customer_id","sku-mappings"],"variable":[{"key":"customer_id","value":"","description":"The customer ID."}]},"description":"Return a paginated list of SKU mappings for the specified customer. Each mapping links a customer-facing SKU code to an internal product.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create / Upsert SKU Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer_id}/sku-mappings","host":["{{baseUrl}}"],"path":["api","customers",":customer_id","sku-mappings"],"variable":[{"key":"customer_id","value":"","description":"The customer ID."}]},"description":"Create a new SKU mapping or update an existing one (upsert) for the given customer. If a mapping for customer_sku already exists, it is updated with the new product_id.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"customer_sku\": \"CUST-SKU-001\",\n  \"product_id\": 1\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete SKU Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer_id}/sku-mappings/{mapping_id}","host":["{{baseUrl}}"],"path":["api","customers",":customer_id","sku-mappings",":mapping_id"],"variable":[{"key":"customer_id","value":"","description":"The customer ID."},{"key":"mapping_id","value":"","description":"The mapping ID."}]},"description":"Delete a specific SKU mapping by ID for the given customer.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Import SKU Mappings from CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer_id}/sku-mappings/import","host":["{{baseUrl}}"],"path":["api","customers",":customer_id","sku-mappings","import"],"variable":[{"key":"customer_id","value":"","description":"The customer ID."}]},"description":"Bulk-import SKU mappings for a customer from a CSV file. The CSV must have a header row with columns customer_sku and product_id. Existing mappings for the same customer_sku are updated (upsert behaviour).\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}}},{"name":"Export SKU Mappings as CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer_id}/sku-mappings/export","host":["{{baseUrl}}"],"path":["api","customers",":customer_id","sku-mappings","export"],"variable":[{"key":"customer_id","value":"","description":"The customer ID."}]},"description":"Export all SKU mappings for a customer as a CSV file download. The response is a CSV with columns customer_sku and product_id. Use this as a template for the import endpoint.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List Customer Contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts"],"variable":[{"key":"customer","value":"12","description":"Customer ID"}]},"description":"List all contacts attached to a customer, paginated. Supports search (title/notes), role/primary/has-email filters, advanced per-column filters, and sorting.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts"],"variable":[{"key":"customer","value":"12","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"name\": \"Jane Buyer\",\n      \"email\": \"jane.buyer@example.com\",\n      \"phone\": \"+1 415-555-0100\",\n      \"role\": \"accounts_payable\",\n      \"role_label\": \"Accounts Payable\",\n      \"title\": \"AP Specialist\",\n      \"is_primary\": true,\n      \"is_messaging\": false,\n      \"notes\": \"Prefers email over phone.\",\n      \"link_type\": \"customer\",\n      \"link_id\": 12,\n      \"created_at\": \"2026-07-13T14:22:05+00:00\",\n      \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n    },\n    {\n      \"id\": 43,\n      \"name\": \"Sam Sales\",\n      \"email\": \"sam.sales@example.com\",\n      \"phone\": \"+1 415-555-0100\",\n      \"role\": \"sales_rep\",\n      \"role_label\": \"Sales Rep\",\n      \"title\": \"Account Executive\",\n      \"is_primary\": false,\n      \"is_messaging\": false,\n      \"notes\": \"Prefers email over phone.\",\n      \"link_type\": \"customer\",\n      \"link_id\": 12,\n      \"created_at\": \"2026-07-13T14:22:05+00:00\",\n      \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Create Customer Contact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts"],"variable":[{"key":"customer","value":"12","description":"Customer ID"}]},"description":"Add a new contact to a customer. Fields: name (required), email, phone, role (default general), title, is_primary, notes (max 500). The first contact added to a customer automatically becomes primary; setting is_primary demotes the previous primary.\n\nRole options: general, sales_rep, account_manager, customer_service, accounts_payable, accounts_receivable, purchasing, shipping_receiving, warehouse_manager, operations, billing, owner, other.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Buyer\",\n  \"email\": \"jane.buyer@example.com\",\n  \"phone\": \"+1 415-555-0100\",\n  \"role\": \"accounts_payable\",\n  \"title\": \"AP Specialist\",\n  \"is_primary\": true,\n  \"is_messaging\": false,\n  \"notes\": \"Prefers email over phone.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts"],"variable":[{"key":"customer","value":"12","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"is_messaging\": false,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"customer\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Export Contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/export?format=csv","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv (default) or xlsx","disabled":true}],"variable":[{"key":"customer","value":"1","description":"Customer ID"}]},"description":"Download all contacts belonging to the customer as a CSV or XLSX file. Columns: Contact ID, Name, Email, Phone, Role, Title, Primary, Notes, Created At, Updated At. The file mirrors the contacts bulk-import template, so an exported file can be edited and re-imported (rows with a Contact ID or a matching email update the existing contact; others are created).\n\nOptional comma-separated column keys (`name,role,title,email,phone,notes,created_at`) to narrow the exported fields; `Contact ID` is always included so the file can round-trip as an update. Omit for the full field set.\n\nOptional. `filtered` applies the request's filter/sort parameters (same syntax as the list endpoint) instead of exporting every contact."}},{"name":"Get Customer Contact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Get a single contact belonging to the customer. A contact id that belongs to a different customer returns 404.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"is_messaging\": false,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"customer\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Update Customer Contact","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Update a contact belonging to the customer. Full update — name is required. Setting is_primary promotes this contact and demotes the previous primary.\n\nRole options: general, sales_rep, account_manager, customer_service, accounts_payable, accounts_receivable, purchasing, shipping_receiving, warehouse_manager, operations, billing, owner, other.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Buyer\",\n  \"email\": \"jane.buyer@example.com\",\n  \"phone\": \"+1 415-555-0100\",\n  \"role\": \"accounts_payable\",\n  \"title\": \"AP Specialist\",\n  \"is_primary\": true,\n  \"is_messaging\": false,\n  \"notes\": \"Prefers email over phone.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"is_messaging\": false,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"customer\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Delete Customer Contact","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Delete a contact from the customer. If the deleted contact was primary and other contacts remain, the oldest remaining contact is promoted to primary.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Contact deleted.\"\n}"}]},{"name":"Set Customer Contact as Primary","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}/make-primary","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact","make-primary"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Promote a contact to be the customer's primary contact, demoting the previous primary.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/customers/{customer}/contacts/{contact}/make-primary","host":["{{baseUrl}}"],"path":["api","v2","customers",":customer","contacts",":contact","make-primary"],"variable":[{"key":"customer","value":"12","description":"Customer ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"is_messaging\": false,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"customer\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Get Store Credit Balance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Returns the customer's current store-credit wallet balance — the running sum of every ledger entry.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"customer_id\": 501,\n    \"balance\": 42.5\n  }\n}"}]},{"name":"Issue Store Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Manually issue (or adjust) store credit for a customer.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n• `amount` (required, numeric, non-zero) — magnitude for signed reasons (goodwill/top_up add, expiry removes); for an `adjustment` the sign is honored, so a negative value removes credit.\n• `reason` (required) — one of the human-selectable reasons: `goodwill`, `top_up`, `adjustment`, `expiry`. System reasons (`refund`, `overpayment`, `redemption`, `reversal`) are rejected here.\n• `notes` (optional, string) — free-text note.\n• `reference` (optional, string) — external reference; defaults to an auto-generated SC-###### code.\n\nAn adjustment/expiry that would drive the wallet below zero returns 422.\n\nAuthentication: Requires Bearer token (PAT).\nRequires permission: customers.update.","body":{"mode":"raw","raw":"{\n  \"amount\": 25,\n  \"reason\": \"goodwill\",\n  \"notes\": \"Apology for the mixed-up order\",\n  \"reference\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 123,\n    \"customer_id\": 501,\n    \"reference\": \"SC-000123\",\n    \"amount\": 25,\n    \"balance_after\": 25,\n    \"reason\": \"goodwill\",\n    \"reason_label\": \"Goodwill\",\n    \"is_credit\": true,\n    \"currency_id\": 1,\n    \"notes\": \"Apology for the mixed-up order\",\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 1,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T14:15:43.000000Z\"\n  },\n  \"balance\": 42.5,\n  \"message\": \"Store credit issued.\"\n}"}]},{"name":"Get Store Credit History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit","history"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Paginated ledger history for the customer's store-credit wallet, newest first. Each entry records a signed movement (`amount`), the running `balance_after`, the reason, and — for system-driven entries — the polymorphic source (e.g. a POS transaction for a refund-to-credit).\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/store-credit/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","store-credit","history"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 123,\n      \"customer_id\": 501,\n      \"reference\": \"SC-000123\",\n      \"amount\": 25,\n      \"balance_after\": 25,\n      \"reason\": \"goodwill\",\n      \"reason_label\": \"Goodwill\",\n      \"is_credit\": true,\n      \"currency_id\": 1,\n      \"notes\": \"Apology for the mixed-up order\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 1,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:15:43.000000Z\"\n    },\n    {\n      \"id\": 120,\n      \"customer_id\": 501,\n      \"reference\": \"SC-000120\",\n      \"amount\": -17.5,\n      \"balance_after\": 17.5,\n      \"reason\": \"redemption\",\n      \"reason_label\": \"Redemption\",\n      \"is_credit\": false,\n      \"currency_id\": 1,\n      \"notes\": null,\n      \"source_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"source_id\": 5012,\n      \"created_by_user_id\": 1,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-05T10:00:00.000000Z\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"...\",\n    \"last\": \"...\",\n    \"prev\": null,\n    \"next\": null\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 1,\n    \"per_page\": 10,\n    \"to\": 2,\n    \"total\": 2\n  }\n}"}]},{"name":"Get Customer AR Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/ar-summary","host":["{{baseUrl}}"],"path":["api","customers",":customer","ar-summary"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Returns the customer's accounts-receivable summary in one call: outstanding and overdue totals, aging buckets, open credits, net receivable, credit headroom, informational wallet balances, the most recent payment, and the head of the overdue worklist.\n\nAll amounts are in the account's base currency (`currency`).\n\nResponse fields:\n- `outstanding_total` — sum of balance due across the customer's open sales orders.\n- `overdue` — `amount`, `count`, and `oldest_due_date` of orders past their due date.\n- `aging` — outstanding amount bucketed by days past due: `current` (not yet due), `d1_30`, `d31_60`, `d61_90`, `d90_plus`.\n- `open_credits` — `amount` and `count` of open sales credits with an unallocated balance.\n- `net_receivable` — `outstanding_total` minus `open_credits.amount`. Negative means you owe the customer.\n- `credit_limit` / `available_credit` — `available_credit` is `credit_limit` minus `outstanding_total`; both null when no credit limit is set.\n- `house_account_balance` / `store_credit_balance` — informational wallet balances. Store credit is a prepaid liability and is never netted into `net_receivable`.\n- `last_payment` — `date`, `amount`, and `id` of the most recent payment against the customer's orders (a convenience hint, not an accounting figure); null when the customer has never paid.\n- `last_statement_sent_at` — when a statement email was last sent to this customer (ISO 8601, or null).\n- `overdue_items` — up to 5 overdue receivable rows, oldest due date first (same row shape as the receivables list).\n- `open_count` — number of open receivable rows.\n- `payment_terms_days` — payment terms used to derive due dates (customer override, else the account default).\n\nDue dates are derived as order date + payment terms.\n\nAuthentication: Requires Bearer token (PAT). Requires permissions `customers.show` and `sales_orders.index`, and a token with the orders scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/ar-summary","host":["{{baseUrl}}"],"path":["api","customers",":customer","ar-summary"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currency\": \"USD\",\n    \"outstanding_total\": 764.38,\n    \"overdue\": {\n      \"amount\": 219.88,\n      \"count\": 1,\n      \"oldest_due_date\": \"2026-06-01\"\n    },\n    \"aging\": {\n      \"current\": 544.5,\n      \"d1_30\": 0,\n      \"d31_60\": 219.88,\n      \"d61_90\": 0,\n      \"d90_plus\": 0\n    },\n    \"open_credits\": {\n      \"amount\": 30,\n      \"count\": 1\n    },\n    \"net_receivable\": 734.38,\n    \"credit_limit\": 5000,\n    \"available_credit\": 4235.62,\n    \"house_account_balance\": 120,\n    \"store_credit_balance\": 42.5,\n    \"last_payment\": {\n      \"date\": \"2026-07-02\",\n      \"amount\": 95.5,\n      \"id\": 9911\n    },\n    \"last_statement_sent_at\": \"2026-07-01T15:04:05+00:00\",\n    \"overdue_items\": [\n      {\n        \"id\": 8123,\n        \"number\": \"SO-01021\",\n        \"date\": \"2026-05-02\",\n        \"due_date\": \"2026-06-01\",\n        \"days_until_due\": -46,\n        \"payment_due_status\": \"overdue\",\n        \"order_status\": \"open\",\n        \"payment_status\": \"unpaid\",\n        \"total\": 219.88,\n        \"total_paid\": 0,\n        \"balance_due\": 219.88,\n        \"balance_due_in_tenant_currency\": 219.88,\n        \"currency\": \"USD\"\n      }\n    ],\n    \"open_count\": 2,\n    \"payment_terms_days\": 30\n  }\n}"}]},{"name":"List Customer Receivables","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/receivables","host":["{{baseUrl}}"],"path":["api","customers",":customer","receivables"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Paginated receivables worklist for one customer — each row is a sales order reduced to its receivable shape.\n\nRow fields: `number`, `date`, `due_date` (order date + payment terms), `days_until_due` (negative when past due), `payment_due_status` (`overdue`, `due_soon` — due within 7 days, `current`, or `no_due_date`), `order_status`, `payment_status`, `total`, `total_paid`, and `balance_due` in the order's own currency, `balance_due_in_tenant_currency` converted to the account's base currency at the order's exchange rate, and `currency`.\n\nFiltering:\n- `filter[status]` — `open` (default: any order with a balance due), `overdue` (balance due and past the due date), `due_7d` (balance due within the next 7 days), `paid` (settled orders), `all`.\n- `filter[search]` — matches the order number.\n\nSorting: `sort` accepts `due_date` (default), `-due_date`, `date`, `-date`.\n\nPagination: `page` (default 1) and `per_page` (default 10, max 100).\n\nAuthentication: Requires Bearer token (PAT). Requires permissions `customers.show` and `sales_orders.index`, and a token with the orders scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/receivables","host":["{{baseUrl}}"],"path":["api","customers",":customer","receivables"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8123,\n      \"number\": \"SO-01021\",\n      \"date\": \"2026-05-02\",\n      \"due_date\": \"2026-06-01\",\n      \"days_until_due\": -46,\n      \"payment_due_status\": \"overdue\",\n      \"order_status\": \"open\",\n      \"payment_status\": \"unpaid\",\n      \"total\": 219.88,\n      \"total_paid\": 0,\n      \"balance_due\": 219.88,\n      \"balance_due_in_tenant_currency\": 219.88,\n      \"currency\": \"USD\"\n    },\n    {\n      \"id\": 8156,\n      \"number\": \"SO-01044\",\n      \"date\": \"2026-07-06\",\n      \"due_date\": \"2026-07-20\",\n      \"days_until_due\": 3,\n      \"payment_due_status\": \"due_soon\",\n      \"order_status\": \"open\",\n      \"payment_status\": \"partially_paid\",\n      \"total\": 640,\n      \"total_paid\": 95.5,\n      \"balance_due\": 544.5,\n      \"balance_due_in_tenant_currency\": 544.5,\n      \"currency\": \"USD\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Get Customer Statement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Returns the customer's statement of account as JSON, in one of two views selected by `type`:\n\n- `open_item` (default) — every open sales order plus open sales credits with an unallocated balance, and a `totals` block (`open`, `credits`, `net_receivable`). `as_at` optionally limits the statement to documents dated on or before that date (balances remain current values).\n- `activity` — a chronological ledger for the `from`/`to` window (both required for this view): an opening balance carried from before the period, then every receivable-affecting event with a running balance — orders (debits), payments (credits), refunds (debits), and issued sales credits (credits) — satisfying opening + debits - credits = closing. Line `type` is one of `order`, `payment`, `refund`, `credit_issued`; each line links its source document via `link.entity` (`sales_order` or `sales_credit`) and `link.id`.\n\nAll amounts are in the account's base currency; foreign-currency documents are converted at each order's snapshot exchange rate. Both views also include the customer header, the aging buckets, and the account's configured `payment_instructions`.\n\nUse the export endpoint for a PDF or CSV download of the same statement.\n\nAuthentication: Requires Bearer token (PAT). Requires permissions `customers.show` and `sales_orders.index`, and a token with the orders scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"customer\": {\n      \"id\": 501,\n      \"name\": \"Jane Smith\",\n      \"company\": \"Acme Retail LLC\",\n      \"email\": \"ap@acmeretail.com\"\n    },\n    \"as_of\": \"2026-07-17\",\n    \"currency\": \"USD\",\n    \"open_items\": [\n      {\n        \"id\": 8123,\n        \"number\": \"SO-01021\",\n        \"date\": \"2026-05-02\",\n        \"due_date\": \"2026-06-01\",\n        \"days_until_due\": -46,\n        \"payment_due_status\": \"overdue\",\n        \"order_status\": \"open\",\n        \"payment_status\": \"unpaid\",\n        \"total\": 219.88,\n        \"total_paid\": 0,\n        \"balance_due\": 219.88,\n        \"balance_due_in_tenant_currency\": 219.88,\n        \"currency\": \"USD\"\n      },\n      {\n        \"id\": 8156,\n        \"number\": \"SO-01044\",\n        \"date\": \"2026-07-06\",\n        \"due_date\": \"2026-07-20\",\n        \"days_until_due\": 3,\n        \"payment_due_status\": \"due_soon\",\n        \"order_status\": \"open\",\n        \"payment_status\": \"partially_paid\",\n        \"total\": 640,\n        \"total_paid\": 95.5,\n        \"balance_due\": 544.5,\n        \"balance_due_in_tenant_currency\": 544.5,\n        \"currency\": \"USD\"\n      }\n    ],\n    \"credits\": [\n      {\n        \"id\": 55,\n        \"number\": \"SC-00055\",\n        \"date\": \"2026-06-18\",\n        \"available\": 30\n      }\n    ],\n    \"totals\": {\n      \"open\": 764.38,\n      \"credits\": 30,\n      \"net_receivable\": 734.38\n    },\n    \"aging\": {\n      \"current\": 544.5,\n      \"d1_30\": 0,\n      \"d31_60\": 219.88,\n      \"d61_90\": 0,\n      \"d90_plus\": 0\n    },\n    \"payment_instructions\": \"Pay by ACH to routing 021000021, account 1234567. Please reference your order number.\"\n  }\n}"}]},{"name":"Export Customer Statement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement/export","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement","export"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Downloads the customer's statement of account as a file. `format=pdf` (default) returns a branded PDF document (`application/pdf`); `format=csv` returns comma-separated rows (`text/csv`).\n\nAccepts the same statement parameters as the JSON statement endpoint: `type` (`open_item` default, or `activity`), `from`/`to` (required when `type=activity`), and `as_at` (`open_item` only).\n\nThe response is a file download named `customer-statement-{customer-name}-{date}.pdf` (or `.csv`) — not JSON.\n\nCSV columns:\n- `activity`: Date, Type, Reference, Description, Debit, Credit, Running Balance — with opening and closing balance rows.\n- `open_item`: Type, Document, Date, Due Date, Status, Document Currency, Total (Document Currency), Outstanding (base currency) — one row per open order, one negative row per open credit, and a final net_receivable row.\n\nAuthentication: Requires Bearer token (PAT). Requires permissions `customers.show` and `sales_orders.index`, and a token with the orders scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement/export","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement","export"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Type,Document,Date,\"Due Date\",Status,\"Document Currency\",\"Total (Document Currency)\",\"Outstanding (USD)\"\nsales_order,SO-01021,2026-05-02,2026-06-01,unpaid,USD,219.88,219.88\nsales_order,SO-01044,2026-07-06,2026-07-20,partially_paid,USD,640.00,544.50\nsales_credit,SC-00055,2026-06-18,,open,USD,,-30\nnet_receivable,,,,,USD,,734.38\n"}]},{"name":"Preview Customer Statement Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement/preview","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement","preview"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Preview the statement email that a send would produce — the exact From and Reply-To addresses, resolved recipient, subject and body — WITHOUT sending it or logging anything. Use it to show the sender and content before committing to send.\n\nBody is identical to Send Customer Statement: `type` (required — `open_item` or `activity`); for `activity`, `from` and `to` (Y-m-d) are required; `as_at` (Y-m-d) optionally dates an open-item statement; `recipient` overrides the customer's billing email; `subject` and `body` override the defaults and support the placeholders {customer_name}, {total_due}, {payment_instructions}.\n\nAuthentication: Requires Bearer token (PAT).","body":{"mode":"raw","raw":"{\n  \"type\": \"open_item\",\n  \"as_at\": \"2026-06-30\",\n  \"recipient\": \"ap@acmeretail.com\",\n  \"subject\": \"Statement of Account — {customer_name}\",\n  \"body\": \"Dear {customer_name},\\n\\nPlease find your statement of account attached. Your current balance is {total_due}.\\n\\n{payment_instructions}\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/statement/preview","host":["{{baseUrl}}"],"path":["api","customers",":customer","statement","preview"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"from\": {\n      \"address\": \"billing@acme-wholesale.example\",\n      \"name\": \"Acme Wholesale\"\n    },\n    \"reply_to\": {\n      \"address\": \"ar@acme-wholesale.example\",\n      \"name\": \"Acme Wholesale AR\"\n    },\n    \"recipient\": \"ap@acmeretail.com\",\n    \"subject\": \"Statement of Account — Acme Retail\",\n    \"body\": \"Dear Acme Retail,\\n\\nPlease find your statement of account attached. Your current balance is $764.38.\\n\\nTo pay, reply to this email or contact our accounts team.\",\n    \"attachment_filename\": \"customer-statement-acme-retail-2026-07-18.pdf\"\n  }\n}"}]},{"name":"Send Customer Statement","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/send-statement","host":["{{baseUrl}}"],"path":["api","customers",":customer","send-statement"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Emails the customer a statement of account with the PDF attached, and records the send in the communications log.\n\nThe statement is generated with the same parameters as the statement endpoints: `type` (required — `open_item` or `activity`), `from`/`to` (required when `type=activity`), and `as_at` (`open_item` only).\n\nThe recipient defaults to the customer's billing email, falling back to their primary email; pass `recipient` to override. `subject` and `body` are optional templates; these placeholders are replaced before sending: `{customer_name}`, `{total_due}` (the statement's closing balance or net receivable, formatted with currency), `{days_overdue}`, and `{payment_instructions}` (the account's configured payment instructions). When omitted, a default subject and body are used.\n\nReturns the logged communication entry.\n\nBody parameters:\n- type (string, required): `open_item` or `activity`.\n- from (date): Period start. Required when type is `activity`.\n- to (date): Period end, on or after `from`. Required when type is `activity`.\n- as_at (date, optional): `open_item` only — include only documents dated on or before this date.\n- recipient (string, email, optional): Override the destination email address.\n- subject (string, max 255, optional): Email subject template.\n- body (string, max 10000, optional): Email body template.\n\nErrors:\n- 422 when `type` is missing, `from`/`to` are missing for the activity view, or no recipient email can be resolved (the customer has no billing or primary email and no `recipient` was supplied).\n\nAuthentication: Requires Bearer token (PAT). Requires permission `customers.send_communications` and a token with the orders scope. Rate limited to 60 requests per minute.\n\nThe activity statement date range cannot exceed 366 days.","body":{"mode":"raw","raw":"{\n  \"type\": \"open_item\",\n  \"as_at\": \"2026-06-30\",\n  \"recipient\": \"ap@acmeretail.com\",\n  \"subject\": \"Statement of Account — {customer_name}\",\n  \"body\": \"Dear {customer_name},\\n\\nPlease find your statement of account attached. Your current balance is {total_due}.\\n\\n{payment_instructions}\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/send-statement","host":["{{baseUrl}}"],"path":["api","customers",":customer","send-statement"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Statement sent to ap@acmeretail.com.\",\n  \"data\": {\n    \"id\": 87,\n    \"customer_id\": 501,\n    \"sales_order_id\": null,\n    \"sales_order_number\": null,\n    \"type\": \"statement\",\n    \"scope\": \"account\",\n    \"statement_type\": \"open_item\",\n    \"params\": {\n      \"as_at\": \"2026-06-30\",\n      \"total_due\": 734.38\n    },\n    \"recipient\": \"ap@acmeretail.com\",\n    \"subject\": \"Statement of Account — Acme Retail LLC\",\n    \"sent_by\": 3,\n    \"sender_name\": \"Alex Rivera\",\n    \"created_at\": \"2026-07-01T15:04:05+00:00\"\n  }\n}"}]},{"name":"Request Customer Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/request-payment","host":["{{baseUrl}}"],"path":["api","customers",":customer","request-payment"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Emails the customer an account-level payment request for their outstanding balance, and records the send in the communications log. To request payment for a single order instead, use the request-payment action on that sales order (Orders collection).\n\nThe recipient defaults to the customer's billing email, falling back to their primary email; pass `recipient` to override. `subject` and `body` are optional templates; these placeholders are replaced before sending: `{customer_name}`, `{total_due}` (the customer's outstanding balance, formatted with currency), `{days_overdue}` (days since the oldest overdue due date), and `{payment_instructions}` (the account's configured payment instructions). When omitted, a default subject and body are used.\n\nSet `attach_statement` to true to attach the customer's current open-item statement as a PDF.\n\nReturns the logged communication entry.\n\nBody parameters (all optional):\n- recipient (string, email): Override the destination email address.\n- subject (string, max 255): Email subject template.\n- body (string, max 10000): Email body template.\n- attach_statement (boolean): Attach the open-item statement PDF. Default false.\n\nErrors:\n- 422 when no recipient email can be resolved (the customer has no billing or primary email and no `recipient` was supplied).\n\nAuthentication: Requires Bearer token (PAT). Requires permission `customers.send_communications` and a token with the orders scope. Rate limited to 60 requests per minute.","body":{"mode":"raw","raw":"{\n  \"recipient\": \"ap@acmeretail.com\",\n  \"subject\": \"Payment Request — {customer_name}\",\n  \"body\": \"Dear {customer_name},\\n\\nOur records show an outstanding balance of {total_due} on your account. Please arrange payment at your earliest convenience.\\n\\n{payment_instructions}\",\n  \"attach_statement\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/request-payment","host":["{{baseUrl}}"],"path":["api","customers",":customer","request-payment"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payment request sent to ap@acmeretail.com.\",\n  \"data\": {\n    \"id\": 89,\n    \"customer_id\": 501,\n    \"sales_order_id\": null,\n    \"sales_order_number\": null,\n    \"type\": \"payment_request\",\n    \"scope\": \"account\",\n    \"statement_type\": null,\n    \"params\": {\n      \"total_due\": 764.38,\n      \"attach_statement\": true\n    },\n    \"recipient\": \"ap@acmeretail.com\",\n    \"subject\": \"Payment Request — Acme Retail LLC\",\n    \"sent_by\": 3,\n    \"sender_name\": \"Alex Rivera\",\n    \"created_at\": \"2026-07-17T09:12:03+00:00\"\n  }\n}"}]},{"name":"List Customer AR Communications","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/ar-communications","host":["{{baseUrl}}"],"path":["api","customers",":customer","ar-communications"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]},"description":"Paginated log of outbound receivables emails sent to this customer, newest first. Entries are created by the send-statement and request-payment actions (both the account-level actions here and the per-order request-payment action in the Orders collection).\n\nEntry fields: `type` (`statement` or `payment_request`), `scope` (`account`, or `order` with `sales_order_id` / `sales_order_number` set), `statement_type` (`open_item` or `activity` for statement sends, null otherwise), `params` (send parameters and amounts captured at send time, e.g. `total_due`, `amount_due`, `days_overdue`, `as_at`, `attach_statement`, `attach_invoice`), `recipient`, `subject`, `sent_by` / `sender_name` (the user who sent it), and `created_at`.\n\nPagination: `page` (default 1) and `per_page` (default 10).\n\nAuthentication: Requires Bearer token (PAT). Requires permissions `customers.show` and `sales_orders.index`, and a token with the orders scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/ar-communications","host":["{{baseUrl}}"],"path":["api","customers",":customer","ar-communications"],"variable":[{"key":"customer","value":"501","description":"Customer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"customer_id\": 501,\n      \"sales_order_id\": 8123,\n      \"sales_order_number\": \"SO-01021\",\n      \"type\": \"payment_request\",\n      \"scope\": \"order\",\n      \"statement_type\": null,\n      \"params\": {\n        \"amount_due\": 219.88,\n        \"days_overdue\": 46,\n        \"attach_invoice\": true\n      },\n      \"recipient\": \"ap@acmeretail.com\",\n      \"subject\": \"Payment Request — Order SO-01021\",\n      \"sent_by\": 3,\n      \"sender_name\": \"Alex Rivera\",\n      \"created_at\": \"2026-07-16T18:22:41+00:00\"\n    },\n    {\n      \"id\": 87,\n      \"customer_id\": 501,\n      \"sales_order_id\": null,\n      \"sales_order_number\": null,\n      \"type\": \"statement\",\n      \"scope\": \"account\",\n      \"statement_type\": \"open_item\",\n      \"params\": {\n        \"as_at\": \"2026-06-30\",\n        \"total_due\": 734.38\n      },\n      \"recipient\": \"ap@acmeretail.com\",\n      \"subject\": \"Statement of Account — Acme Retail LLC\",\n      \"sent_by\": 3,\n      \"sender_name\": \"Alex Rivera\",\n      \"created_at\": \"2026-07-01T15:04:05+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"List Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Paginated list of Magento 2 customers scoped to one integration instance.\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer) — Magento 2 IntegrationInstance ID.\n\n**Query params** — all optional. Sorts: `id`, `magento_entity_id`, `email`, `firstname`, `lastname`, `group_id`, `website_id`, `magento_created_at`, `magento_updated_at`, `created_at`, `updated_at`. Advanced filters (Spatie AdvancedFilterBuilder) are also available for `email`, `firstname`, `lastname`, `telephone`, and the datetime columns.\n\n**Notes:**\n- `filter[integration_instance_ids]` is accepted as a no-op so the channel layout's URL param doesn't 400.\n- Eager-loads the integration instance + addresses + a withCount('orders') so the resource can emit `orders_count` and a derived primary-address city / region / country without N+1.\n- Fields the schema doesn't yet carry (`group_name`, `website_name`, `total_spent`, etc.) are returned as `null`; Phase 2D's sync work will populate them."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 17,\n      \"integration_instance_id\": 42,\n      \"magento_id\": 1234,\n      \"magento_entity_id\": 1234,\n      \"email\": \"buyer@example.com\",\n      \"firstname\": \"Alex\",\n      \"lastname\": \"Buyer\",\n      \"first_name\": \"Alex\",\n      \"last_name\": \"Buyer\",\n      \"full_name\": \"Alex Buyer\",\n      \"telephone\": \"+1 415 555 0190\",\n      \"phone\": \"+1 415 555 0190\",\n      \"website_id\": 1,\n      \"group_id\": 1,\n      \"group_name\": null,\n      \"website_name\": null,\n      \"store_id\": null,\n      \"store_view_code\": null,\n      \"sku_customer_name\": null,\n      \"currency\": null,\n      \"city\": \"San Francisco\",\n      \"region\": \"CA\",\n      \"country_id\": \"US\",\n      \"orders_count\": 4,\n      \"total_spent\": null,\n      \"is_active\": true,\n      \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n      \"magento_updated_at\": \"2026-06-01T11:22:18+00:00\",\n      \"created_at\": \"2026-02-12T18:30:00+00:00\",\n      \"updated_at\": \"2026-06-15T09:11:08+00:00\",\n      \"sku_customer_id\": null,\n      \"magento_admin_url\": \"https://shop.example.com/admin/customer/index/edit/id/1234\",\n      \"raw_payload\": null\n    }\n  ],\n  \"first_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/customers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/customers?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-io-test/api/magento2/integration-instances/42/customers\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Customer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/{customer}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers",":customer"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"customer","value":"17","description":"Internal magento2_customers.id"}]},"description":"Single customer detail. Eager-loads the integration instance, addresses, and orders_count.\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer) — Magento 2 IntegrationInstance ID.\n- `customer` (required, integer) — Internal `magento2_customers.id`.\n\n**Error responses:**\n- `404` — customer does not exist OR belongs to a different instance.\n- `401` — caller is not authenticated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/{customer}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers",":customer"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"customer","value":"17","description":"Internal magento2_customers.id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"integration_instance_id\": 42,\n    \"magento_id\": 1234,\n    \"magento_entity_id\": 1234,\n    \"email\": \"buyer@example.com\",\n    \"firstname\": \"Alex\",\n    \"lastname\": \"Buyer\",\n    \"first_name\": \"Alex\",\n    \"last_name\": \"Buyer\",\n    \"full_name\": \"Alex Buyer\",\n    \"telephone\": \"+1 415 555 0190\",\n    \"phone\": \"+1 415 555 0190\",\n    \"website_id\": 1,\n    \"group_id\": 1,\n    \"group_name\": null,\n    \"website_name\": null,\n    \"store_id\": null,\n    \"store_view_code\": null,\n    \"sku_customer_name\": null,\n    \"currency\": null,\n    \"city\": \"San Francisco\",\n    \"region\": \"CA\",\n    \"country_id\": \"US\",\n    \"orders_count\": 4,\n    \"total_spent\": null,\n    \"is_active\": true,\n    \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n    \"magento_updated_at\": \"2026-06-01T11:22:18+00:00\",\n    \"created_at\": \"2026-02-12T18:30:00+00:00\",\n    \"updated_at\": \"2026-06-15T09:11:08+00:00\",\n    \"sku_customer_id\": null,\n    \"magento_admin_url\": \"https://shop.example.com/admin/customer/index/edit/id/1234\",\n    \"raw_payload\": null\n  }\n}"}]},{"name":"Get Customer Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Aggregated dropdown options for the customers filter panel — countries (via the address rows), customer groups, and websites — each as `{value, label, count}` so the picker can render counts inline. Pulled live from the customers persisted for this instance; empty / never-synced instances surface empty lists."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"countries\": [\n      {\n        \"value\": \"US\",\n        \"label\": \"US\",\n        \"count\": 12\n      },\n      {\n        \"value\": \"GB\",\n        \"label\": \"GB\",\n        \"count\": 3\n      }\n    ],\n    \"groups\": [\n      {\n        \"value\": 1,\n        \"label\": \"1\",\n        \"count\": 14\n      },\n      {\n        \"value\": 2,\n        \"label\": \"2\",\n        \"count\": 1\n      }\n    ],\n    \"websites\": [\n      {\n        \"value\": 1,\n        \"label\": \"1\",\n        \"count\": 15\n      }\n    ]\n  }\n}"}]},{"name":"Refresh Customers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Dispatch the tracked job that refreshes Magento 2 customers. Returns the `tracked_job_log_id` so the frontend can pivot the global JobProgressTray to it. Job name prefix is `Sync Magento 2 Customers: ` — the page's `lastCompletedJob` watcher matches on this prefix.\n\nPhase 2C scope: the dispatch + tracked-job harness only. The actual `/V1/customers/search` walking + upsert lands in Phase 2D — until then the job acknowledges the dispatch and completes immediately with zero-counter results."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 91812\n  },\n  \"message\": \"Customer sync queued.\"\n}"}]},{"name":"Refresh Single Customer","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/{customer}/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers",":customer","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"customer","value":"17","description":"Internal magento2_customers.id"}]},"description":"Dispatch the tracked job to re-fetch a single customer. Shares the `Sync Magento 2 Customers: ` job-name prefix with the bulk refresh so the page's `lastCompletedJob` watcher reacts to either run.\n\n**Error responses:**\n- `404` — customer does not exist OR belongs to a different instance.\n- `401` — caller is not authenticated."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/{customer}/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers",":customer","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"customer","value":"17","description":"Internal magento2_customers.id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 91823\n  },\n  \"message\": \"Customer refresh queued.\"\n}"}]},{"name":"Search Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Search-as-you-type endpoint. Delegates to the same paginated query as `List Customers` (Spatie QueryBuilder under the hood) so every filter / sort / pagination param the index supports is also accepted here. Provided as a separate route so the frontend can wire a dedicated debounce path."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/customers/search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","customers","search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 17,\n      \"integration_instance_id\": 42,\n      \"magento_id\": 1234,\n      \"magento_entity_id\": 1234,\n      \"email\": \"buyer@example.com\",\n      \"firstname\": \"Alex\",\n      \"lastname\": \"Buyer\",\n      \"first_name\": \"Alex\",\n      \"last_name\": \"Buyer\",\n      \"full_name\": \"Alex Buyer\",\n      \"telephone\": \"+1 415 555 0190\",\n      \"phone\": \"+1 415 555 0190\",\n      \"website_id\": 1,\n      \"group_id\": 1,\n      \"group_name\": null,\n      \"website_name\": null,\n      \"store_id\": null,\n      \"store_view_code\": null,\n      \"sku_customer_name\": null,\n      \"currency\": null,\n      \"city\": \"San Francisco\",\n      \"region\": \"CA\",\n      \"country_id\": \"US\",\n      \"orders_count\": 4,\n      \"total_spent\": null,\n      \"is_active\": true,\n      \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n      \"magento_updated_at\": \"2026-06-01T11:22:18+00:00\",\n      \"created_at\": \"2026-02-12T18:30:00+00:00\",\n      \"updated_at\": \"2026-06-15T09:11:08+00:00\",\n      \"sku_customer_id\": null,\n      \"magento_admin_url\": \"https://shop.example.com/admin/customer/index/edit/id/1234\",\n      \"raw_payload\": null\n    }\n  ],\n  \"first_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/customers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/customers?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-io-test/api/magento2/integration-instances/42/customers\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]}]},{"name":"Suppliers","item":[{"name":"List Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers?page=1&limit=10&search=&sort=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","v2","suppliers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"search","value":"","description":"Search by supplier name, email, company name","disabled":true},{"key":"sort","value":"","description":"Sort field. Prefix with - for descending (e.g. -name, created_at, leadtime)","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"Columns to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude from response","disabled":true}]},"description":"List all suppliers with list support. Supports filtering, sorting, and pagination.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nSort fields: name, email, company_name, leadtime, created_at, updated_at, archived_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers?page=1&limit=10&search=&sort=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","v2","suppliers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"search","value":"","description":"Search by supplier name, email, company name","disabled":true},{"key":"sort","value":"","description":"Sort field. Prefix with - for descending (e.g. -name, created_at, leadtime)","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"Columns to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude from response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Acme Supplier\",\n      \"company_name\": \"Acme Wholesale Co\",\n      \"email\": \"orders@acmewholesale.com\",\n      \"primary_contact_name\": \"Bob Johnson\",\n      \"purchase_order_email\": \"po@acmewholesale.com\",\n      \"messaging_phone\": \"+15551234567\",\n      \"website\": \"https://acmewholesale.com\",\n      \"leadtime\": 7,\n      \"minimum_order_quantity\": 10,\n      \"target_stock_days\": 30,\n      \"minimum_purchase_order\": 500,\n      \"purchase_order_format\": null,\n      \"po_processing_method\": \"email\",\n      \"auto_fulfill_dropship\": false,\n      \"auto_submit_dropship_po\": false,\n      \"auto_generate_backorder_po\": false,\n      \"auto_submit_backorder_po\": false,\n      \"auto_split_backorder_po_by_brand\": false,\n      \"auto_receive_backorder_po\": false,\n      \"default_warehouse_id\": 2,\n      \"default_store_id\": null,\n      \"default_tax_rate_id\": null,\n      \"default_payment_term_id\": null,\n      \"wire_instructions\": \"Beneficiary: Acme Wholesale Co\\nBank: Example Bank\\nRouting: 021000021\\nAccount: 12345678\",\n      \"wire_instructions_verified_at\": \"2026-07-10T04:00:00.000000Z\",\n      \"timezone\": \"Australia/Sydney\",\n      \"products_count\": 45,\n      \"address\": {\n        \"id\": 3,\n        \"label\": \"Default\",\n        \"address1\": \"100 Supplier Lane\",\n        \"city\": \"Sydney\",\n        \"zip\": \"2000\",\n        \"country\": \"Australia\",\n        \"country_code\": \"AU\"\n      },\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T09:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28\n}"}]},{"name":"Show Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier"],"variable":[{"key":"supplier","value":"3","description":"Supplier ID"}]},"description":"Returns a single supplier. The response includes the supplier's address, default payment term, default shipping method, default incoterm, and warehouses (each with its address) by default.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUse the `with` query parameter (comma-separated) to include additional relations: `pricingTiers` (also aliased as `pricing`), `defaultStore`, `defaultIncoterm`, `wireInstructionsVerifiedBy`, `customFieldValues`. Passing `customFieldValues` adds `custom_field_values` to the response — each stored custom-field value with its field metadata (`custom_field_id`, `name`, `slug`, `field_type`, `options`, `description`, `is_visible_in_details`). Pass `bill_stats` to include bill activity statistics for the supplier."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier"],"variable":[{"key":"supplier","value":"3","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Global Supplies Inc\",\n    \"email\": \"orders@globalsupplies.com\",\n    \"phone\": \"+1-555-0200\",\n    \"created_at\": \"2023-01-10T08:00:00.000000Z\",\n    \"updated_at\": \"2024-02-01T10:00:00.000000Z\"\n  }\n}"}]},{"name":"List Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers?page=1&limit=10&search=&sort=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","suppliers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"search","value":"","description":"Search by supplier name, email, company name","disabled":true},{"key":"sort","value":"","description":"Sort field. Prefix with - for descending (e.g. -name, created_at, leadtime)","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"Columns to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude from response","disabled":true}]},"description":"List all suppliers with list view support. Supports filtering, sorting, and pagination.\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nSort fields: name, email, company_name, leadtime, created_at, updated_at, archived_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers?page=1&limit=10&search=&sort=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","suppliers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"search","value":"","description":"Search by supplier name, email, company name","disabled":true},{"key":"sort","value":"","description":"Sort field. Prefix with - for descending (e.g. -name, created_at, leadtime)","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"Columns to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude from response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Acme Supplier\",\n      \"company_name\": \"Acme Wholesale Co\",\n      \"email\": \"orders@acmewholesale.com\",\n      \"primary_contact_name\": \"Bob Johnson\",\n      \"purchase_order_email\": \"po@acmewholesale.com\",\n      \"messaging_phone\": \"+15551234567\",\n      \"website\": \"https://acmewholesale.com\",\n      \"leadtime\": 7,\n      \"minimum_order_quantity\": 10,\n      \"target_stock_days\": 30,\n      \"minimum_purchase_order\": 500,\n      \"purchase_order_format\": null,\n      \"po_processing_method\": \"email\",\n      \"auto_fulfill_dropship\": false,\n      \"auto_submit_dropship_po\": false,\n      \"auto_generate_backorder_po\": false,\n      \"auto_submit_backorder_po\": false,\n      \"auto_split_backorder_po_by_brand\": false,\n      \"auto_receive_backorder_po\": false,\n      \"default_warehouse_id\": 2,\n      \"default_store_id\": null,\n      \"default_tax_rate_id\": null,\n      \"default_payment_term_id\": null,\n      \"timezone\": \"Australia/Sydney\",\n      \"products_count\": 45,\n      \"address\": {\n        \"id\": 3,\n        \"label\": \"Default\",\n        \"address1\": \"100 Supplier Lane\",\n        \"city\": \"Sydney\",\n        \"zip\": \"2000\",\n        \"country\": \"Australia\",\n        \"country_code\": \"AU\"\n      },\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T09:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28\n}"}]},{"name":"Create Supplier","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers","host":["{{baseUrl}}"],"path":["api","suppliers"]},"description":"Create a new supplier. Automatically creates a default warehouse for the supplier and attaches default pricing tiers.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nNotes:\n- email and purchase_order_email accept comma-separated multiple email addresses\n- messaging_phone: the supplier's WhatsApp/SMS number in international format (E.164, e.g. +15551234567), used to message them from a purchase order\n- name must be unique\n- po_processing_method: email, ftp, direct\n- po_batch_schedule.days: monday, tuesday, wednesday, thursday, friday, saturday, sunday\n- default_stock_level: normal, low, critical\n\n**Requires permission:** `suppliers.create`\n\nClearing `default_incoterm_id` (sending it as null/empty) also clears `default_incoterm_place` — a default named place is never kept without a default term.\n\n**Custom fields:** `custom_field_values` (optional array) sets values for supplier custom fields. Each entry takes `custom_field_id` (required — must reference a custom field defined for suppliers) and `value` (nullable); `id` is prohibited on create (value ids only exist once the supplier does). The response echoes each value with its field metadata: `name`, `slug`, `field_type` (`text` | `long_text` | `number` | `decimal` | `date` | `datetime` | `checkbox` | `dropdown`), `options`, `description`, and `is_visible_in_details`.","body":{"mode":"raw","raw":"{\n  \"name\": \"New Supplier\",\n  \"company_name\": \"New Supplier Co Pty Ltd\",\n  \"primary_contact_name\": \"Alice Brown\",\n  \"email\": \"alice@newsupplier.com,billing@newsupplier.com\",\n  \"purchase_order_email\": \"po@newsupplier.com\",\n  \"messaging_phone\": \"+15551234567\",\n  \"website\": \"https://newsupplier.com\",\n  \"leadtime\": 14,\n  \"minimum_order_quantity\": 5,\n  \"target_stock_days\": 45,\n  \"minimum_purchase_order\": 200,\n  \"po_processing_method\": \"email\",\n  \"po_batch_schedule\": [\n    {\n      \"time\": \"09:00\",\n      \"days\": [\n        \"monday\",\n        \"wednesday\",\n        \"friday\"\n      ]\n    }\n  ],\n  \"auto_fulfill_dropship\": false,\n  \"auto_submit_dropship_po\": false,\n  \"auto_generate_backorder_po\": true,\n  \"auto_submit_backorder_po\": false,\n  \"auto_split_backorder_po_by_brand\": false,\n  \"auto_receive_backorder_po\": false,\n  \"backorder_po_schedule\": [],\n  \"default_stock_level\": \"normal\",\n  \"default_tax_rate_id\": null,\n  \"default_payment_term_id\": 1,\n  \"timezone\": \"Australia/Sydney\",\n  \"address\": {\n    \"name\": \"Alice Brown\",\n    \"company\": \"New Supplier Co\",\n    \"email\": \"info@newsupplier.com\",\n    \"phone\": \"+61-2-9000-0000\",\n    \"address1\": \"200 Supplier Road\",\n    \"city\": \"Melbourne\",\n    \"province\": \"Victoria\",\n    \"province_code\": \"VIC\",\n    \"zip\": \"3000\",\n    \"country\": \"Australia\",\n    \"country_code\": \"AU\",\n    \"label\": \"Default\"\n  },\n  \"pricing\": [\n    {\n      \"id\": 1\n    }\n  ],\n  \"default_incoterm_id\": 12,\n  \"default_incoterm_place\": \"Shanghai Port, CN\",\n  \"custom_field_values\": [\n    {\n      \"custom_field_id\": 3,\n      \"value\": \"Gold\"\n    },\n    {\n      \"custom_field_id\": 5,\n      \"value\": \"2026-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers","host":["{{baseUrl}}"],"path":["api","suppliers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"New Supplier\",\n    \"company_name\": \"New Supplier Co Pty Ltd\",\n    \"email\": \"alice@newsupplier.com,billing@newsupplier.com\",\n    \"leadtime\": 14,\n    \"minimum_order_quantity\": 5,\n    \"address\": {\n      \"id\": 8,\n      \"label\": \"Default\",\n      \"address1\": \"200 Supplier Road\",\n      \"city\": \"Melbourne\",\n      \"zip\": \"3000\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\"\n    },\n    \"pricing\": [\n      {\n        \"id\": 1,\n        \"name\": \"Standard\",\n        \"currency_code\": \"AUD\"\n      }\n    ],\n    \"custom_field_values\": [\n      {\n        \"id\": 21,\n        \"custom_field_id\": 3,\n        \"value\": \"Gold\",\n        \"name\": \"Preferred Tier\",\n        \"slug\": \"preferred_tier\",\n        \"field_type\": \"dropdown\",\n        \"options\": [\n          \"Gold\",\n          \"Silver\",\n          \"Bronze\"\n        ],\n        \"description\": \"Negotiated service tier\",\n        \"is_visible_in_details\": true\n      },\n      {\n        \"id\": 22,\n        \"custom_field_id\": 5,\n        \"value\": \"2026-01-15\",\n        \"name\": \"Contract Renewal Date\",\n        \"slug\": \"contract_renewal_date\",\n        \"field_type\": \"date\",\n        \"options\": null,\n        \"description\": null,\n        \"is_visible_in_details\": true\n      }\n    ],\n    \"created_at\": \"2024-01-20T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-20T10:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"supplier created successfully\"\n}"}]},{"name":"Bulk Delete Suppliers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers","host":["{{baseUrl}}"],"path":["api","suppliers"]},"description":"Bulk delete suppliers by IDs or by applying to all filtered results.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/suppliers","host":["{{baseUrl}}"],"path":["api","suppliers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 suppliers deleted successfully.\"\n}"}]},{"name":"Get Supplier (with Warehouses)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Get a single supplier with warehouses loaded.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nThe response includes the supplier's `default_incoterm` (the full incoterm object, or null when no default is set).\n\nThe response also includes `custom_field_values` — each entry pairs the stored value with its field metadata (`custom_field_id`, `name`, `slug`, `field_type`, `options`, `description`, `is_visible_in_details`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Acme Supplier\",\n    \"company_name\": \"Acme Wholesale Co\",\n    \"email\": \"orders@acmewholesale.com\",\n    \"primary_contact_name\": \"Bob Johnson\",\n    \"purchase_order_email\": \"po@acmewholesale.com\",\n    \"messaging_phone\": \"+15551234567\",\n    \"website\": \"https://acmewholesale.com\",\n    \"leadtime\": 7,\n    \"minimum_order_quantity\": 10,\n    \"target_stock_days\": 30,\n    \"minimum_purchase_order\": 500,\n    \"po_processing_method\": \"email\",\n    \"auto_fulfill_dropship\": false,\n    \"auto_generate_backorder_po\": false,\n    \"auto_submit_backorder_po\": false,\n    \"auto_split_backorder_po_by_brand\": false,\n    \"auto_receive_backorder_po\": false,\n    \"default_warehouse_id\": 2,\n    \"default_store_id\": null,\n    \"default_payment_term\": {\n      \"id\": 1,\n      \"name\": \"Net 30\",\n      \"generated_description\": \"Payment due within 30 days\"\n    },\n    \"timezone\": \"Australia/Sydney\",\n    \"address\": {\n      \"id\": 3,\n      \"label\": \"Default\",\n      \"address1\": \"100 Supplier Lane\",\n      \"city\": \"Sydney\",\n      \"zip\": \"2000\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\"\n    },\n    \"warehouses\": [\n      {\n        \"id\": 2,\n        \"name\": \"Acme Warehouse\",\n        \"type\": \"supplier\"\n      }\n    ],\n    \"warehouse_lead_times\": [\n      {\n        \"warehouse_id\": 2,\n        \"warehouse_name\": \"Main DC\",\n        \"leadtime\": 20\n      }\n    ],\n    \"custom_field_values\": [\n      {\n        \"id\": 21,\n        \"custom_field_id\": 3,\n        \"value\": \"Gold\",\n        \"name\": \"Preferred Tier\",\n        \"slug\": \"preferred_tier\",\n        \"field_type\": \"dropdown\",\n        \"options\": [\n          \"Gold\",\n          \"Silver\",\n          \"Bronze\"\n        ],\n        \"description\": \"Negotiated service tier\",\n        \"is_visible_in_details\": true\n      },\n      {\n        \"id\": 22,\n        \"custom_field_id\": 5,\n        \"value\": \"2026-01-15\",\n        \"name\": \"Contract Renewal Date\",\n        \"slug\": \"contract_renewal_date\",\n        \"field_type\": \"date\",\n        \"options\": null,\n        \"description\": null,\n        \"is_visible_in_details\": true\n      }\n    ],\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T09:00:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Supplier","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Update an existing supplier. All fields are optional.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n- `messaging_phone` — the supplier's WhatsApp/SMS number in international format (E.164, e.g. +15551234567), used to message them from a purchase order.\n\n- `purchase_order_format` — only allowed on PUT.\n- `purchase_order_csv_columns` — optional array of column keys controlling which columns appear in this supplier's outgoing PO email CSV attachment. Each entry must be one of the keys returned by `GET /api/purchase-orders/csv-columns`. Set to `null` (or omit) to fall back to the tenant default. Set to an empty array to fall back to the tenant default. Order of the array determines column order in the CSV. Use the `POST /api/suppliers/:supplier/csv-sample` endpoint to preview the layout.\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.update`\n\nClearing `default_incoterm_id` (sending it as null/empty) also clears `default_incoterm_place` — a default named place is never kept without a default term.\n\n**Custom fields:** `custom_field_values` (optional array) fully replaces the supplier's stored custom field values when present — entries with an `id` update that existing value (the id must reference a custom-field value belonging to THIS supplier; a value id from another supplier is rejected with a 422), entries without one create a new value (`custom_field_id` required, must reference a custom field defined for suppliers), and any stored value row omitted from the array is deleted. Omit the key entirely to leave stored values untouched.\n\n**Advanced lead times:** `warehouse_lead_times` (optional array of `{ warehouse_id, leadtime }`) sets supplier-level per-warehouse lead-time overrides. Rows with a `warehouse_id` and a numeric `leadtime` are upserted; a warehouse omitted from the array has its override removed. Omit the key to leave overrides untouched.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme Supplier Updated\",\n  \"company_name\": \"Acme Wholesale International\",\n  \"primary_contact_name\": \"Bob Johnson\",\n  \"email\": \"orders@acmewholesale.com\",\n  \"purchase_order_email\": \"po@acmewholesale.com\",\n  \"messaging_phone\": \"+15551234567\",\n  \"leadtime\": 10,\n  \"warehouse_lead_times\": [\n    {\n      \"warehouse_id\": 2,\n      \"leadtime\": 20\n    },\n    {\n      \"warehouse_id\": 5,\n      \"leadtime\": 45\n    }\n  ],\n  \"minimum_order_quantity\": 15,\n  \"target_stock_days\": 45,\n  \"po_processing_method\": \"email\",\n  \"auto_fulfill_dropship\": true,\n  \"auto_generate_backorder_po\": true,\n  \"purchase_order_format\": null,\n  \"purchase_order_csv_columns\": [\n    \"sku\",\n    \"barcode\",\n    \"name\",\n    \"qty_ordered\",\n    \"unit_cost\",\n    \"extended_cost\"\n  ],\n  \"address\": {\n    \"address1\": \"100 Supplier Lane Updated\",\n    \"city\": \"Sydney\",\n    \"zip\": \"2000\",\n    \"country\": \"Australia\",\n    \"country_code\": \"AU\",\n    \"label\": \"Default\"\n  },\n  \"pricing\": [\n    {\n      \"id\": 1\n    },\n    {\n      \"id\": 2\n    }\n  ],\n  \"default_incoterm_id\": 12,\n  \"default_incoterm_place\": \"Shanghai Port, CN\",\n  \"custom_field_values\": [\n    {\n      \"id\": 21,\n      \"custom_field_id\": 3,\n      \"value\": \"Silver\"\n    },\n    {\n      \"custom_field_id\": 5,\n      \"value\": \"2027-01-15\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Acme Supplier Updated\",\n    \"leadtime\": 10,\n    \"warehouse_lead_times\": [\n      {\n        \"warehouse_id\": 2,\n        \"warehouse_name\": \"Main DC\",\n        \"leadtime\": 20\n      },\n      {\n        \"warehouse_id\": 5,\n        \"warehouse_name\": \"West Coast Store\",\n        \"leadtime\": 45\n      }\n    ],\n    \"custom_field_values\": [\n      {\n        \"id\": 21,\n        \"custom_field_id\": 3,\n        \"value\": \"Silver\",\n        \"name\": \"Preferred Tier\",\n        \"slug\": \"preferred_tier\",\n        \"field_type\": \"dropdown\",\n        \"options\": [\n          \"Gold\",\n          \"Silver\",\n          \"Bronze\"\n        ],\n        \"description\": \"Negotiated service tier\",\n        \"is_visible_in_details\": true\n      },\n      {\n        \"id\": 23,\n        \"custom_field_id\": 5,\n        \"value\": \"2027-01-15\",\n        \"name\": \"Contract Renewal Date\",\n        \"slug\": \"contract_renewal_date\",\n        \"field_type\": \"date\",\n        \"options\": null,\n        \"description\": null,\n        \"is_visible_in_details\": true\n      }\n    ],\n    \"updated_at\": \"2024-01-20T11:00:00.000000Z\"\n  },\n  \"message\": \"supplier Acme Supplier Updated updated successfully\"\n}"}]},{"name":"Delete Supplier","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Delete a supplier. Returns 400 if the supplier is linked to purchase orders or other records. Deleting a supplier also removes its owned records, including its custom field values.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"supplier deleted successfully\"\n}"}]},{"name":"Set Supplier WhatsApp Contact","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/messaging-contact","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","messaging-contact"],"variable":[{"key":"supplier","value":"41","description":"The supplier ID."}]},"description":"Designate which of the supplier's contacts is its WhatsApp/SMS contact. The supplier's messaging number is synced to that contact's phone. Send `contact_id: null` to clear the designation (the stored number is kept). Returns the updated supplier.\n\nRequires the `suppliers.update` permission. Returns 404 when the contact does not belong to the supplier.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"contact_id\": 5012\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/messaging-contact","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","messaging-contact"],"variable":[{"key":"supplier","value":"41","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41,\n    \"name\": \"Acme Corp\",\n    \"messaging_phone\": \"+15551234567\"\n  }\n}"}]},{"name":"Merge Suppliers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/merge","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","merge"],"variable":[{"key":"supplier","value":"58","description":"Source supplier ID — this supplier is merged away and permanently deleted"}]},"description":"Merge one supplier into another. The supplier in the URL is the **source**: all of its records are re-pointed to the target, and the source is then **permanently deleted**. **This operation is irreversible — there is no undo.**\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody:\n- `target_supplier_id` (integer, required) — the surviving supplier that absorbs everything.\n\nWhat gets transferred to the target: purchase orders, purchase invoices, bills, vendor credits, vendor deposits, inbound shipments, supplier warehouses, inventory allocations, manufacturing/contractor references, cost entries, and forecast configurations. Supplier-product links, pricing-tier attachments, supplier inventory, and metric snapshots move too — where the target already has an equivalent record (e.g. the same product), the source's duplicate is dropped in favor of the target's. If the source was a product's default supplier and the target also supplies that product, the target becomes the default. Custom field values move to the target as well — where the target already has a value for the same custom field, the target's value is kept and the source's is dropped.\n\nErrors (422):\n- merging a supplier into itself\n- the target supplier does not exist\n- source and target are different types (a product supplier cannot merge with a service provider)\n- the target supplier is archived (unarchive it first)\n\nSynchronous — completes in one transaction. Requires the `suppliers:write` token scope and permission to delete suppliers.","body":{"mode":"raw","raw":"{\n  \"target_supplier_id\": 41\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/merge","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","merge"],"variable":[{"key":"supplier","value":"58","description":"Source supplier ID — this supplier is merged away and permanently deleted"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The supplier merged into 'Acme Corp' successfully\",\n  \"data\": {\n    \"name\": \"Acme Corp\",\n    \"id\": 41,\n    \"type\": \"goods\",\n    \"type_label\": \"Product Supplier\",\n    \"company_name\": \"Acme Corporation\",\n    \"email\": \"orders@acme.com\",\n    \"primary_contact_name\": \"John Doe\",\n    \"purchase_order_email\": \"po@acme.com\",\n    \"messaging_phone\": \"+15551234567\",\n    \"website\": \"https://acme.com\",\n    \"leadtime\": 14,\n    \"minimum_order_quantity\": 50,\n    \"target_stock_days\": 60,\n    \"minimum_purchase_order\": \"500.00\",\n    \"minimum_purchase_order_quantity\": 100,\n    \"purchase_order_format\": \"pdf\",\n    \"purchase_order_csv_columns\": null,\n    \"created_at\": \"2025-11-02T09:15:22.000000Z\",\n    \"updated_at\": \"2026-07-06T18:40:00.000000Z\",\n    \"archived_at\": null,\n    \"address\": {\n      \"id\": 913,\n      \"label\": null,\n      \"name\": \"Acme Corp\",\n      \"phone\": \"+1 555 0100\",\n      \"company\": \"Acme Corporation\",\n      \"address1\": \"100 Main St\",\n      \"address2\": null,\n      \"address3\": null,\n      \"city\": \"Austin\",\n      \"province\": \"Texas\",\n      \"province_code\": \"TX\",\n      \"zip\": \"78701\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\",\n      \"fax\": null,\n      \"redacted\": false\n    },\n    \"warehouses\": [\n      {\n        \"id\": 12,\n        \"name\": \"Acme Dropship WH\",\n        \"dropship_enabled\": true,\n        \"direct_returns\": false,\n        \"customer_returns\": false\n      }\n    ],\n    \"default_pricing_tier\": {\n      \"id\": 3,\n      \"name\": \"Wholesale\",\n      \"currency_code\": \"USD\"\n    },\n    \"default_warehouse_id\": 12,\n    \"default_store_id\": null,\n    \"po_processing_method\": null,\n    \"po_batch_schedule\": null,\n    \"default_shipping_method\": null,\n    \"auto_fulfill_dropship\": false,\n    \"auto_submit_dropship_po\": false,\n    \"auto_generate_backorder_po\": false,\n    \"auto_submit_backorder_po\": false,\n    \"auto_split_backorder_po_by_brand\": false,\n    \"auto_receive_backorder_po\": false,\n    \"backorder_po_schedule\": null,\n    \"default_stock_level\": null,\n    \"default_tax_rate_id\": null,\n    \"default_payment_term_id\": 2,\n    \"default_deposit_percentage\": null,\n    \"auto_apply_deposits\": false,\n    \"wire_instructions\": null,\n    \"default_payment_term\": {\n      \"id\": 2,\n      \"name\": \"Net 30\",\n      \"generated_description\": \"Net 30\"\n    },\n    \"timezone\": null,\n    \"products_count\": null\n  }\n}"}]},{"name":"Get Supplier Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/activity-log","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","activity-log"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Rolled-up activity timeline for a single supplier. Returns the supplier's own field changes plus related activity across its purchase orders (and their lines and invoices), vendor credits (and their lines and shipments), vendor deposits, bills, and supplier products (and pricing). Results are paginated and ordered newest-first.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token and the suppliers.show permission.\n\nFilters: filter[event] (created, updated, deleted, bulk_upsert), filter[source] (the origin of the change), filter[batch_uuid] (a single bulk batch), and filter[search] (matches actor name, event, changed properties, and related record type). Pagination: per_page (default 15)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/activity-log","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","activity-log"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 48213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Supplier\",\n      \"subject_id\": 35,\n      \"properties\": {\n        \"source\": \"manual\",\n        \"attributes\": {\n          \"leadtime\": 10\n        },\n        \"old\": {\n          \"leadtime\": 7\n        },\n        \"metadata\": {\n          \"name\": \"HOGTUNES\",\n          \"type\": \"service\",\n          \"company_name\": \"Hogtunes Inc\"\n        }\n      },\n      \"causer_name\": \"Kelly McKeown\",\n      \"created_at\": \"2026-07-06T14:22:11.000000Z\"\n    },\n    {\n      \"id\": 48190,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"PurchaseOrder\",\n      \"subject_id\": 9021,\n      \"properties\": {\n        \"source\": \"manual\",\n        \"attributes\": {\n          \"status\": \"draft\",\n          \"supplier_id\": 35\n        },\n        \"metadata\": {\n          \"purchase_order_number\": \"PO-9021\"\n        }\n      },\n      \"causer_name\": \"Kelly McKeown\",\n      \"created_at\": \"2026-07-05T09:10:03.000000Z\"\n    },\n    {\n      \"id\": 48001,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"Bill\",\n      \"subject_id\": 412,\n      \"properties\": {\n        \"source\": \"manual\",\n        \"metadata\": {\n          \"invoice_number\": \"INV-412\",\n          \"supplier_id\": 35,\n          \"invoice_date\": \"2026-07-01\"\n        }\n      },\n      \"causer_name\": \"System\",\n      \"created_at\": \"2026-07-01T00:05:44.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 52,\n  \"from\": 1,\n  \"to\": 15,\n  \"path\": \"{{protocol}}{{domain}}/api/suppliers/35/activity-log\",\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/suppliers/35/activity-log?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/suppliers/35/activity-log?page=4\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/suppliers/35/activity-log?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Archive Supplier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/archive","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","archive"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Archive a single supplier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/archive","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","archive"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Acme Supplier\"\n  },\n  \"message\": \"supplier Acme Supplier archived successfully\"\n}"}]},{"name":"Unarchive Supplier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/unarchived","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","unarchived"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Unarchive a previously archived supplier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/unarchived","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","unarchived"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Acme Supplier\",\n    \"archived_at\": null\n  },\n  \"message\": \"supplier Acme Supplier unarchived successfully\"\n}"}]},{"name":"Download PO CSV Sample","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/csv-sample","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","csv-sample"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"**Legacy proxy.** Generate and download a 3-row sample CSV showing exactly which columns will be included in this supplier's outgoing PO email attachment.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis endpoint is kept for backward compatibility — new clients should call `POST /api/suppliers/:supplier/po-sample` instead, which supports both CSV and XLSX (`format=xlsx`). Internally this route forwards to `po-sample` with `format=csv` forced.\n\nUsed by the per-supplier CSV column picker so users can preview the layout before saving.\n\nRequest body (all optional):\n- `columns` (array of strings) — Unsaved column selection to preview. If omitted, the saved supplier preference is used; if that is also empty, the tenant default falls through, then the system default (every registered column).\n\nValid column keys (current registry): `purchase_order`, `sku`, `barcode`, `supplier_sku`, `name`, `qty_ordered`, `unit_cost`, `extended_cost`. Unknown keys are silently dropped.\n\nThe response is a CSV file download (`Content-Type: text/csv`), not JSON.\n\nAuthentication: Requires Bearer token. Scope: `suppliers:rw`.","body":{"mode":"raw","raw":"{\n  \"columns\": [\n    \"sku\",\n    \"barcode\",\n    \"name\",\n    \"qty_ordered\",\n    \"unit_cost\",\n    \"extended_cost\"\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Download PO Sample (CSV/XLSX)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/po-sample","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","po-sample"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Generate and download a 3-row sample of the file the supplier will receive when this PO is submitted. Supports both CSV and XLSX (controlled by `format`). Backs the per-supplier PO file attachment column picker so users can preview the layout before saving.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body (all optional):\n- `format` (string, `csv` | `xlsx`) — Output format. Defaults to `csv`. Use `xlsx` to preview the spreadsheet with text-typed cells (no scientific-notation corruption of long barcodes/SKUs).\n- `columns` (array of strings) — Unsaved column selection to preview. If omitted, the saved supplier preference is used; if that is also empty, the tenant default falls through, then the system default (every registered column).\n\nValid column keys (current registry): `purchase_order`, `sku`, `barcode`, `supplier_sku`, `name`, `qty_ordered`, `unit_cost`, `extended_cost`. Unknown keys are silently dropped.\n\n**CSV behavior:** Values are written as plain CSV strings — quoted when they contain commas, quotes, or newlines per RFC 4180. No formula-prefix escaping is applied; long numeric-text columns (barcode, SKU) may be coerced to scientific notation by Excel on open. Use XLSX format to avoid that.\n\n**XLSX behavior:** Numeric-text columns are written with `t=\"inlineStr\"` cells (force text), quantities as integers, costs with the `#,##0.00` price format.\n\nThe response is a binary file download — `text/csv` for CSV, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for XLSX. Not JSON.\n\nValidation:\n- `format` must be one of `csv`, `xlsx` (any other value returns 422).\n\nAuthentication: Requires Bearer token. Scope: `suppliers:rw`.","body":{"mode":"raw","raw":"{\n  \"format\": \"xlsx\",\n  \"columns\": [\n    \"sku\",\n    \"barcode\",\n    \"name\",\n    \"qty_ordered\",\n    \"unit_cost\",\n    \"extended_cost\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/po-sample","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","po-sample"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unauthenticated.\"\n}"}]},{"name":"Bulk Archive Suppliers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/archive","host":["{{baseUrl}}"],"path":["api","suppliers","archive"]},"description":"Bulk archive suppliers by IDs or by applying to all filtered results.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/archive","host":["{{baseUrl}}"],"path":["api","suppliers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 suppliers archived successfully.\"\n}"}]},{"name":"Bulk Unarchive Suppliers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/unarchive","host":["{{baseUrl}}"],"path":["api","suppliers","unarchive"]},"description":"Bulk unarchive suppliers by IDs or by applying to all filtered results.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/unarchive","host":["{{baseUrl}}"],"path":["api","suppliers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 suppliers unarchived successfully.\"\n}"}]},{"name":"List Supplier Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/products?query=&limit=15&page=1","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","products"],"query":[{"key":"query","value":"","description":"Search by supplier SKU, product SKU, or product name","disabled":true},{"key":"limit","value":"15","description":"Items per page. Pass negative value to return all.","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Retrieve all products linked to a supplier. Supports search by supplier SKU, product SKU, or name (using Typesense with SQL fallback).\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nPass a negative limit to return all products without pagination."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/products?query=&limit=15&page=1","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","products"],"query":[{"key":"query","value":"","description":"Search by supplier SKU, product SKU, or product name","disabled":true},{"key":"limit","value":"15","description":"Items per page. Pass negative value to return all.","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"supplier_sku\": \"ACM-001\",\n      \"product_id\": 12,\n      \"product\": {\n        \"id\": 12,\n        \"sku\": \"PROD-001\",\n        \"name\": \"Widget A\"\n      },\n      \"supplier_id\": 1,\n      \"cost\": 9.99,\n      \"minimum_order_quantity\": 10\n    }\n  ],\n  \"status\": \"success\",\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"total\": 25\n}"}]},{"name":"Get Supplier Products Stock","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/products-stocks","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","products-stocks"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Get stock levels for specific products from a supplier's perspective.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    15,\n    20\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/products-stocks","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","products-stocks"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 12,\n      \"sku\": \"PROD-001\",\n      \"supplier_stock\": 500,\n      \"available_stock\": 450\n    }\n  ]\n}"}]},{"name":"Get Supplier Pricing Tiers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10). -1 returns all rows on one page (the legacy `limit` param is accepted as an alias)","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"List pricing tiers attached to a supplier using Spatie QueryBuilder (filter[key]=value bracket format).\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe legacy table_specifications flag is now ignored. Response is a standard Laravel paginator (top-level data, current_page, last_page, per_page, total, links — not resource meta).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\nQuery params: page, per_page (default 10; -1 = all rows), filter[search], filter[name], filter[currency_code], filter[pricing_type], filter[is_default], filter[archived], filter_groups (base64-encoded advanced filter tree), sort (default -is_default,-created_at)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10). -1 returns all rows on one page (the legacy `limit` param is accepted as an alias)","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard\",\n      \"currency_code\": \"AUD\",\n      \"pricing_type\": \"fixed_price\",\n      \"is_default\": true,\n      \"base_pricing_tier_id\": null,\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T08:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/suppliers/1/pricing-tiers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/suppliers/1/pricing-tiers?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/suppliers/1/pricing-tiers\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Attach Pricing Tier to Supplier","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers/{supplierPricingTier}/attach","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers",":supplierPricingTier","attach"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"},{"key":"supplierPricingTier","value":"2","description":"Supplier Pricing Tier ID to attach"}]},"description":"Attach an existing pricing tier to a supplier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers/{supplierPricingTier}/attach","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers",":supplierPricingTier","attach"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"},{"key":"supplierPricingTier","value":"2","description":"Supplier Pricing Tier ID to attach"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {},\n  \"message\": \"Pricing tier attached successfully.\"\n}"}]},{"name":"Detach Pricing Tier from Supplier","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers/{tierId}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers",":tierId"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"},{"key":"tierId","value":"2","description":"Pricing Tier ID to remove"}]},"description":"Delete a pricing tier from a supplier. Cannot delete default or linked pricing tiers.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/pricing-tiers/{tierId}","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","pricing-tiers",":tierId"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"},{"key":"tierId","value":"2","description":"Pricing Tier ID to remove"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Pricing tier deleted successfully.\"\n}"}]},{"name":"Get Supplier Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/warehouses?page=1&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","warehouses"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Get all warehouses associated with a supplier, with list view support.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/warehouses?page=1&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","warehouses"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"name\": \"Acme Warehouse\",\n      \"type\": \"supplier\",\n      \"supplier_id\": 1,\n      \"address\": {\n        \"address1\": \"100 Supplier Lane\",\n        \"city\": \"Sydney\",\n        \"country_code\": \"AU\"\n      }\n    }\n  ]\n}"}]},{"name":"Create Supplier Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/warehouses","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","warehouses"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Create a new warehouse for a supplier. Automatically initializes supplier inventory for the new warehouse. If this is the supplier's first warehouse (or is_default is true), it becomes the default warehouse.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"raw","raw":"{\n  \"name\": \"Sydney Warehouse\",\n  \"is_default\": false,\n  \"address\": {\n    \"label\": \"Main\",\n    \"address1\": \"500 Warehouse Rd\",\n    \"city\": \"Sydney\",\n    \"province\": \"New South Wales\",\n    \"province_code\": \"NSW\",\n    \"zip\": \"2000\",\n    \"country\": \"Australia\",\n    \"country_code\": \"AU\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/warehouses","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","warehouses"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Sydney Warehouse\",\n    \"type\": \"supplier\",\n    \"supplier_id\": 1,\n    \"address\": {\n      \"address1\": \"500 Warehouse Rd\",\n      \"city\": \"Sydney\",\n      \"country_code\": \"AU\"\n    }\n  },\n  \"message\": \"warehouse created successfully\"\n}"}]},{"name":"Get Warehouse Linked Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/warehouses/{warehouse}/linked-orders","host":["{{baseUrl}}"],"path":["api","suppliers","warehouses",":warehouse","linked-orders"],"variable":[{"key":"warehouse","value":"2","description":"Warehouse ID"}]},"description":"Get the count of open purchase orders linked to a warehouse. Used before deleting a warehouse to check for dependencies.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/warehouses/{warehouse}/linked-orders","host":["{{baseUrl}}"],"path":["api","suppliers","warehouses",":warehouse","linked-orders"],"variable":[{"key":"warehouse","value":"2","description":"Warehouse ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"linked_orders\": 3\n  }\n}"}]},{"name":"Preview Supplier Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/import/preview","host":["{{baseUrl}}"],"path":["api","suppliers","import","preview"]},"description":"Preview a supplier import from a CSV file.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/import/preview","host":["{{baseUrl}}"],"path":["api","suppliers","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 20,\n    \"valid\": 18,\n    \"errors\": 2\n  }\n}"}]},{"name":"Import Suppliers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/import","host":["{{baseUrl}}"],"path":["api","suppliers","import"]},"description":"Import suppliers from a CSV file.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/import","host":["{{baseUrl}}"],"path":["api","suppliers","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 18,\n    \"skipped\": 2\n  },\n  \"message\": \"Import completed\"\n}"}]},{"name":"Preview Supplier Inventory Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/import/preview","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","import","preview"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Preview supplier inventory import from a CSV file.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/import/preview","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","import","preview"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 100,\n    \"valid\": 98,\n    \"errors\": 2\n  }\n}"}]},{"name":"Import Supplier Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/import","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","import"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Import inventory levels for a specific supplier from a CSV file.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/import","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","import"],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 98,\n    \"skipped\": 2\n  },\n  \"message\": \"Inventory imported successfully\"\n}"}]},{"name":"Export Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/export","host":["{{baseUrl}}"],"path":["api","v2","suppliers","export"]},"description":"Export the supplier list as a spreadsheet file. Synchronous — the response body is the file itself (`text/csv` or, with `format=xlsx`, an Excel workbook) named `suppliers-{timestamp}.{format}`.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAccepts the same filters as the supplier list, so you can export a filtered subset. Every matching supplier is included (no pagination), ordered by ID ascending, with a fixed column set: ID, Name, Company Name, Email, Contact Name, Lead Time, Min Order Qty, Created At, Updated At, PO Email, Website, Minimum PO $, Minimum PO Qty, Fax, address fields (lines 1-3, city, state/province and code, zip, country and code, label), Default Pricing Tier ID, Default Warehouse ID, and Default Store ID.\n\nBy default only non-archived suppliers are exported; use `filter[archived]=all` or `filter[archived]=only` to change that.\n\nRequires the `suppliers:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers/export","host":["{{baseUrl}}"],"path":["api","v2","suppliers","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"ID,Name,Company Name,Email,Contact Name,Lead Time,Min Order Qty,Created At,Updated At,PO Email,Website,\"Minimum PO $\",\"Minimum PO Qty\",Fax,Address Line 1,Address Line 2,Address Line 3,City,State/Province,State/Province Code,Zip/Postal Code,Country,Country Code,Address Label,Default Pricing Tier ID,Default Warehouse ID,Default Store ID\n41,Acme Corp,Acme Corporation,orders@acme.com,John Doe,14,50,2025-11-02 09:15:22,2026-06-30 11:03:10,po@acme.com,https://acme.com,500.00,100,,100 Main St,,,Austin,Texas,TX,78701,United States,US,,3,12,"}]},{"name":"Request Invoices (Consolidated)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/request-invoices","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","request-invoices"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"Send a supplier one consolidated email requesting the outstanding invoices for several purchase orders at once. Each selected PO is re-validated server-side: it must belong to this supplier AND still be awaiting its invoice — ineligible ids are skipped and reported back (not emailed). Every PO that IS sent is stamped (invoice_requested_at, invoice_request_count++, invoice_last_requested_by).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIf none of the selected POs are eligible, returns 422.\n\nAuthentication: Requires Bearer token.\n**Requires permission:** `purchase_orders.update`. Throttled: 60 requests/min.\n\n**Body fields:**\n- to (string, required) — recipient email\n- subject (string, required, max 255)\n- purchase_order_ids (array of ints, required, min 1) — POs to include\n- note (string, optional, max 2000)\n- cc (array of emails, optional, max 10)\n\nRequires both the suppliers and purchase-orders token scopes (it mutates purchase orders by stamping invoice-request tracking), plus the purchase_orders.update permission.","body":{"mode":"raw","raw":"{\n  \"to\": \"ap@acme.example\",\n  \"subject\": \"Outstanding invoices — 3 purchase orders\",\n  \"purchase_order_ids\": [\n    4521,\n    4530,\n    4544\n  ],\n  \"note\": \"Please send the invoices for the orders listed below; several are already prepaid.\",\n  \"cc\": [\n    \"buyer@ourcompany.example\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/request-invoices","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","request-invoices"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"sent_count\": 2,\n  \"skipped\": [\n    {\n      \"purchase_order_id\": 4544,\n      \"reason\": \"Not awaiting an invoice for this supplier.\"\n    }\n  ]\n}"}]},{"name":"Manage Invoice Reminders","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/invoice-reminders","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","invoice-reminders"],"variable":[{"key":"purchase_order","value":"4521","description":"Purchase Order ID"}]},"description":"Set the automated invoice-reminder mode for a purchase order: inherit (use the supplier/tenant setting), on, or off. Setting on arms the recurring chase when the PO is still awaiting its invoice; off stops it.\n\nAuthentication: Requires Bearer token.\nRequires permission: purchase_orders.update. Throttled: 60 requests/min.\n\nBody fields:\n- mode (string, required) — one of: inherit, on, off","body":{"mode":"raw","raw":"{\n  \"mode\": \"on\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/invoice-reminders","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","invoice-reminders"],"variable":[{"key":"purchase_order","value":"4521","description":"Purchase Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 4521,\n  \"purchase_order_number\": \"PO-004521\",\n  \"invoice_status\": \"uninvoiced\",\n  \"invoice_requested_at\": \"2026-07-09T09:30:00+00:00\",\n  \"invoice_request_count\": 1,\n  \"invoice_reminder_state\": \"active\",\n  \"invoice_reminder_next_at\": \"2026-07-16T09:30:00+00:00\",\n  \"invoice_reminder_paused_reason\": null,\n  \"invoice_reply_received_at\": null,\n  \"invoice_reminders_enabled\": true,\n  \"invoice_reminders_mode\": \"on\"\n}"}]},{"name":"Update Supplier Invoice Reminders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/invoice-reminders","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","invoice-reminders"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"Update a supplier's automated invoice-reminder settings — the mode plus optional cadence overrides. These resolve above the tenant default and below any per-PO override.\n\nAuthentication: Requires Bearer token.\nRequires permission: purchase_orders.update.\n\nBody fields:\n- invoice_reminders_mode (string, required) — inherit | on | off\n- invoice_reminder_interval_days (int, nullable, 1-90) — days between reminders (blank = tenant default)\n- invoice_reminder_max_count (int, nullable, 1-12) — total requests (blank = tenant default)\n- invoice_reminder_start_after_days (int, nullable, 0-90) — delay before the first reminder (blank = tenant default)","body":{"mode":"raw","raw":"{\n  \"invoice_reminders_mode\": \"on\",\n  \"invoice_reminder_interval_days\": 10,\n  \"invoice_reminder_max_count\": 4,\n  \"invoice_reminder_start_after_days\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/invoice-reminders","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","invoice-reminders"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"name\": \"Acme Co\",\n  \"invoice_reminders_mode\": \"on\",\n  \"invoice_reminder_interval_days\": 10,\n  \"invoice_reminder_max_count\": 4,\n  \"invoice_reminder_start_after_days\": 3\n}"}]},{"name":"Verify Supplier Bank Details","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/verify-bank-details","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","verify-bank-details"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"Mark this supplier's wire instructions as verified out-of-band (for example, confirmed by phone with a known contact). Records who verified them and when, and clears the non-blocking bank-details warning shown when authorizing payment on the supplier's bills.\n\nEditing a supplier's wire instructions afterwards automatically clears this verification, so changed payee details must be re-verified.\n\nAuthentication: Requires Bearer token.\nRequires permission: suppliers.update.\n\nReturns 422 if the supplier has no wire instructions to verify."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/verify-bank-details","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","verify-bank-details"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Acme Manufacturing Co.\",\n    \"type\": \"goods\",\n    \"wire_instructions\": \"Beneficiary: Acme Manufacturing Co.\\nBank: HSBC Hong Kong\\nSWIFT: HSBCHKHH\\nIBAN: HK29 2000 0000 0000 4821\",\n    \"wire_instructions_verified_at\": \"2026-07-11T14:32:00+00:00\",\n    \"wire_instructions_verified_by\": 7,\n    \"wire_instructions_verified_by_name\": \"Jane Cooper\"\n  },\n  \"message\": \"supplier Acme Manufacturing Co. updated successfully\"\n}"}]},{"name":"Unverify Supplier Bank Details","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/unverify-bank-details","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","unverify-bank-details"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"Clear a previous out-of-band verification of this supplier's wire instructions. The bank-details warning reappears on the supplier's bills until the details are verified again.\n\nAuthentication: Requires Bearer token.\nRequires permission: suppliers.update."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/suppliers/{supplier}/unverify-bank-details","host":["{{baseUrl}}"],"path":["api","suppliers",":supplier","unverify-bank-details"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Acme Manufacturing Co.\",\n    \"type\": \"goods\",\n    \"wire_instructions\": \"Beneficiary: Acme Manufacturing Co.\\nBank: HSBC Hong Kong\\nSWIFT: HSBCHKHH\\nIBAN: HK29 2000 0000 0000 4821\",\n    \"wire_instructions_verified_at\": null,\n    \"wire_instructions_verified_by\": null,\n    \"wire_instructions_verified_by_name\": null\n  },\n  \"message\": \"supplier Acme Manufacturing Co. updated successfully\"\n}"}]},{"name":"Check Suppliers Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/suppliers/deletable","host":["{{baseUrl}}"],"path":["api","suppliers","deletable"]},"description":"Check which suppliers can be deleted before performing bulk delete.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires IsPowerUserAccess middleware.\n\n**Requires permission:** `suppliers.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ],\n  \"scope\": \"ids\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/suppliers/deletable","host":["{{baseUrl}}"],"path":["api","suppliers","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Acme Supplier\",\n      \"deletable\": false,\n      \"reason\": \"Linked to purchase orders\",\n      \"reason_details\": {}\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Beta Supplier\",\n      \"deletable\": true,\n      \"reason\": null,\n      \"reason_details\": null\n    }\n  ]\n}"}]},{"name":"Create Supplier Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-products","host":["{{baseUrl}}"],"path":["api","supplier-products"]},"description":"Creates a new supplier product relationship (a product sold by a specific supplier).\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- supplier_id (required): Supplier ID (must exist in suppliers table)\n- product_id (required): Product ID (must be unique per supplier; must exist in products table)\n- supplier_sku (nullable, max:255): Supplier's own SKU — must be unique per supplier\n- leadtime (nullable, integer): Lead time in days\n- minimum_order_quantity (nullable, numeric): Minimum order quantity (max 999,999)\n- target_stock_days (nullable, integer): Target stock days (1-365)\n- is_default (boolean): Whether this is the default supplier for this product\n- default_tax_rate_id (nullable): Tax rate ID for this supplier product","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 3,\n  \"product_id\": 42,\n  \"supplier_sku\": \"ACM-WIDGET-001\",\n  \"leadtime\": 7,\n  \"minimum_order_quantity\": 50,\n  \"target_stock_days\": 30,\n  \"is_default\": true,\n  \"default_tax_rate_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-products","host":["{{baseUrl}}"],"path":["api","supplier-products"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"product_id\": 42,\n    \"supplier_id\": 3,\n    \"supplier_sku\": \"ACM-WIDGET-001\",\n    \"leadtime\": 7,\n    \"minimum_order_quantity\": 50,\n    \"target_stock_days\": 30,\n    \"is_default\": true,\n    \"default_tax_rate_id\": 1,\n    \"product_leadtime\": 7,\n    \"product_minimum_order_quantity\": 50,\n    \"product_target_stock_days\": 30,\n    \"created_at\": \"2024-01-15T10:00:00Z\",\n    \"updated_at\": \"2024-01-15T10:00:00Z\"\n  },\n  \"message\": \"supplier product created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Supplier Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Returns full details for a supplier product including product, supplier, pricing tiers, and inventory levels per warehouse.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"product_id\": 42,\n    \"supplier_id\": 3,\n    \"supplier_sku\": \"ACM-WIDGET-001\",\n    \"leadtime\": 7,\n    \"minimum_order_quantity\": 50,\n    \"target_stock_days\": 30,\n    \"is_default\": true,\n    \"default_tax_rate_id\": 1,\n    \"supplier\": {\n      \"id\": 3,\n      \"name\": \"Acme Supplies Co.\",\n      \"default_tax_rate_id\": 1\n    },\n    \"supplier_default_tax_rate_id\": 1,\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"average_cost\": 12.5,\n      \"leadtime\": 7\n    },\n    \"supplier_stock\": {\n      \"id\": 8,\n      \"quantity\": 500,\n      \"warehouse_id\": 1\n    },\n    \"pricing\": [\n      {\n        \"id\": 20,\n        \"supplier_pricing_tier_id\": 1,\n        \"price\": 10,\n        \"min_quantity\": 1\n      }\n    ],\n    \"inventories\": [\n      {\n        \"id\": 8,\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"quantity\": 500,\n        \"in_stock\": true,\n        \"discontinued\": false,\n        \"eta\": null,\n        \"source\": \"manual\",\n        \"updated_at\": \"2024-01-10T08:00:00Z\"\n      }\n    ],\n    \"product_leadtime\": 7,\n    \"product_minimum_order_quantity\": 50,\n    \"product_target_stock_days\": 30,\n    \"created_at\": \"2024-01-15T10:00:00Z\",\n    \"updated_at\": \"2024-01-15T10:00:00Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Supplier Product","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Updates an existing supplier product.\nAuthentication: Requires Bearer token.\nNote: If supplier_id or product_id changes, supplier inventories are cleared and re-initialized. A warning is included in the response.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"supplier_sku\": \"ACM-WIDGET-001-V2\",\n  \"leadtime\": 10,\n  \"minimum_order_quantity\": 100,\n  \"target_stock_days\": 45,\n  \"is_default\": true,\n  \"default_tax_rate_id\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"supplier_sku\": \"ACM-WIDGET-001-V2\",\n    \"leadtime\": 10,\n    \"minimum_order_quantity\": 100,\n    \"target_stock_days\": 45,\n    \"updated_at\": \"2024-01-16T09:00:00Z\"\n  },\n  \"message\": \"supplier product ACM-WIDGET-001-V2 updated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Supplier Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Deletes a supplier product and its associated inventories.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"supplier product deleted.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Supplier Product Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search across causer name, properties, event","disabled":true}],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Returns paginated activity log for a supplier product.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search across causer name, properties, event","disabled":true}],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 300,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"SupplierProduct\",\n      \"subject_id\": 15,\n      \"properties\": {\n        \"old\": {\n          \"leadtime\": 7\n        },\n        \"attributes\": {\n          \"leadtime\": 10\n        }\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2024-01-16T09:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Supplier Product Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Returns paginated notes for a supplier product, most recent first.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": 25,\n        \"note\": \"Lead time confirmed by supplier.\",\n        \"is_pinned\": true,\n        \"user\": {\n          \"id\": 5,\n          \"name\": \"John Smith\"\n        },\n        \"created_at\": \"2024-01-15T10:00:00Z\"\n      }\n    ],\n    \"current_page\": 1,\n    \"total\": 1\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Add Supplier Product Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Adds a note to a supplier product.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- note (required): Note text content\n- is_pinned (optional, boolean): Whether to pin the note","body":{"mode":"raw","raw":"{\n  \"note\": \"Lead time confirmed by supplier via email on 2024-01-15.\",\n  \"is_pinned\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 26,\n    \"note\": \"Lead time confirmed by supplier via email on 2024-01-15.\",\n    \"is_pinned\": false,\n    \"user\": {\n      \"id\": 5,\n      \"name\": \"John Smith\"\n    },\n    \"created_at\": \"2024-01-15T11:00:00Z\"\n  },\n  \"message\": \"note created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Supplier Product Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes/{note}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes",":note"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"},{"key":"note","value":"26","description":"Note ID to delete"}]},"description":"Deletes a note from a supplier product.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/notes/{note}","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","notes",":note"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"},{"key":"note","value":"26","description":"Note ID to delete"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 26 deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Update Pricing Tiers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/pricing","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","pricing"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]},"description":"Updates pricing tiers for a supplier product.\nAuthentication: Requires Bearer token.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- pricing (required, array): Array of pricing tier entries\n  - pricing.*.supplier_pricing_tier_id (required, integer): Must exist in supplier_pricing_tiers table\n  - pricing.*.price (required, numeric, min:0): Price for this tier","body":{"mode":"raw","raw":"{\n  \"pricing\": [\n    {\n      \"supplier_pricing_tier_id\": 1,\n      \"price\": 10\n    },\n    {\n      \"supplier_pricing_tier_id\": 2,\n      \"price\": 9.5\n    },\n    {\n      \"supplier_pricing_tier_id\": 3,\n      \"price\": 9\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-products/{supplier_product}/pricing","host":["{{baseUrl}}"],"path":["api","supplier-products",":supplier_product","pricing"],"variable":[{"key":"supplier_product","value":"15","description":"Supplier product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"pricing\": [\n      {\n        \"id\": 20,\n        \"supplier_pricing_tier_id\": 1,\n        \"price\": 10\n      },\n      {\n        \"id\": 21,\n        \"supplier_pricing_tier_id\": 2,\n        \"price\": 9.5\n      },\n      {\n        \"id\": 22,\n        \"supplier_pricing_tier_id\": 3,\n        \"price\": 9\n      }\n    ]\n  },\n  \"message\": \"pricing 15 updated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"List Supplier Pricing Tiers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers?search=retail&sort=name&page=1&limit=25&archived=0","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"],"query":[{"key":"search","value":"retail","description":"General text search across searchable columns (name, currency_code)","disabled":true},{"key":"sort","value":"name","description":"Sort column. Prefix with - for descending. Sortable: name, currency_code, is_default, created_at, updated_at.","disabled":true},{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"25","description":"Results per page","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true}]},"description":"Returns a paginated list of supplier pricing tiers.\n\nAuthentication: Requires Bearer token.\n\nUses the list view trait supporting search, sort, pagination, and archived filtering.\n\nResponse fields: id, name, pricing_type (absolute|relative), base_pricing_tier_id, base_pricing_tier_name, adjustment_percentage, adjustment_fixed_amount, rounding_value, display_name, currency_code, is_default, dependent_tier_count, chain_depth, created_at, updated_at, archived_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers?search=retail&sort=name&page=1&limit=25&archived=0","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"],"query":[{"key":"search","value":"retail","description":"General text search across searchable columns (name, currency_code)","disabled":true},{"key":"sort","value":"name","description":"Sort column. Prefix with - for descending. Sortable: name, currency_code, is_default, created_at, updated_at.","disabled":true},{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"25","description":"Results per page","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Retail USD\",\n      \"pricing_type\": \"absolute\",\n      \"base_pricing_tier_id\": null,\n      \"base_pricing_tier_name\": null,\n      \"adjustment_percentage\": null,\n      \"adjustment_fixed_amount\": null,\n      \"rounding_value\": null,\n      \"display_name\": \"Retail USD (USD)\",\n      \"currency_code\": \"USD\",\n      \"is_default\": true,\n      \"dependent_tier_count\": 2,\n      \"chain_depth\": 0,\n      \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n      \"updated_at\": \"2024-03-15T10:00:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale USD\",\n      \"pricing_type\": \"relative\",\n      \"base_pricing_tier_id\": 1,\n      \"base_pricing_tier_name\": \"Retail USD\",\n      \"adjustment_percentage\": \"-15.0000\",\n      \"adjustment_fixed_amount\": null,\n      \"rounding_value\": \"0.0500\",\n      \"display_name\": \"Wholesale USD (USD)\",\n      \"currency_code\": \"USD\",\n      \"is_default\": false,\n      \"dependent_tier_count\": 0,\n      \"chain_depth\": 1,\n      \"created_at\": \"2024-01-12T09:00:00.000000Z\",\n      \"updated_at\": \"2024-03-20T11:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 25,\n  \"total\": 8\n}"}]},{"name":"Create Supplier Pricing Tier","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"]},"description":"Creates a new supplier pricing tier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `name` (required, max:255, unique in supplier_pricing_tiers)\n- `currency_code` (required, exists:currencies,code)\n- `pricing_type` (required, in:absolute,relative; defaults to 'absolute' if omitted)\n- `base_pricing_tier_id` (required_if:pricing_type,relative; nullable, integer, exists:supplier_pricing_tiers)\n- `adjustment_percentage` (required_if:pricing_type,relative; nullable, numeric, between:-99.9999,999.9999)\n- `adjustment_fixed_amount` (nullable, numeric, between:-999999.9999,999999.9999)\n- `rounding_value` (nullable, numeric, gt:0, max:999999.9999)\n\nBusiness rules:\n- Relative tiers inherit the currency of their root absolute tier\n- Circular references are rejected\n- A tier cannot reference itself as the base tier\n\n**Requires permission:** `supplier_pricing_tiers.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Wholesale USD\",\n  \"currency_code\": \"USD\",\n  \"pricing_type\": \"relative\",\n  \"base_pricing_tier_id\": 1,\n  \"adjustment_percentage\": -15,\n  \"adjustment_fixed_amount\": null,\n  \"rounding_value\": 0.05\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Wholesale USD\",\n    \"pricing_type\": \"relative\",\n    \"base_pricing_tier_id\": 1,\n    \"base_pricing_tier_name\": null,\n    \"adjustment_percentage\": \"-15.0000\",\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": \"0.0500\",\n    \"display_name\": \"Wholesale USD (USD)\",\n    \"currency_code\": \"USD\",\n    \"is_default\": false,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 1,\n    \"created_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Supplier pricing tier has been created successfully\"\n}"}]},{"name":"Bulk Delete Pricing Tiers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"]},"description":"Bulk deletes multiple supplier pricing tiers by ID.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `supplier_pricing_tiers.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 supplier pricing tiers have been deleted successfully\"\n}"}]},{"name":"Get Supplier Pricing Tier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single supplier pricing tier by ID.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Retail USD\",\n    \"pricing_type\": \"absolute\",\n    \"base_pricing_tier_id\": null,\n    \"base_pricing_tier_name\": null,\n    \"adjustment_percentage\": null,\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": null,\n    \"display_name\": \"Retail USD (USD)\",\n    \"currency_code\": \"USD\",\n    \"is_default\": true,\n    \"dependent_tier_count\": 2,\n    \"chain_depth\": 0,\n    \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"updated_at\": \"2024-03-15T10:00:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Supplier Pricing Tier","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing supplier pricing tier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation (PUT — currency_code cannot be changed; all other fields are sometimes/optional):\n- `name` (required, max:255, unique ignoring current record)\n- `pricing_type` (sometimes, in:absolute,relative)\n- `base_pricing_tier_id` (sometimes, required_if:pricing_type,relative; nullable, integer)\n- `adjustment_percentage` (sometimes, required_if:pricing_type,relative; nullable, numeric, between:-99.9999,999.9999)\n- `adjustment_fixed_amount` (sometimes, nullable, numeric, between:-999999.9999,999999.9999)\n- `rounding_value` (sometimes, nullable, numeric, gt:0)\n\nNote: currency_code is immutable — excluded from PUT validation.","body":{"mode":"raw","raw":"{\n  \"name\": \"Wholesale USD Updated\",\n  \"pricing_type\": \"relative\",\n  \"base_pricing_tier_id\": 1,\n  \"adjustment_percentage\": -20,\n  \"adjustment_fixed_amount\": null,\n  \"rounding_value\": 0.05\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Wholesale USD Updated\",\n    \"pricing_type\": \"relative\",\n    \"base_pricing_tier_id\": 1,\n    \"base_pricing_tier_name\": null,\n    \"adjustment_percentage\": \"-20.0000\",\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": \"0.0500\",\n    \"display_name\": \"Wholesale USD Updated (USD)\",\n    \"currency_code\": \"USD\",\n    \"is_default\": false,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 1,\n    \"created_at\": \"2024-01-12T09:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T13:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Supplier pricing tier Wholesale USD Updated has been updated successfully\"\n}"}]},{"name":"Delete Supplier Pricing Tier","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a supplier pricing tier. Will fail if:\n- The tier is the default tier\n- The tier has active supplier product prices\n- The tier is used in integration instance import mappings\n- The tier has active dependent relative tiers\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Supplier pricing tier Wholesale USD has been deleted successfully\"\n}"}]},{"name":"Archive Pricing Tier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/archive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a supplier pricing tier. Cannot archive the default tier or a tier that is the base for active dependent tiers.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/archive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Supplier pricing tier Wholesale USD has been archived successfully\"\n}"}]},{"name":"Unarchive Pricing Tier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a supplier pricing tier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Wholesale USD\",\n    \"pricing_type\": \"relative\",\n    \"base_pricing_tier_id\": 1,\n    \"base_pricing_tier_name\": null,\n    \"adjustment_percentage\": \"-15.0000\",\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": \"0.0500\",\n    \"display_name\": \"Wholesale USD (USD)\",\n    \"currency_code\": \"USD\",\n    \"is_default\": false,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 1,\n    \"created_at\": \"2024-01-12T09:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T14:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Supplier pricing tier Wholesale USD has been unarchived successfully\"\n}"}]},{"name":"Bulk Archive Pricing Tiers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/archive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","archive"]},"description":"Bulk archives multiple supplier pricing tiers. Default tiers and tiers with active dependents are skipped with warnings.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `supplier_pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/archive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 supplier pricing tiers have been archived successfully\"\n}"}]},{"name":"Bulk Unarchive Pricing Tiers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/unarchive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","unarchive"]},"description":"Bulk unarchives multiple supplier pricing tiers.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `supplier_pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/unarchive","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 supplier pricing tiers have been unarchived successfully\"\n}"}]},{"name":"Check Supplier Pricing Tiers Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/deletable","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","deletable"]},"description":"Checks whether each pricing tier can be safely deleted.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `ids` (required, array of integers, each must exist in supplier_pricing_tiers)\n- `ids.*` (integer)\n\n**Requires permission:** `supplier_pricing_tiers.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/deletable","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Retail USD\",\n      \"deletable\": false,\n      \"reason\": {\n        \"is_default\": \"Cannot delete default supplier pricing tier (Retail USD)\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale USD\",\n      \"deletable\": false,\n      \"reason\": {\n        \"supplierProducts\": \"Supplier pricing tier(Wholesale USD) is currently used by 8 supplier product(s)\"\n      }\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Unused Tier\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Check Supplier Pricing Tiers Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/archivable","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","archivable"]},"description":"Checks whether each pricing tier can be archived. Default tiers cannot be archived.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `ids` (required, array of integers, each must exist in supplier_pricing_tiers)\n- `ids.*` (integer)\n\n**Requires permission:** `supplier_pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/archivable","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Retail USD\",\n      \"is_default\": true,\n      \"archivable\": false,\n      \"reason\": {\n        \"is_default\": \"Cannot archive the default supplier pricing tier (Retail USD)\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale USD\",\n      \"is_default\": false,\n      \"archivable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 3,\n      \"name\": \"VIP USD\",\n      \"is_default\": false,\n      \"archivable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Set as Default","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/default","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Sets the specified pricing tier as the system default. Clears the is_default flag from the previously default tier.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBusiness rules:\n- Archived tiers cannot be set as default\n- Relative (non-absolute) tiers cannot be set as default"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/{id}/default","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers",":id","default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Wholesale USD\",\n    \"pricing_type\": \"absolute\",\n    \"base_pricing_tier_id\": null,\n    \"base_pricing_tier_name\": null,\n    \"adjustment_percentage\": null,\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": null,\n    \"display_name\": \"Wholesale USD (USD)\",\n    \"currency_code\": \"USD\",\n    \"is_default\": true,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 0,\n    \"created_at\": \"2024-01-12T09:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T15:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Supplier pricing tier Wholesale USD has been set as default successfully\"\n}"}]},{"name":"Preview Pricing Tier Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/import/preview","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","import","preview"]},"description":"Preview the result of importing supplier pricing tiers from a CSV/Excel file without committing.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `supplier_pricing_tiers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/import/preview","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"headers\": [\n      \"name\",\n      \"currency_code\"\n    ],\n    \"rows\": [\n      {\n        \"name\": \"New Tier\",\n        \"currency_code\": \"AUD\",\n        \"status\": \"create\"\n      },\n      {\n        \"name\": \"Retail USD\",\n        \"currency_code\": \"USD\",\n        \"status\": \"update\"\n      }\n    ],\n    \"total\": 2,\n    \"errors\": []\n  }\n}"}]},{"name":"Import Pricing Tiers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/import","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","import"]},"description":"Imports supplier pricing tiers from a CSV or Excel file.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `supplier_pricing_tiers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-pricing-tiers/import","host":["{{baseUrl}}"],"path":["api","supplier-pricing-tiers","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import completed: 3 created, 1 updated, 0 errors\"\n}"}]},{"name":"List Supplier Inventories","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories?page=1&sort=-updated_at&filter[supplier_id]=1","host":["{{baseUrl}}"],"path":["api","supplier-inventories"],"query":[{"key":"page","value":"1","description":"Page number (Spatie QueryBuilder)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort field. Allowed: id, quantity, eta, in_stock, discontinued, created_at, updated_at. Prefix with - for descending (default: -updated_at)","disabled":true},{"key":"filter[supplier_id]","value":"1","description":"Filter by exact supplier ID","disabled":true}]},"description":"Returns a paginated list of supplier inventory records using Spatie QueryBuilder.\n\nAuthentication: Requires Bearer token.\n\nFilters (Spatie QueryBuilder):\n- filter[id]: Exact match on ID\n- filter[supplier_id]: Exact match on supplier ID\n- filter[warehouse_id]: Exact match on warehouse ID\n- filter[product_id]: Exact match on product ID\n- filter[sku]: Partial match on product SKU\n- filter[search]: Advanced search on product SKU\n\nSort fields: id, quantity, eta, in_stock, discontinued, created_at, updated_at (default: -updated_at)\n\nPagination: page + per_page (default 10)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories?page=1&sort=-updated_at&filter[supplier_id]=1","host":["{{baseUrl}}"],"path":["api","supplier-inventories"],"query":[{"key":"page","value":"1","description":"Page number (Spatie QueryBuilder)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort field. Allowed: id, quantity, eta, in_stock, discontinued, created_at, updated_at. Prefix with - for descending (default: -updated_at)","disabled":true},{"key":"filter[supplier_id]","value":"1","description":"Filter by exact supplier ID","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"quantity\": 500,\n      \"in_stock\": null,\n      \"discontinued\": false,\n      \"eta\": null,\n      \"source\": \"user\",\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"supplier_sku\": \"ACME-W001\",\n      \"supplier_id\": 5,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T14:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Our Inventory for Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/our-inventory","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","our-inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a paginated list of OUR internal warehouse inventory rows for products supplied by the given supplier.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns one row per (product, our_warehouse). Excludes the per-product totals row (warehouse_id = 0) and supplier-type warehouses.\n\nAuthentication: Requires Bearer token.\n\nFilters (Spatie QueryBuilder):\n- filter[warehouse_id]: Exact match on warehouse ID\n- filter[product_id]: Exact match on product ID\n- filter[sku]: Partial match on product SKU\n- filter[search]: Partial match on product SKU or name\n- filter[stock_status]: Computed status filter (in_stock, low_stock, out_of_stock, incoming, allocated)\n\nSort fields: inventory_total, inventory_available, inventory_allocated, inventory_on_hold, inventory_in_transit, inventory_stock_value, updated_at, sku, product_name, warehouse_name (default: -inventory_total)\n\nPagination: page + per_page (default 10)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/our-inventory","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","our-inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"internal\"\n      },\n      \"inventory_total\": 500,\n      \"inventory_available\": 420,\n      \"inventory_allocated\": 50,\n      \"inventory_on_hold\": 10,\n      \"inventory_in_transit\": 20,\n      \"inventory_stock_value\": 1250.5,\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Our Inventory Stats for Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/our-inventory/stats","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","our-inventory","stats"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns aggregate stats for OUR internal warehouse inventory of products supplied by the given supplier.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nHonors the same filters as the index endpoint so stats reflect the active filter set.\n\nAuthentication: Requires Bearer token.\n\nResponse fields:\n- total_skus: Distinct product count\n- warehouses_count: Distinct internal warehouse count\n- total_available: Sum of available units across all rows\n- total_allocated: Sum of allocated units\n- total_on_hold: Sum of on-hold units\n- total_in_transit: Sum of in-transit units\n- total_units: Sum of total units (available + allocated + on_hold + in_transit)\n- total_stock_value: Sum of stock value (in account currency)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/our-inventory/stats","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","our-inventory","stats"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_skus\": 47,\n    \"warehouses_count\": 3,\n    \"total_available\": 12450,\n    \"total_allocated\": 320,\n    \"total_on_hold\": 85,\n    \"total_in_transit\": 540,\n    \"total_units\": 13395,\n    \"total_stock_value\": 24613.27\n  }\n}"}]},{"name":"List Supplier Inventories (Lookup)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/list?per_page=20&filter[supplier_id]=5","host":["{{baseUrl}}"],"path":["api","supplier-inventories","list"],"query":[{"key":"per_page","value":"20","description":"Records per page","disabled":true},{"key":"filter[supplier_id]","value":"5","description":"Filter by supplier ID","disabled":true}]},"description":"Returns a paginated list of supplier inventories via Spatie QueryBuilder. Same filter/sort support as the list view index.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/list?per_page=20&filter[supplier_id]=5","host":["{{baseUrl}}"],"path":["api","supplier-inventories","list"],"query":[{"key":"per_page","value":"20","description":"Records per page","disabled":true},{"key":"filter[supplier_id]","value":"5","description":"Filter by supplier ID","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"quantity\": 500,\n      \"in_stock\": null,\n      \"discontinued\": false,\n      \"eta\": null,\n      \"source\": \"api\",\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"supplier_id\": 5,\n      \"updated_at\": \"2024-06-01T14:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 20,\n  \"total\": 35\n}"}]},{"name":"Get Supplier Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single supplier inventory record with related product and warehouse data.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1,\n    \"quantity\": 500,\n    \"in_stock\": null,\n    \"discontinued\": false,\n    \"eta\": \"2024-09-01T00:00:00.000000Z\",\n    \"source\": \"user\",\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"product_name\": \"Blue Widget\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"supplier_sku\": \"ACME-W001\",\n    \"supplier_id\": 5,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T14:30:00.000000Z\"\n  }\n}"}]},{"name":"Update Supplier Inventory","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a supplier inventory record. Sets source to 'user'. Provide either quantity OR in_stock (not both). On update every field is optional, so you can send a partial update — for example only `discontinued` or `eta` — without re-sending quantity/in_stock; the existing stock value is preserved.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- supplier_id (required on create, optional on update): ID of the supplier\n- product_id (required on create, optional on update): ID of the product\n- warehouse_id (required on create, optional on update): ID of the warehouse\n- quantity (required on create if in_stock not provided; optional on update): Stock quantity (must be non-negative number). Sending quantity clears in_stock.\n- in_stock (required on create if quantity not provided; optional on update): Boolean stock flag — true means in stock with unspecified quantity. Sending in_stock clears quantity.\n- discontinued (optional): Boolean, marks item as discontinued\n- eta (optional): Expected availability date (ISO date)\n- source (required on create, optional on update): One of: user, api","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 5,\n  \"product_id\": 42,\n  \"warehouse_id\": 2,\n  \"quantity\": 750,\n  \"discontinued\": false,\n  \"eta\": \"2024-09-15\",\n  \"source\": \"user\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"supplier inventory updated successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"quantity\": 750,\n    \"in_stock\": null,\n    \"discontinued\": false,\n    \"eta\": \"2024-09-15T00:00:00.000000Z\",\n    \"source\": \"user\",\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"product_name\": \"Blue Widget\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"supplier_id\": 5,\n    \"updated_at\": \"2024-06-15T14:00:00.000000Z\"\n  }\n}"}]},{"name":"Export Supplier Inventories","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/export","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","export"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Exports all supplier inventory records for a specific supplier as a CSV or Excel file download. The supplier_id filter is automatically applied.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- supplier: Supplier ID\n\nResponse: File download"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/export","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","export"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"\"SKU\",\"Product Name\",\"Warehouse\",\"Quantity\",\"In Stock\",\"Discontinued\",\"ETA\",\"Source\"\n\"WIDGET-001\",\"Blue Widget\",\"Main Warehouse\",\"500\",\"\",\"No\",\"\",\"user\""}]},{"name":"Archive Supplier Inventory","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/archive","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a single supplier inventory record. Idempotent — returns a warning if already archived.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/archive","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"supplier inventory 1 archived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"quantity\": 500\n  }\n}"}]},{"name":"Unarchive Supplier Inventory","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a single supplier inventory record.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"supplier inventory 1 unarchived successfully\",\n  \"data\": {\n    \"id\": 1\n  }\n}"}]},{"name":"Bulk Archive Supplier Inventories","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/archive","host":["{{baseUrl}}"],"path":["api","supplier-inventories","archive"]},"description":"Bulk archives multiple supplier inventory records by ID array or current list view filters.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-inventories/archive","host":["{{baseUrl}}"],"path":["api","supplier-inventories","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Supplier inventories archived successfully\"\n}"}]},{"name":"Bulk Unarchive Supplier Inventories","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/unarchive","host":["{{baseUrl}}"],"path":["api","supplier-inventories","unarchive"]},"description":"Bulk unarchives multiple supplier inventory records by ID array or current list view filters.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/supplier-inventories/unarchive","host":["{{baseUrl}}"],"path":["api","supplier-inventories","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Supplier inventories unarchived successfully\"\n}"}]},{"name":"Check Supplier Inventories Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/archivable","host":["{{baseUrl}}"],"path":["api","supplier-inventories","archivable"]},"description":"Checks whether each provided supplier inventory ID can be safely archived.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-inventories/archivable","host":["{{baseUrl}}"],"path":["api","supplier-inventories","archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"archivable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"archivable\": false,\n      \"reason\": \"Already archived\"\n    }\n  ]\n}"}]},{"name":"Check Supplier Inventories Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/deletable","host":["{{baseUrl}}"],"path":["api","supplier-inventories","deletable"]},"description":"Checks whether each provided supplier inventory ID can be safely deleted.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-inventories/deletable","host":["{{baseUrl}}"],"path":["api","supplier-inventories","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"deletable\": false,\n      \"reason\": \"Linked to active purchase orders\"\n    }\n  ]\n}"}]},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import/template","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import","template"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Downloads an XLSX import template for a specific supplier, pre-populated with headers, sample data, field guide, and reference data (products, warehouses) for the tenant's account.\n\n**Required scope: `suppliers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- supplier: Supplier ID\n\nResponse: XLSX file download"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import/template","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import","template"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[Binary XLSX file content]"}]},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import/validate","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import","validate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Validates import data rows for a supplier without creating any records. Safe to call repeatedly for UI previewing. Resolves SKU and warehouse names against the tenant's catalogue and returns a per-row preview alongside an aggregate summary.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThere is no hard row cap on this endpoint — SKU and warehouse lookups are chunked internally so large files can be submitted in one request. Per-request execution time and memory limits are raised for the duration of the call.\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- supplier: Supplier ID\n\nBody fields:\n- rows (required): Array of raw import rows (1+).\n  - rows.*.sku (optional): Product SKU. Resolved case-insensitively.\n  - rows.*.quantity (optional): Stock quantity (numeric string)\n  - rows.*.eta (optional): ETA date string\n  - rows.*.in_stock (optional): Stock flag (1/0/true/false/yes/y)\n  - rows.*.discontinued (optional): Discontinued flag (1/0/true/false/yes/y)\n  - rows.*.warehouse (optional): Warehouse name. Falls back to the supplier's default warehouse when omitted.\n\nErrors:\n- 422 when standard validation fails (e.g. empty rows array).\n- 422 when the manager raises an exception during lookup (translated from a 500 so the client gets an actionable message).","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"sku\": \"WIDGET-001\",\n      \"quantity\": \"500\",\n      \"eta\": \"2024-09-01\",\n      \"in_stock\": null,\n      \"discontinued\": \"0\",\n      \"warehouse\": \"Main Warehouse\"\n    },\n    {\n      \"sku\": \"GADGET-XL\",\n      \"quantity\": null,\n      \"eta\": null,\n      \"in_stock\": \"1\",\n      \"discontinued\": \"0\",\n      \"warehouse\": \"East Warehouse\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import/validate","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import","validate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"row_index\": 0,\n      \"sku\": \"WIDGET-001\",\n      \"product_id\": 42,\n      \"product_name\": \"Widget 001\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"quantity\": 500,\n      \"eta\": \"2024-09-01\",\n      \"in_stock\": false,\n      \"discontinued\": false,\n      \"errors\": []\n    },\n    {\n      \"row_index\": 1,\n      \"sku\": \"UNKNOWN-SKU\",\n      \"product_id\": null,\n      \"product_name\": null,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"quantity\": null,\n      \"eta\": null,\n      \"in_stock\": false,\n      \"discontinued\": false,\n      \"errors\": [\n        \"SKU 'UNKNOWN-SKU' not found.\"\n      ]\n    }\n  ],\n  \"summary\": {\n    \"total_items\": 2,\n    \"total_errors\": 1,\n    \"total_valid\": 1\n  }\n}"}]},{"name":"Execute Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Queues a supplier inventory import — creates or updates inventory records for a specific supplier in the background.\n\n**Required scope: `suppliers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis endpoint is asynchronous. The HTTP response returns immediately (202 Accepted) with a `tracked_job_log_id` that the client polls via the tracked job log endpoints for progress and completion status. There is no hard row cap on the payload — the queued job processes items in chunks of 500 in its own transaction per chunk, so payloads of any size complete cleanly without holding a long-running transaction open.\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- supplier: Supplier ID\n\nBody fields:\n- items (required): Array of inventory items (1+). Only the top-level `items` array is validated at the HTTP layer; each row is validated inside the queued job and any per-row problems are surfaced as failures in the tracked job results rather than as a 422. (Per-row `exists` validation was intentionally removed from the request layer to avoid an N+1 that timed out large payloads.)\n  - items.*.product_id (required): Product ID\n  - items.*.warehouse_id (optional): Warehouse ID\n  - items.*.quantity (optional): Stock quantity, integer >= 0\n  - items.*.eta (optional): Expected availability date\n  - items.*.in_stock (optional): Boolean stock flag\n  - items.*.discontinued (optional): Boolean discontinued flag\n\nErrors:\n- 422 only when the top-level `items` array is missing or empty.\n- 404 when the supplier does not exist.\n- Invalid rows (e.g. unknown product_id) do NOT return 422 — the import is queued and those rows are reported as failures in the tracked job results.\n\nNote: Use the validate endpoint first to preview and catch row-level errors before importing.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"product_id\": 42,\n      \"warehouse_id\": 2,\n      \"quantity\": 500,\n      \"eta\": \"2024-09-01\",\n      \"in_stock\": null,\n      \"discontinued\": false\n    },\n    {\n      \"product_id\": 78,\n      \"warehouse_id\": 3,\n      \"quantity\": null,\n      \"eta\": null,\n      \"in_stock\": true,\n      \"discontinued\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/supplier-inventories/{id}/import","host":["{{baseUrl}}"],"path":["api","supplier-inventories",":id","import"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Import queued — track progress in the job tray.\"\n}"}]}]},{"name":"Returns & RMAs","item":[{"name":"List Return Reasons","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/return-reasons?archived=0&search=&sort=name&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","v2","return-reasons"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search return reasons by name","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Records per page","disabled":true}]},"description":"List all return reasons using the standard list interface. Supports filtering, sorting, search and pagination.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nSort fields: id, name, created_at, updated_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/return-reasons?archived=0&search=&sort=name&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","v2","return-reasons"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search return reasons by name","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Records per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Defective Item\",\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wrong Item Shipped\",\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2\n}"}]},{"name":"List RMAs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/rmas?page=1&per_page=10&sort=-created_at&filter[search]=&filter[status]=&filter[customer_id]=&filter[sales_order_id]=&filter[rma_number][is]=&filter[rma_number][contains]=&filter[rma_date][from]=&filter[rma_date][to]=&filter[created_at][from]=&filter[created_at][to]=","host":["{{baseUrl}}"],"path":["api","rmas"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Allowed: rma_number, status, rma_date, created_at","disabled":true},{"key":"filter[search]","value":"","description":"Search by RMA number or sales order number","disabled":true},{"key":"filter[status]","value":"","description":"Filter by status: draft, approved, in_transit, received, closed, canceled","disabled":true},{"key":"filter[customer_id]","value":"","description":"Filter by customer ID (searches via sales order)","disabled":true},{"key":"filter[sales_order_id]","value":"","description":"Filter by exact sales order ID","disabled":true},{"key":"filter[rma_number][is]","value":"","description":"Filter by exact RMA number","disabled":true},{"key":"filter[rma_number][contains]","value":"","description":"Filter RMA number containing value","disabled":true},{"key":"filter[rma_date][from]","value":"","description":"Filter RMA date from (Y-m-d)","disabled":true},{"key":"filter[rma_date][to]","value":"","description":"Filter RMA date to (Y-m-d)","disabled":true},{"key":"filter[created_at][from]","value":"","description":"Filter created_at from (Y-m-d)","disabled":true},{"key":"filter[created_at][to]","value":"","description":"Filter created_at to (Y-m-d)","disabled":true}]},"description":"List all RMAs with pagination, filtering, and sorting via Spatie QueryBuilder.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilter system: Uses Spatie QueryBuilder filter syntax.\n- filter[search]: Searches rma_number and related sales_order_number\n- filter[status]: draft | approved | in_transit | received | closed | canceled\n- filter[customer_id]: Filters via associated sales order\n- filter[sales_order_id]: Exact match\n- Advanced text filters: filter[rma_number][is], [is_not], [contains], [does_not_contain], [starts_with], [ends_with], [is_empty], [is_not_empty]\n- Advanced date filters: filter[rma_date][from], [to], filter[created_at][from], [to]\n\nAllowed sorts: rma_number, status, rma_date, created_at. Default sort: -created_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/rmas?page=1&per_page=10&sort=-created_at&filter[search]=&filter[status]=&filter[customer_id]=&filter[sales_order_id]=&filter[rma_number][is]=&filter[rma_number][contains]=&filter[rma_date][from]=&filter[rma_date][to]=&filter[created_at][from]=&filter[created_at][to]=","host":["{{baseUrl}}"],"path":["api","rmas"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Allowed: rma_number, status, rma_date, created_at","disabled":true},{"key":"filter[search]","value":"","description":"Search by RMA number or sales order number","disabled":true},{"key":"filter[status]","value":"","description":"Filter by status: draft, approved, in_transit, received, closed, canceled","disabled":true},{"key":"filter[customer_id]","value":"","description":"Filter by customer ID (searches via sales order)","disabled":true},{"key":"filter[sales_order_id]","value":"","description":"Filter by exact sales order ID","disabled":true},{"key":"filter[rma_number][is]","value":"","description":"Filter by exact RMA number","disabled":true},{"key":"filter[rma_number][contains]","value":"","description":"Filter RMA number containing value","disabled":true},{"key":"filter[rma_date][from]","value":"","description":"Filter RMA date from (Y-m-d)","disabled":true},{"key":"filter[rma_date][to]","value":"","description":"Filter RMA date to (Y-m-d)","disabled":true},{"key":"filter[created_at][from]","value":"","description":"Filter created_at from (Y-m-d)","disabled":true},{"key":"filter[created_at][to]","value":"","description":"Filter created_at to (Y-m-d)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"rma_number\": \"RMA-0001\",\n      \"status\": \"approved\",\n      \"sales_order_id\": 10,\n      \"sales_order\": {\n        \"id\": 10,\n        \"sales_order_number\": \"SO-0010\",\n        \"order_date\": \"2024-01-10\"\n      },\n      \"is_orphaned\": false,\n      \"orphan_info\": null,\n      \"customer_id\": 5,\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"address\": null\n      },\n      \"notes\": \"Customer returning defective unit\",\n      \"tracking_number\": null,\n      \"carrier\": null,\n      \"shipped_at\": null,\n      \"expected_at\": null,\n      \"approved_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"approved_by_user_id\": 1,\n      \"rma_date\": \"2024-01-14\",\n      \"is_amazon_fba_return\": false,\n      \"rma_lines\": [\n        {\n          \"id\": 1,\n          \"product_id\": 20,\n          \"product\": {\n            \"id\": 20,\n            \"sku\": \"WIDGET-A\",\n            \"name\": \"Widget A\"\n          },\n          \"expected_quantity\": 2,\n          \"received_quantity\": 0,\n          \"remaining_quantity\": 2,\n          \"return_reason_id\": 1,\n          \"notes\": null\n        }\n      ],\n      \"created_at\": \"2024-01-14T08:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 27\n}"}]},{"name":"Create RMA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas","host":["{{baseUrl}}"],"path":["api","rmas"]},"description":"Create a new RMA for a fulfilled sales order.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation rules:\n- sales_order_id: required, must be an order that has been fulfilled (unless sales_credit_id is provided)\n- warehouse_id: required\n- status: optional, allowed values: draft, approved\n- notes: optional, max 1000 chars\n- sales_credit_id: optional, if provided skips fulfillment and quantity validation\n- rma_lines: required array with at least 1 line\n  - product_id: required\n  - expected_quantity: required, min 1, cannot exceed fulfilled minus already RMA'd quantity\n  - sales_order_line_id: optional, must belong to the specified sales order and match the product\n  - return_reason_id: optional\n  - notes: optional, max 500 chars\n\n**Requires permission:** `returns.create`","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 10,\n  \"warehouse_id\": 2,\n  \"status\": \"draft\",\n  \"notes\": \"Customer returning 2 units of Widget A due to defect\",\n  \"sales_credit_id\": null,\n  \"rma_lines\": [\n    {\n      \"product_id\": 20,\n      \"expected_quantity\": 2,\n      \"sales_order_line_id\": 55,\n      \"return_reason_id\": 1,\n      \"notes\": \"Unit arrived damaged\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas","host":["{{baseUrl}}"],"path":["api","rmas"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"rma_number\": \"RMA-0015\",\n    \"status\": \"draft\",\n    \"sales_order_id\": 10,\n    \"sales_order\": {\n      \"id\": 10,\n      \"sales_order_number\": \"SO-0010\",\n      \"order_date\": \"2024-01-10\"\n    },\n    \"is_orphaned\": false,\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"address\": null\n    },\n    \"notes\": \"Customer returning 2 units of Widget A due to defect\",\n    \"rma_lines\": [\n      {\n        \"id\": 20,\n        \"product_id\": 20,\n        \"product\": {\n          \"id\": 20,\n          \"sku\": \"WIDGET-A\",\n          \"name\": \"Widget A\"\n        },\n        \"expected_quantity\": 2,\n        \"received_quantity\": 0,\n        \"remaining_quantity\": 2,\n        \"return_reason_id\": 1,\n        \"notes\": \"Unit arrived damaged\"\n      }\n    ],\n    \"created_at\": \"2024-01-20T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-20T10:00:00.000000Z\"\n  },\n  \"message\": \"RMA created successfully\"\n}"}]},{"name":"Get RMA","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Get a single RMA with full detail including lines, return receipts, sales credits, and approved-by user.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nLoads: salesOrder.customer, warehouse.address, approvedBy, rmaLines.product, rmaLines.returnReason, rmaLines.salesOrderLine, rmaLines.amazonFbaCustomerReturns, returnReceipts.receivedBy, returnReceipts.returnReceiptLines.product, returnReceipts.returnReceiptLines.returnReason, salesCredits."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"approved\",\n    \"sales_order_id\": 10,\n    \"sales_order\": {\n      \"id\": 10,\n      \"sales_order_number\": \"SO-0010\",\n      \"order_date\": \"2024-01-10\"\n    },\n    \"is_orphaned\": false,\n    \"orphan_info\": null,\n    \"customer_id\": 5,\n    \"customer\": {\n      \"id\": 5,\n      \"name\": \"John Doe\",\n      \"email\": \"john@example.com\",\n      \"company\": \"Acme Corp\",\n      \"phone\": \"+1-555-0100\",\n      \"address1\": \"123 Main St\",\n      \"city\": \"Beverly Hills\",\n      \"zip\": \"90210\",\n      \"country\": \"US\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"address\": {\n        \"address1\": \"500 Industrial Way\",\n        \"city\": \"Glendale\",\n        \"zip\": \"91201\",\n        \"country\": \"United States\",\n        \"country_code\": \"US\"\n      }\n    },\n    \"notes\": \"Customer returning defective unit\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipped_at\": \"2024-01-16\",\n    \"expected_at\": \"2024-01-20\",\n    \"approved_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"approved_by_user_id\": 1,\n    \"approved_by\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    },\n    \"rma_date\": \"2024-01-14\",\n    \"is_amazon_fba_return\": false,\n    \"rma_lines\": [\n      {\n        \"id\": 1,\n        \"rma_id\": 1,\n        \"product_id\": 20,\n        \"product\": {\n          \"id\": 20,\n          \"sku\": \"WIDGET-A\",\n          \"name\": \"Widget A\"\n        },\n        \"sales_order_line_id\": 55,\n        \"sales_order_line\": {\n          \"id\": 55,\n          \"quantity\": 5,\n          \"amount\": 49.99\n        },\n        \"return_reason_id\": 1,\n        \"return_reason\": {\n          \"id\": 1,\n          \"name\": \"Defective\"\n        },\n        \"expected_quantity\": 2,\n        \"received_quantity\": 0,\n        \"remaining_quantity\": 2,\n        \"notes\": \"Unit arrived damaged\",\n        \"amazon_fba_return\": null\n      }\n    ],\n    \"return_receipts\": [\n      {\n        \"id\": 5,\n        \"rma_id\": 1,\n        \"warehouse_id\": 2,\n        \"warehouse\": {\n          \"id\": 2,\n          \"name\": \"Main Warehouse\"\n        },\n        \"received_at\": \"2024-01-21T09:00:00.000000Z\",\n        \"received_by_user_id\": 1,\n        \"received_by\": {\n          \"id\": 1,\n          \"name\": \"Admin User\"\n        },\n        \"notes\": \"Received in good condition\",\n        \"return_receipt_lines\": [\n          {\n            \"id\": 8,\n            \"product_id\": 20,\n            \"product\": {\n              \"id\": 20,\n              \"sku\": \"WIDGET-A\",\n              \"name\": \"Widget A\"\n            },\n            \"quantity\": 2,\n            \"action\": \"added_to_stock\",\n            \"return_reason\": {\n              \"id\": 1,\n              \"name\": \"Defective\"\n            }\n          }\n        ],\n        \"created_at\": \"2024-01-21T09:00:00.000000Z\"\n      }\n    ],\n    \"sales_credits\": [],\n    \"created_at\": \"2024-01-14T08:00:00.000000Z\",\n    \"updated_at\": \"2024-01-16T09:00:00.000000Z\"\n  }\n}"}]},{"name":"Update RMA","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Update an RMA's warehouse and/or notes.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly warehouse_id (optional) and notes (optional, max 1000 chars) can be updated via this endpoint. Use the /approve, /shipping, etc. endpoints for status transitions.\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"notes\": \"Updated return notes — item is scratched, not broken\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"draft\",\n    \"warehouse_id\": 3,\n    \"notes\": \"Updated return notes — item is scratched, not broken\",\n    \"updated_at\": \"2024-01-20T11:00:00.000000Z\"\n  },\n  \"message\": \"RMA updated successfully\"\n}"}]},{"name":"Delete RMA","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Delete an RMA. Only draft RMAs can typically be deleted. Returns 422 if the RMA cannot be deleted.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/rmas/{rma}","host":["{{baseUrl}}"],"path":["api","rmas",":rma"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"RMA deleted successfully\"\n}"}]},{"name":"Approve RMA","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/approve","host":["{{baseUrl}}"],"path":["api","rmas",":rma","approve"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Approve a draft RMA. Records the approving user and approval timestamp.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: draft → approved\n\n**Requires permission:** `returns.approve`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/approve","host":["{{baseUrl}}"],"path":["api","rmas",":rma","approve"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"approved\",\n    \"approved_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"approved_by\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    }\n  },\n  \"message\": \"RMA approved successfully.\"\n}"}]},{"name":"Cancel RMA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/cancel","host":["{{baseUrl}}"],"path":["api","rmas",":rma","cancel"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Cancel an RMA and keep it on record (the RMA is not deleted). Only RMAs in a cancellable status (draft, approved, in_transit) with zero return receipts can be canceled — `can_be_canceled` on the resource reflects this.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. **Requires permission:** `returns.cancel`.\n\nStatus transition: draft / approved / in_transit → canceled\n\n**Request body (optional):**\n- `cancellation_reason` (string, nullable, max 500) — audit note recorded alongside `canceled_at` and `canceled_by_user_id`.\n\nThe response resource exposes the cancellation audit fields (`canceled_at`, `canceled_by_user_id`, `canceled_by`, `cancellation_reason`) and the capability flags (`can_be_canceled`, `can_be_deleted`).","body":{"mode":"raw","raw":"{\n  \"cancellation_reason\": \"Customer decided to keep the item\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/cancel","host":["{{baseUrl}}"],"path":["api","rmas",":rma","cancel"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"canceled\",\n    \"canceled_at\": \"2026-06-29T14:32:00.000000Z\",\n    \"canceled_by_user_id\": 7,\n    \"canceled_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Operator\"\n    },\n    \"cancellation_reason\": \"Customer decided to keep the item\",\n    \"can_be_canceled\": false,\n    \"can_be_deleted\": true\n  },\n  \"message\": \"RMA canceled successfully.\"\n}"}]},{"name":"Close RMA","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/close","host":["{{baseUrl}}"],"path":["api","rmas",":rma","close"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Close an approved or received RMA.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: approved/in_transit/received → closed\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/close","host":["{{baseUrl}}"],"path":["api","rmas",":rma","close"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"closed\"\n  },\n  \"message\": \"RMA closed successfully.\"\n}"}]},{"name":"Reopen RMA","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/reopen","host":["{{baseUrl}}"],"path":["api","rmas",":rma","reopen"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Reopen a closed RMA.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: closed → approved\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/reopen","host":["{{baseUrl}}"],"path":["api","rmas",":rma","reopen"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"approved\"\n  },\n  \"message\": \"RMA reopened successfully.\"\n}"}]},{"name":"Uncancel RMA","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/uncancel","host":["{{baseUrl}}"],"path":["api","rmas",":rma","uncancel"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Restore a canceled RMA back to draft status.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: canceled → draft\n\n**Requires permission:** `returns.cancel`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/uncancel","host":["{{baseUrl}}"],"path":["api","rmas",":rma","uncancel"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"draft\"\n  },\n  \"message\": \"RMA restored successfully.\"\n}"}]},{"name":"Revert to Draft","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","rmas",":rma","revert-to-draft"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Revert an approved RMA back to draft status. Clears approved_at and approved_by_user_id.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: approved → draft\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","rmas",":rma","revert-to-draft"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"draft\",\n    \"approved_at\": null,\n    \"approved_by_user_id\": null,\n    \"approved_by\": null\n  },\n  \"message\": \"RMA reverted to draft.\"\n}"}]},{"name":"Mark as Shipped","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/ship","host":["{{baseUrl}}"],"path":["api","rmas",":rma","ship"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Mark an RMA as shipped by the customer.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus transition: approved → in_transit\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/ship","host":["{{baseUrl}}"],"path":["api","rmas",":rma","ship"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"in_transit\"\n  },\n  \"message\": \"RMA marked as shipped.\"\n}"}]},{"name":"Update Shipping Details","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/shipping","host":["{{baseUrl}}"],"path":["api","rmas",":rma","shipping"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Update shipping details for an RMA. Automatically transitions status based on whether shipping info is added or removed:\n- Adding shipping info: APPROVED → IN_TRANSIT\n- Clearing all shipping info (when no receipts exist): IN_TRANSIT → APPROVED\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields are nullable — pass null to clear a field.\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"carrier\": \"UPS\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"shipped_at\": \"2024-01-16\",\n  \"expected_at\": \"2024-01-20\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/shipping","host":["{{baseUrl}}"],"path":["api","rmas",":rma","shipping"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"in_transit\",\n    \"carrier\": \"UPS\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"shipped_at\": \"2024-01-16\",\n    \"expected_at\": \"2024-01-20\"\n  },\n  \"message\": \"Shipping details updated.\"\n}"}]},{"name":"Clear Shipping Details","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/shipping","host":["{{baseUrl}}"],"path":["api","rmas",":rma","shipping"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Clear all shipping information from an RMA. If no receipts exist and the RMA is in IN_TRANSIT, it transitions back to APPROVED.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/shipping","host":["{{baseUrl}}"],"path":["api","rmas",":rma","shipping"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"status\": \"approved\",\n    \"carrier\": null,\n    \"tracking_number\": null,\n    \"shipped_at\": null,\n    \"expected_at\": null\n  },\n  \"message\": \"Shipping information cleared.\"\n}"}]},{"name":"Add Line to RMA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Add a new line to an existing RMA. Cannot add lines to terminal (closed/canceled) RMAs.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation: Same quantity rules as creating an RMA — cannot exceed fulfilled minus already RMA'd.\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"product_id\": 25,\n  \"expected_quantity\": 1,\n  \"sales_order_line_id\": 60,\n  \"return_reason_id\": 2,\n  \"notes\": \"Additional defective unit\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"rma_lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 20,\n        \"expected_quantity\": 2\n      },\n      {\n        \"id\": 21,\n        \"product_id\": 25,\n        \"expected_quantity\": 1\n      }\n    ]\n  },\n  \"message\": \"RMA Line created successfully\"\n}"}]},{"name":"Update RMA Line","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines/{rmaLine}","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines",":rmaLine"],"variable":[{"key":"rma","value":"1","description":"RMA ID"},{"key":"rmaLine","value":"1","description":"RMA Line ID"}]},"description":"Update an RMA line. Cannot update lines on closed or canceled RMAs.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields are optional (sometimes rule):\n- expected_quantity: min 1, cannot exceed fulfilled minus existing RMAs (excluding current line)\n- return_reason_id: nullable\n- notes: nullable, max 500 chars\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"expected_quantity\": 1,\n  \"return_reason_id\": 3,\n  \"notes\": \"Customer changed mind — only 1 unit is defective\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines/{rmaLine}","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines",":rmaLine"],"variable":[{"key":"rma","value":"1","description":"RMA ID"},{"key":"rmaLine","value":"1","description":"RMA Line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"rma_lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 20,\n        \"expected_quantity\": 1,\n        \"return_reason_id\": 3,\n        \"notes\": \"Customer changed mind — only 1 unit is defective\"\n      }\n    ]\n  },\n  \"message\": \"RMA Line updated successfully\"\n}"}]},{"name":"Remove Line from RMA","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines/{rmaLine}","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines",":rmaLine"],"variable":[{"key":"rma","value":"1","description":"RMA ID"},{"key":"rmaLine","value":"1","description":"RMA Line ID"}]},"description":"Remove a line from an RMA. Returns 422 if the RMA is in a terminal state or if the line doesn't belong to the RMA.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/lines/{rmaLine}","host":["{{baseUrl}}"],"path":["api","rmas",":rma","lines",":rmaLine"],"variable":[{"key":"rma","value":"1","description":"RMA ID"},{"key":"rmaLine","value":"1","description":"RMA Line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_number\": \"RMA-0001\",\n    \"rma_lines\": []\n  },\n  \"message\": \"RMA Line deleted successfully\"\n}"}]},{"name":"Create Return Receipt from RMA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/receipts","host":["{{baseUrl}}"],"path":["api","rmas",":rma","receipts"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]},"description":"Record a return receipt against an RMA (items physically received at the warehouse).\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAction values: added_to_stock, discarded, new_blemished_sku\n- For new_blemished_sku: provide blemished_configurations array with sku, condition, and reference fields\n- product_id: the product being received back (can differ from original if substituted)\n- original_product_id: the original product (if product_id differs)\n\nLot / batch capture (optional per line - only meaningful for added_to_stock on lot-tracked products):\n- lots[]: { batch_number, manufacture_date, expiry_date, quantity, lot_notes }. Each lot becomes its own FIFO layer; the lot quantities must sum to the line quantity.\n- Batch number + expiry date are REQUIRED on each lot only when the return is traceable to its original sale (the RMA is linked to a sales order). For a blind/untraceable RMA (no sales order link), a blank batch is auto-generated (AUTO-...) at persistence and an undated lot is valid - the receiver is never forced to invent a lot id.\n\n**Requires permission:** `returns.receive` rma_line_id is OPTIONAL — omit it (supply product_id) to receive an item NOT on the RMA; it is stored and flagged unexpected_item=true rather than dropped.","body":{"mode":"raw","raw":"{\n  \"received_at\": \"2024-01-21\",\n  \"notes\": \"Received in good condition\",\n  \"lines\": [\n    {\n      \"rma_line_id\": 1,\n      \"quantity\": 5,\n      \"action\": \"added_to_stock\",\n      \"product_id\": 20,\n      \"original_product_id\": null,\n      \"return_reason_id\": 1,\n      \"notes\": \"Units tested and in working order\",\n      \"blemished_configurations\": null,\n      \"lots\": [\n        {\n          \"batch_number\": \"LOT-2026-A\",\n          \"manufacture_date\": \"2026-01-01\",\n          \"expiry_date\": \"2030-01-31\",\n          \"quantity\": 5,\n          \"lot_notes\": \"Original shipped lot\"\n        }\n      ],\n      \"unexpected_item\": false\n    },\n    {\n      \"rma_line_id\": null,\n      \"product_id\": 44,\n      \"quantity\": 1,\n      \"action\": \"added_to_stock\",\n      \"unexpected_item\": true,\n      \"notes\": \"Customer returned a different item than declared\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/receipts","host":["{{baseUrl}}"],"path":["api","rmas",":rma","receipts"],"variable":[{"key":"rma","value":"1","description":"RMA ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"rma_id\": 1,\n    \"rma\": {\n      \"id\": 1,\n      \"rma_number\": \"RMA-0001\",\n      \"status\": \"received\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"received_at\": \"2024-01-21T00:00:00.000000Z\",\n    \"received_by_user_id\": 1,\n    \"received_by\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    },\n    \"notes\": \"Received in good condition\",\n    \"return_receipt_lines\": [\n      {\n        \"id\": 8,\n        \"product_id\": 20,\n        \"product\": {\n          \"id\": 20,\n          \"sku\": \"WIDGET-A\",\n          \"name\": \"Widget A\"\n        },\n        \"quantity\": 2,\n        \"action\": \"return_to_stock\"\n      }\n    ],\n    \"created_at\": \"2024-01-21T09:00:00.000000Z\"\n  },\n  \"message\": \"Return Receipt created successfully\"\n}"}]},{"name":"Bulk Approve RMAs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/approve","host":["{{baseUrl}}"],"path":["api","rmas","bulk","approve"]},"description":"Bulk approve multiple RMAs. Returns success and failed counts.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUse apply_to_all=true with filters to operate on all matching RMAs.\n\n**Requires permission:** `returns.approve`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/approve","host":["{{baseUrl}}"],"path":["api","rmas","bulk","approve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": [\n      1,\n      2,\n      3\n    ],\n    \"failed\": {}\n  },\n  \"message\": \"3 RMA(s) approved successfully.\"\n}"}]},{"name":"Bulk Cancel RMAs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/cancel","host":["{{baseUrl}}"],"path":["api","rmas","bulk","cancel"]},"description":"Bulk cancel multiple RMAs.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.cancel`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4,\n    5\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/cancel","host":["{{baseUrl}}"],"path":["api","rmas","bulk","cancel"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": [\n      4,\n      5\n    ],\n    \"failed\": {}\n  },\n  \"message\": \"2 RMA(s) canceled successfully.\"\n}"}]},{"name":"Bulk Close RMAs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/close","host":["{{baseUrl}}"],"path":["api","rmas","bulk","close"]},"description":"Bulk close multiple RMAs.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6,\n    7\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/close","host":["{{baseUrl}}"],"path":["api","rmas","bulk","close"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": [\n      6,\n      7\n    ],\n    \"failed\": {}\n  },\n  \"message\": \"2 RMA(s) closed successfully.\"\n}"}]},{"name":"Bulk Delete RMAs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/delete","host":["{{baseUrl}}"],"path":["api","rmas","bulk","delete"]},"description":"Bulk delete multiple RMAs.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8,\n    9\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/delete","host":["{{baseUrl}}"],"path":["api","rmas","bulk","delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": [\n      8,\n      9\n    ],\n    \"failed\": {}\n  },\n  \"message\": \"2 RMA(s) deleted successfully.\"\n}"}]},{"name":"Bulk Revert RMAs to Draft","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/revert-to-draft","host":["{{baseUrl}}"],"path":["api","rmas","bulk","revert-to-draft"]},"description":"Bulk revert approved RMAs back to draft status.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/revert-to-draft","host":["{{baseUrl}}"],"path":["api","rmas","bulk","revert-to-draft"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": [\n      10,\n      11\n    ],\n    \"failed\": {}\n  },\n  \"message\": \"2 RMA(s) reverted to draft successfully.\"\n}"}]},{"name":"Bulk Generate RMAs from Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/rmas/bulk/generate-from-orders","host":["{{baseUrl}}"],"path":["api","rmas","bulk","generate-from-orders"]},"description":"Dispatch a tracked background job that creates one RMA per selected (or all-matching) sales order, from each order's fulfilled, not-already-RMA'd lines. Returns a tracked_job_log_id immediately; progress shows via the tracked job log endpoints.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_order_ids (required without apply_to_all): explicit list of sales order IDs\n- apply_to_all (optional bool): when true, resolve target orders from the sales-orders list filters instead of an explicit list\n- filters (optional): the sales-orders list filters to resolve when apply_to_all is true\n- warehouse_id (optional): default warehouse for generated RMAs; per order, the order's fulfillment warehouse is preferred when resolvable\n- status (optional): draft | approved (default draft) — when approved, each generated RMA is approved\n- rma_date (optional date): date for the generated RMAs\n- skip_existing_open (optional bool, default true): skip orders that already have a non-terminal (open) RMA\n\nPer-order outcomes (created / skipped / failed) and the created RMA list are stored on the tracked job log for the details dialog. The completion watcher matches the job name \"Generate RMAs from Orders\".","body":{"mode":"raw","raw":"{\n  \"sales_order_ids\": [\n    42,\n    43,\n    44\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {},\n  \"warehouse_id\": 1,\n  \"status\": \"draft\",\n  \"rma_date\": \"2026-06-09\",\n  \"skip_existing_open\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/rmas/bulk/generate-from-orders","host":["{{baseUrl}}"],"path":["api","rmas","bulk","generate-from-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Generating RMAs from orders — track progress in the job tray.\"\n}"}]},{"name":"Get RMA Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/activity-log","host":["{{baseUrl}}"],"path":["api","rmas",":rma","activity-log"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]},"description":"Get the activity log for an RMA — every recorded change on the RMA itself, its lines, and its return receipts, newest first.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach entry includes the event, the record type it applies to (`Rma`, `RmaLine`, or `ReturnReceipt`), the changed attributes with old values, and the acting user (`causer_name` is null for system-generated changes).\n\nStandard paginated response. Requires the `returns:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/activity-log","host":["{{baseUrl}}"],"path":["api","rmas",":rma","activity-log"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 48213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Rma\",\n      \"subject_id\": 512,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"approved\"\n        },\n        \"old\": {\n          \"status\": \"draft\"\n        },\n        \"source\": \"manual\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-07-01T14:22:05.000000Z\"\n    },\n    {\n      \"id\": 48120,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"ReturnReceipt\",\n      \"subject_id\": 88,\n      \"properties\": {\n        \"attributes\": {\n          \"warehouse_id\": 3\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-07-01T13:10:41.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://acme.sku.io/api/rmas/512/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"https://acme.sku.io/api/rmas/512/activity-log?page=3\",\n  \"links\": [],\n  \"next_page_url\": \"https://acme.sku.io/api/rmas/512/activity-log?page=2\",\n  \"path\": \"https://acme.sku.io/api/rmas/512/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 34\n}"}]},{"name":"List RMA Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/inventory-movements","host":["{{baseUrl}}"],"path":["api","rmas",":rma","inventory-movements"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]},"description":"List the inventory movements created by an RMA's return receipts — the stock re-entering inventory as returned units are received.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach movement carries the product, warehouse, quantity, and unit cost. When the movement is tied to a cost layer, `unit_cost` comes from that layer and `unit_cost_provisional` is false; movements not yet tied to a layer use the product's current unit cost with `unit_cost_provisional: true`.\n\nStandard paginated response (default 15 per page, sorted by movement date descending). Requires the `returns:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/inventory-movements","host":["{{baseUrl}}"],"path":["api","rmas",":rma","inventory-movements"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 77120,\n      \"type\": \"return\",\n      \"inventory_status\": \"active\",\n      \"quantity\": 2,\n      \"reference\": \"RMA-00042: Receipt 88\",\n      \"link_type\": \"App\\\\Models\\\\ReturnReceiptLine\",\n      \"link_id\": 1440,\n      \"parent_link_id\": 88,\n      \"detail_link_id\": null,\n      \"product_id\": 341,\n      \"product_sku\": \"WIDGET-BLK\",\n      \"product_name\": \"Widget - Black\",\n      \"warehouse_id\": 3,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 12.5,\n      \"unit_cost_provisional\": false,\n      \"layer\": {\n        \"name\": \"fifo\",\n        \"fifo_layer_id\": 9021\n      },\n      \"inventory_movement_date\": \"2026-06-28T16:40:12.000000Z\",\n      \"created_at\": \"2026-06-28T16:40:12.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://acme.sku.io/api/rmas/512/inventory-movements?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://acme.sku.io/api/rmas/512/inventory-movements?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://acme.sku.io/api/rmas/512/inventory-movements\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List RMA FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/rmas/{rma}/fifo-layers","host":["{{baseUrl}}"],"path":["api","rmas",":rma","fifo-layers"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]},"description":"List the inventory cost layers created by receiving this RMA's returned stock. Each layer records the received quantity, its unit cost, remaining availability, and lot details (batch number, expiry) when the product is lot-tracked.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`origin` identifies the return receipt line the layer came from; `available_quantity` is `original_quantity - fulfilled_quantity`; `days_to_expiry` is a signed day count (negative when expired, null when no expiry).\n\nStandard paginated response, sorted newest first. Requires the `returns:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/rmas/{rma}/fifo-layers","host":["{{baseUrl}}"],"path":["api","rmas",":rma","fifo-layers"],"variable":[{"key":"rma","value":"512","description":"RMA ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9021,\n      \"product_id\": 341,\n      \"fifo_layer_date\": \"2026-06-28T16:40:12.000000Z\",\n      \"sku\": \"WIDGET-BLK\",\n      \"product_name\": \"Widget - Black\",\n      \"product_barcode\": 812345678901,\n      \"stock_uom_code\": \"EA\",\n      \"batch_number\": null,\n      \"manufacture_date\": null,\n      \"expiry_date\": null,\n      \"days_to_expiry\": null,\n      \"lot_notes\": null,\n      \"original_quantity\": 2,\n      \"fulfilled_quantity\": 0,\n      \"avg_cost\": \"12.5000\",\n      \"total_cost\": \"25.0000\",\n      \"cost_breakdown\": null,\n      \"origin\": {\n        \"link_type\": \"App\\\\Models\\\\ReturnReceiptLine\",\n        \"link_id\": 1440,\n        \"name\": \"return_receipt\",\n        \"parent_link_id\": 88,\n        \"detail_link_id\": null,\n        \"reference\": \"RMA-00042: Receipt 88\",\n        \"parent_reference\": \"RMA-00042: Receipt 88\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_fba\": false,\n      \"condition\": \"sellable\",\n      \"integration_unique_id\": null,\n      \"allocated_quantity\": 0,\n      \"available_quantity\": 2,\n      \"archived_at\": null,\n      \"created_at\": \"2026-06-28T16:40:12.000000Z\",\n      \"updated_at\": \"2026-06-28T16:40:12.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://acme.sku.io/api/rmas/512/fifo-layers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://acme.sku.io/api/rmas/512/fifo-layers?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://acme.sku.io/api/rmas/512/fifo-layers\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Return Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts","host":["{{baseUrl}}"],"path":["api","return-receipts"]},"description":"List all return receipts with pagination. Supports filtering by RMA, warehouse, blind receipts (no RMA), and search by ID or RMA number.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-receipts","host":["{{baseUrl}}"],"path":["api","return-receipts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"rma_id\": 5,\n      \"rma\": {\n        \"id\": 5,\n        \"rma_number\": \"RMA-2024-0001\",\n        \"status\": \"received\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"received_at\": \"2024-01-15T10:30:00.000000Z\",\n      \"received_by_user_id\": 2,\n      \"received_by\": {\n        \"id\": 2,\n        \"name\": \"Jane Smith\"\n      },\n      \"notes\": \"All items received in good condition.\",\n      \"return_receipt_lines\": [\n        {\n          \"id\": 1,\n          \"return_receipt_id\": 1,\n          \"rma_line_id\": 3,\n          \"product_id\": 10,\n          \"product\": {\n            \"id\": 10,\n            \"sku\": \"PROD-001\",\n            \"name\": \"Widget A\"\n          },\n          \"original_product_id\": null,\n          \"quantity\": 2,\n          \"action\": \"return_to_stock\",\n          \"return_reason_id\": 1,\n          \"notes\": null,\n          \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n          \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n        }\n      ],\n      \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 25,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Create Return Receipt","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts","host":["{{baseUrl}}"],"path":["api","return-receipts"]},"description":"Create a new return receipt (blind or RMA-linked). Adjusts inventory based on each line's action.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- warehouse_id (required): Warehouse where items are being received\n- rma_id (optional): Link to an RMA; omit for blind receipts\n- received_at (optional): ISO 8601 datetime; defaults to now\n- notes (optional): General notes for the receipt\n- return_receipt_lines (required): Array of line items\n  - product_id (required): Product being returned\n  - original_product_id (optional): If different from product_id (e.g., substituted product)\n  - rma_line_id (optional): Link to specific RMA line\n  - quantity (required): Quantity received (min: 1)\n  - action (required): One of: return_to_stock, dispose, refurbish\n  - return_reason_id (optional): ID of return reason\n  - notes (optional): Line-level notes (max 500 chars)\n\n**Requires permission:** `returns.receive`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"rma_id\": 5,\n  \"received_at\": \"2024-01-15T10:30:00\",\n  \"notes\": \"All items received in good condition.\",\n  \"return_receipt_lines\": [\n    {\n      \"product_id\": 10,\n      \"original_product_id\": null,\n      \"rma_line_id\": 3,\n      \"quantity\": 2,\n      \"action\": \"return_to_stock\",\n      \"return_reason_id\": 1,\n      \"notes\": \"Minor cosmetic damage.\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts","host":["{{baseUrl}}"],"path":["api","return-receipts"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"rma_id\": 5,\n    \"rma\": {\n      \"id\": 5,\n      \"rma_number\": \"RMA-2024-0001\",\n      \"status\": \"received\"\n    },\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"received_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"received_by_user_id\": 2,\n    \"received_by\": {\n      \"id\": 2,\n      \"name\": \"Jane Smith\"\n    },\n    \"notes\": \"All items received in good condition.\",\n    \"return_receipt_lines\": [\n      {\n        \"id\": 15,\n        \"return_receipt_id\": 12,\n        \"rma_line_id\": 3,\n        \"product_id\": 10,\n        \"product\": {\n          \"id\": 10,\n          \"sku\": \"PROD-001\",\n          \"name\": \"Widget A\"\n        },\n        \"quantity\": 2,\n        \"action\": \"return_to_stock\",\n        \"return_reason_id\": 1,\n        \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n        \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n  },\n  \"message\": \"Return Receipt created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Return Receipt","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/{return_receipt}","host":["{{baseUrl}}"],"path":["api","return-receipts",":return_receipt"],"variable":[{"key":"return_receipt","value":"1","description":"Return receipt ID"}]},"description":"Get a single return receipt with full detail, including RMA and sales order, warehouse, received-by user, and all receipt lines with products, original products, RMA lines, and return reasons.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-receipts/{return_receipt}","host":["{{baseUrl}}"],"path":["api","return-receipts",":return_receipt"],"variable":[{"key":"return_receipt","value":"1","description":"Return receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_id\": 5,\n    \"rma\": {\n      \"id\": 5,\n      \"rma_number\": \"RMA-2024-0001\",\n      \"status\": \"received\"\n    },\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"received_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"received_by_user_id\": 2,\n    \"received_by\": {\n      \"id\": 2,\n      \"name\": \"Jane Smith\"\n    },\n    \"notes\": \"All items received in good condition.\",\n    \"return_receipt_lines\": [\n      {\n        \"id\": 1,\n        \"return_receipt_id\": 1,\n        \"rma_line_id\": 3,\n        \"rma_line\": {\n          \"id\": 3,\n          \"expected_quantity\": 2,\n          \"product_id\": 10\n        },\n        \"product_id\": 10,\n        \"product\": {\n          \"id\": 10,\n          \"sku\": \"PROD-001\",\n          \"name\": \"Widget A\"\n        },\n        \"original_product_id\": null,\n        \"original_product\": null,\n        \"quantity\": 2,\n        \"action\": \"return_to_stock\",\n        \"return_reason_id\": 1,\n        \"return_reason\": {\n          \"id\": 1,\n          \"name\": \"Defective\"\n        },\n        \"notes\": \"Minor cosmetic damage.\",\n        \"fifo_layer_id\": 42,\n        \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n        \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:30:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Return Receipt","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/{return_receipt}","host":["{{baseUrl}}"],"path":["api","return-receipts",":return_receipt"],"variable":[{"key":"return_receipt","value":"1","description":"Return receipt ID"}]},"description":"Delete a return receipt and all its lines. Reverses inventory adjustments.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.receive`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-receipts/{return_receipt}","host":["{{baseUrl}}"],"path":["api","return-receipts",":return_receipt"],"variable":[{"key":"return_receipt","value":"1","description":"Return receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Return Receipt deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Add Line to Return Receipt","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"}]},"description":"Add a new line to an existing return receipt. Creates an inventory movement for the specified action.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- product_id (required): Product being returned\n- original_product_id (optional): Original product if different (e.g., substituted)\n- rma_line_id (optional): Link to specific RMA line\n- quantity (required): Quantity received (min: 1)\n- action (required): One of: return_to_stock, dispose, refurbish\n- return_reason_id (optional): ID of return reason\n- notes (optional): Notes (max 500 chars)\n\n**Requires permission:** `returns.receive`","body":{"mode":"raw","raw":"{\n  \"product_id\": 10,\n  \"original_product_id\": null,\n  \"rma_line_id\": 3,\n  \"quantity\": 1,\n  \"action\": \"dispose\",\n  \"return_reason_id\": 2,\n  \"notes\": \"Item is not suitable for resale.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_id\": 5,\n    \"warehouse_id\": 1,\n    \"return_receipt_lines\": [\n      {\n        \"id\": 15,\n        \"product_id\": 10,\n        \"quantity\": 2,\n        \"action\": \"return_to_stock\"\n      },\n      {\n        \"id\": 16,\n        \"product_id\": 10,\n        \"quantity\": 1,\n        \"action\": \"dispose\"\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\"\n  },\n  \"message\": \"Return Receipt Line created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Update Return Receipt Line","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines",":returnReceiptLine"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"},{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]},"description":"Update non-inventory-impacting fields on a return receipt line. Only notes and return_reason_id can be changed after creation. Fields that affect inventory (quantity, action, product_id) cannot be updated — delete and recreate the line to correct those.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.receive`","body":{"mode":"raw","raw":"{\n  \"return_reason_id\": 2,\n  \"notes\": \"Updated note: item was cosmetically damaged.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines",":returnReceiptLine"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"},{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"rma_id\": 5,\n    \"return_receipt_lines\": [\n      {\n        \"id\": 15,\n        \"product_id\": 10,\n        \"quantity\": 2,\n        \"action\": \"return_to_stock\",\n        \"return_reason_id\": 2,\n        \"notes\": \"Updated note: item was cosmetically damaged.\"\n      }\n    ]\n  },\n  \"message\": \"Return Receipt Line updated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Remove Line from Return Receipt","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines",":returnReceiptLine"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"},{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]},"description":"Remove a specific line from a return receipt. Reverses the inventory adjustment for that line. The line must belong to the specified return receipt.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.receive`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines",":returnReceiptLine"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"},{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"return_receipt_lines\": []\n  },\n  \"message\": \"Return Receipt Line deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Return Receipt Line (standalone)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts","lines",":returnReceiptLine"],"variable":[{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]},"description":"Delete a return receipt line directly by its ID (without specifying the parent receipt). If this is the last line on the return receipt, the entire return receipt is deleted automatically.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `returns.receive`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-receipts/lines/{returnReceiptLine}","host":["{{baseUrl}}"],"path":["api","return-receipts","lines",":returnReceiptLine"],"variable":[{"key":"returnReceiptLine","value":"15","description":"Return receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return receipt line deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Set Disposition on Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/bulk-disposition","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines","bulk-disposition"],"variable":[{"key":"returnReceipt","value":"5","description":"Return Receipt ID"}]},"description":"Set the disposition (action + optional condition grade) on multiple lines of a return receipt at once. When a line's action changes, its prior inventory effect is reversed and the new action is re-applied so inventory stays consistent.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- line_ids (array of integers, required, min 1) — return receipt line IDs to update; each must exist\n- action (string, required) — disposition to apply. Bulk disposition only supports: added_to_stock, discarded. (Use the per-line blemished SKU flow for new_blemished_sku.)\n- condition_grade (string, optional, nullable) — condition grade to set on the lines. One of: A, B, C, unsellable\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Requires permission:** `returns.receive`","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    8,\n    9\n  ],\n  \"action\": \"added_to_stock\",\n  \"condition_grade\": \"A\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/lines/bulk-disposition","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","lines","bulk-disposition"],"variable":[{"key":"returnReceipt","value":"5","description":"Return Receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"rma_id\": 1,\n    \"rma\": {\n      \"id\": 1,\n      \"rma_number\": \"RMA-0001\",\n      \"status\": \"received\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"received_at\": \"2026-06-09T00:00:00.000000Z\",\n    \"received_by_user_id\": 1,\n    \"received_by\": {\n      \"id\": 1,\n      \"name\": \"Dev User\"\n    },\n    \"notes\": null,\n    \"return_receipt_lines\": [\n      {\n        \"id\": 8,\n        \"product_id\": 20,\n        \"product\": {\n          \"id\": 20,\n          \"sku\": \"WIDGET-A\",\n          \"name\": \"Widget A\"\n        },\n        \"quantity\": 2,\n        \"action\": \"added_to_stock\",\n        \"condition_grade\": \"A\",\n        \"condition_grade_label\": \"Grade A — Like New\",\n        \"disposition_policy_id\": null,\n        \"return_reason_id\": 1\n      },\n      {\n        \"id\": 9,\n        \"product_id\": 21,\n        \"product\": {\n          \"id\": 21,\n          \"sku\": \"WIDGET-B\",\n          \"name\": \"Widget B\"\n        },\n        \"quantity\": 1,\n        \"action\": \"added_to_stock\",\n        \"condition_grade\": \"A\",\n        \"condition_grade_label\": \"Grade A — Like New\",\n        \"disposition_policy_id\": null,\n        \"return_reason_id\": 1\n      }\n    ],\n    \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-09T09:30:00.000000Z\"\n  },\n  \"message\": \"Disposition applied to 2 line(s).\"\n}"}]},{"name":"Resolve Scan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/scan-resolve","host":["{{baseUrl}}"],"path":["api","return-receipts","scan-resolve"]},"description":"Resolve a scanned token for the Receive Returns Station. Resolution order: open RMA by number → open RMA by tracking number → sales order by number → product by SKU/barcode. Returns the match type plus staged lines whose dispositions are defaulted by the active return disposition policies (the matching policy id is included so the UI can show a 'policy applied' badge). Closed/canceled RMAs are excluded and fall through to 'none'.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- token (required): The raw scanned value (RMA #, tracking #, order #, SKU, or barcode)\n- warehouse_id (required): Warehouse the operator is receiving into (used for warehouse-scoped policy matching)\n\nWhen the token matches an RMA or a sales order, the response includes `sales_order_notes` — the notes on the sales order being returned (pinned notes first, then newest first), each with `id`, `note`, `user_name`, `created_at`, and `is_pinned`. An RMA match also includes the linked `sales_order_id`, `sales_order_number`, and the RMA's own free-text `notes`.","body":{"mode":"raw","raw":"{\n  \"token\": \"RMA-2026-00012\",\n  \"warehouse_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts/scan-resolve","host":["{{baseUrl}}"],"path":["api","return-receipts","scan-resolve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"match_type\": \"product\",\n    \"rma\": null,\n    \"order\": null,\n    \"staged_lines\": [\n      {\n        \"product_id\": 10,\n        \"sku\": \"WIDGET-BLK\",\n        \"name\": \"Widget - Black\",\n        \"rma_line_id\": null,\n        \"suggested_quantity\": 1,\n        \"suggested_action\": \"added_to_stock\",\n        \"policy_id\": 4,\n        \"policy_name\": \"Main Warehouse Grade A → Restock\",\n        \"return_reason_id\": null\n      }\n    ],\n    \"sales_order_notes\": []\n  }\n}"}]},{"name":"Resolve Line Disposition","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/resolve-line-disposition","host":["{{baseUrl}}"],"path":["api","return-receipts","resolve-line-disposition"]},"description":"Re-resolve the policy-defaulted disposition for a single staged line once more criteria are known (e.g. after the operator selects a condition grade), so grade-specific disposition policies apply at the Receive Station.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- product_id (required)\n- warehouse_id (required)\n- return_reason_id (optional)\n- condition_grade (optional): A|B|C|unsellable","body":{"mode":"raw","raw":"{\n  \"product_id\": 10,\n  \"warehouse_id\": 1,\n  \"return_reason_id\": null,\n  \"condition_grade\": \"C\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts/resolve-line-disposition","host":["{{baseUrl}}"],"path":["api","return-receipts","resolve-line-disposition"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"action\": \"new_blemished_sku\",\n    \"policy_id\": 2,\n    \"policy_name\": \"Grade C electronics → Open Box SKU\"\n  }\n}"}]},{"name":"Get Session Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/session-summary","host":["{{baseUrl}}"],"path":["api","return-receipts","session-summary"]},"description":"Aggregate the return receipts the current authenticated user has committed since a timestamp, powering the station's running 'this session' totals (receipts, units, and units by disposition).\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- since (optional): ISO 8601 datetime; defaults to the start of today"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-receipts/session-summary","host":["{{baseUrl}}"],"path":["api","return-receipts","session-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"receipt_count\": 7,\n    \"unit_count\": 23,\n    \"restocked_units\": 18,\n    \"discarded_units\": 3,\n    \"blemished_units\": 2\n  }\n}"}]},{"name":"Preview Return Receipt Delete Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","delete-impact"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"}]},"description":"Read-only preview of the allocation-demotion impact of deleting this return receipt. Because deleting it removes the stock it added, this behaves like a manual negative adjustment and returns one row per affected product: how much of the removed quantity is unallocated vs soft-allocated vs hard-allocated, plus every sales-order allocation and fulfillment (printed shipping label) the removal would disturb. Use it to decide which fulfillments to authorize voiding via `void_confirmations` on the deleting call. Nothing is mutated. A removal that only re-adds stock returns an empty `data` array.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-receipts/{returnReceipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","return-receipts",":returnReceipt","delete-impact"],"variable":[{"key":"returnReceipt","value":"1","description":"Return receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 5567,\n      \"product_sku\": \"WIDGET-BLUE\",\n      \"product_name\": \"Blue Widget\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 10,\n      \"soft_allocated_quantity\": 6,\n      \"hard_allocated_quantity\": 4,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88201,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 3120,\n          \"order_number\": \"SO-3120\",\n          \"customer_name\": \"Acme Co.\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 6\n        },\n        {\n          \"allocation_id\": 88205,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 3125,\n          \"order_number\": \"SO-3125\",\n          \"customer_name\": \"Beta LLC\",\n          \"fulfillment_id\": 90142,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 4,\n          \"allocation_ids\": [\n            88205\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Preview Return Receipt Release Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-receipts/preview-release-impact","host":["{{baseUrl}}"],"path":["api","return-receipts","preview-release-impact"]},"description":"Read-only preview of which back-ordered sales orders this return receipt would release, per restock-to-sellable line. Send the same payload you would POST to create the receipt; each line that restocks sellable stock is resolved to its product and the receive warehouse and evaluated against waiting back-ordered demand. Nothing is written.\n\nEach row describes one product the receive would restock. `releasable_quantity` is the number of incoming units that can be released to back-ordered demand; `orders[]` are the back-ordered sales orders that would be filled; `held_back[]` is demand that stays back-ordered, with `reason_kept` explaining why (e.g. \"Insufficient supply\").\n\nBody: the same shape as Create Return Receipt. Minimum: `warehouse_id` and one `return_receipt_lines` entry with `product_id`, `quantity`, and `action`. `release_backorders` (true/false/null) mirrors the receive call's release control.\n\nAuthentication: Requires Bearer token. Requires the returns.receive permission.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"release_backorders\": true,\n  \"return_receipt_lines\": [\n    {\n      \"product_id\": 123,\n      \"rma_line_id\": 3,\n      \"quantity\": 8,\n      \"action\": \"return_to_stock\",\n      \"return_reason_id\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-receipts/preview-release-impact","host":["{{baseUrl}}"],"path":["api","return-receipts","preview-release-impact"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"releasable_quantity\": 8,\n      \"orders\": [\n        {\n          \"sales_order_id\": 4602,\n          \"order_number\": \"SO-10501\",\n          \"customer_name\": \"Acme Retail\",\n          \"quantity\": 5\n        },\n        {\n          \"sales_order_id\": 4610,\n          \"order_number\": \"SO-10509\",\n          \"customer_name\": \"Gamma Foods\",\n          \"quantity\": 3\n        }\n      ],\n      \"held_back\": [\n        {\n          \"allocation_id\": 90311,\n          \"product_id\": 123,\n          \"sales_order_id\": 4620,\n          \"sales_order_line_id\": 55123,\n          \"sales_order_number\": \"SO-10518\",\n          \"customer_name\": \"Delta Mart\",\n          \"quantity\": 4,\n          \"from_status\": \"planned\",\n          \"to_status\": \"allocated\",\n          \"reason_kept\": \"Insufficient supply\"\n        }\n      ]\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List Return Reasons","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons?archived=0&search=&sort=name&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","return-reasons"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search return reasons by name","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Records per page","disabled":true}]},"description":"List all return reasons with standard list query parameters. Supports filtering, sorting, search and pagination.\n\nAuthentication: Requires Bearer token.\n\nSort fields: id, name, created_at, updated_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-reasons?archived=0&search=&sort=name&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","return-reasons"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search return reasons by name","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Records per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Defective Item\",\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wrong Item Shipped\",\n      \"created_at\": \"2024-01-01T00:00:00Z\",\n      \"updated_at\": \"2024-01-01T00:00:00Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2\n}"}]},{"name":"Create Return Reason","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-reasons","host":["{{baseUrl}}"],"path":["api","return-reasons"]},"description":"Create a new return reason.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Unique return reason name, max 255 characters\n\n**Requires permission:** `return_reasons.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Customer Changed Mind\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-reasons","host":["{{baseUrl}}"],"path":["api","return-reasons"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return reason has been successfully created\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Customer Changed Mind\",\n    \"created_at\": \"2024-03-15T14:30:00Z\",\n    \"updated_at\": \"2024-03-15T14:30:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Delete Return Reasons","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons","host":["{{baseUrl}}"],"path":["api","return-reasons"]},"description":"Bulk delete multiple return reasons by ID.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-reasons","host":["{{baseUrl}}"],"path":["api","return-reasons"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 return reasons deleted successfully\"\n}"}]},{"name":"Get Return Reason","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"1","description":"Return reason ID"}]},"description":"Retrieve a single return reason by ID.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"1","description":"Return reason ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Defective Item\",\n    \"created_at\": \"2024-01-01T00:00:00Z\",\n    \"updated_at\": \"2024-01-01T00:00:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Return Reason","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]},"description":"Update an existing return reason.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): New unique return reason name, max 255 characters\n\n**Requires permission:** `return_reasons.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Changed Mind / No Longer Needed\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return reason Changed Mind / No Longer Needed has been successfully updated\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Changed Mind / No Longer Needed\",\n    \"created_at\": \"2024-03-15T14:30:00Z\",\n    \"updated_at\": \"2024-03-15T15:00:00Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Delete Return Reason","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]},"description":"Delete a return reason. Will fail if reason is linked to existing return receipt lines.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return reason Changed Mind / No Longer Needed has been successfully deleted\"\n}"}]},{"name":"Check Return Reasons Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-reasons/deletable","host":["{{baseUrl}}"],"path":["api","return-reasons","deletable"]},"description":"Check which return reasons can be safely deleted. Returns deletability status per ID.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of integer return reason IDs\n\n**Requires permission:** `return_reasons.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-reasons/deletable","host":["{{baseUrl}}"],"path":["api","return-reasons","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Defective Item\",\n      \"deletable\": false,\n      \"reason\": \"In use by 12 return receipts\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wrong Item Shipped\",\n      \"deletable\": false,\n      \"reason\": \"In use by 5 return receipts\"\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Changed Mind\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Archive Return Reason","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}/archive","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason","archive"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]},"description":"Archive a single return reason.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}/archive","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason","archive"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return reason Changed Mind has been archived\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Changed Mind\",\n    \"archived_at\": \"2024-03-16T10:00:00Z\"\n  }\n}"}]},{"name":"Unarchive Return Reason","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}/unarchived","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason","unarchived"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]},"description":"Unarchive a single return reason.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-reasons/{return_reason}/unarchived","host":["{{baseUrl}}"],"path":["api","return-reasons",":return_reason","unarchived"],"variable":[{"key":"return_reason","value":"5","description":"Return reason ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"return reason Changed Mind has been unarchived\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Changed Mind\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Return Reasons","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-reasons/archive","host":["{{baseUrl}}"],"path":["api","return-reasons","archive"]},"description":"Bulk archive multiple return reasons.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-reasons/archive","host":["{{baseUrl}}"],"path":["api","return-reasons","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 return reasons archived successfully\"\n}"}]},{"name":"Bulk Unarchive Return Reasons","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-reasons/unarchive","host":["{{baseUrl}}"],"path":["api","return-reasons","unarchive"]},"description":"Bulk unarchive multiple return reasons.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `return_reasons.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-reasons/unarchive","host":["{{baseUrl}}"],"path":["api","return-reasons","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 return reasons unarchived successfully\"\n}"}]},{"name":"List Disposition Policies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies","host":["{{baseUrl}}"],"path":["api","return-disposition-policies"]},"description":"List all return disposition policies, ordered by precedence (priority ascending, then id ascending).\n\nAuthentication: Requires Bearer token.\n\nDisposition policies are evaluated top-to-bottom at return-receiving time to auto-assign a line's disposition (added to stock, discarded, or new blemished SKU). The first active policy whose match_* criteria all match wins; if none match, the default is added_to_stock.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-disposition-policies","host":["{{baseUrl}}"],"path":["api","return-disposition-policies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Like-new returns → restock\",\n      \"is_active\": true,\n      \"priority\": 0,\n      \"match_product_id\": null,\n      \"match_product_category_id\": null,\n      \"match_return_reason_id\": null,\n      \"match_warehouse_id\": null,\n      \"match_condition_grade\": \"A\",\n      \"match_condition_grade_label\": \"Grade A — Like New\",\n      \"action\": \"added_to_stock\",\n      \"action_label\": \"Added to Stock\",\n      \"blemished_condition\": null,\n      \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Grade B → blemished SKU\",\n      \"is_active\": true,\n      \"priority\": 1,\n      \"match_product_id\": null,\n      \"match_product_category_id\": null,\n      \"match_return_reason_id\": null,\n      \"match_warehouse_id\": null,\n      \"match_condition_grade\": \"B\",\n      \"match_condition_grade_label\": \"Grade B — Good\",\n      \"action\": \"new_blemished_sku\",\n      \"action_label\": \"New Blemished SKU\",\n      \"blemished_condition\": \"Open box — good condition\",\n      \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Disposition Policy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies","host":["{{baseUrl}}"],"path":["api","return-disposition-policies"]},"description":"Create a new return disposition policy.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (string, required, max 255) — human-readable policy name\n- action (string, required) — disposition to apply when this policy matches. One of: added_to_stock, discarded, new_blemished_sku\n- is_active (boolean, optional, default true) — only active policies are evaluated at resolve time\n- priority (integer, optional, min 0) — lower numbers are evaluated first; ties broken by id\n- match_product_id (integer, optional, nullable) — restrict to a single product\n- match_product_category_id (integer, optional, nullable) — restrict to a product category (matches the product's category and any ancestor category)\n- match_return_reason_id (integer, optional, nullable) — restrict to a return reason\n- match_warehouse_id (integer, optional, nullable) — restrict to a warehouse\n- match_condition_grade (string, optional, nullable) — restrict to a condition grade. One of: A, B, C, unsellable\n- blemished_condition (string, optional, nullable, max 255) — condition note applied when action is new_blemished_sku\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.","body":{"mode":"raw","raw":"{\n  \"name\": \"Damaged electronics → discard\",\n  \"action\": \"discarded\",\n  \"is_active\": true,\n  \"priority\": 0,\n  \"match_product_id\": null,\n  \"match_product_category_id\": 12,\n  \"match_return_reason_id\": 4,\n  \"match_warehouse_id\": null,\n  \"match_condition_grade\": \"unsellable\",\n  \"blemished_condition\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-disposition-policies","host":["{{baseUrl}}"],"path":["api","return-disposition-policies"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Damaged electronics → discard\",\n    \"is_active\": true,\n    \"priority\": 0,\n    \"match_product_id\": null,\n    \"match_product_category_id\": 12,\n    \"match_product_category\": {\n      \"id\": 12,\n      \"name\": \"Electronics\"\n    },\n    \"match_return_reason_id\": 4,\n    \"match_return_reason\": {\n      \"id\": 4,\n      \"name\": \"Arrived damaged\"\n    },\n    \"match_warehouse_id\": null,\n    \"match_condition_grade\": \"unsellable\",\n    \"match_condition_grade_label\": \"Unsellable\",\n    \"action\": \"discarded\",\n    \"action_label\": \"Discarded\",\n    \"blemished_condition\": null,\n    \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n  },\n  \"message\": \"Disposition Policy created successfully\"\n}"}]},{"name":"Get Disposition Policy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]},"description":"Get a single disposition policy with its matched product, category, return reason, and warehouse summaries.\n\nAuthentication: Requires Bearer token.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Damaged electronics → discard\",\n    \"is_active\": true,\n    \"priority\": 0,\n    \"match_product_id\": null,\n    \"match_product_category_id\": 12,\n    \"match_product_category\": {\n      \"id\": 12,\n      \"name\": \"Electronics\"\n    },\n    \"match_return_reason_id\": 4,\n    \"match_return_reason\": {\n      \"id\": 4,\n      \"name\": \"Arrived damaged\"\n    },\n    \"match_warehouse_id\": null,\n    \"match_condition_grade\": \"unsellable\",\n    \"match_condition_grade_label\": \"Unsellable\",\n    \"action\": \"discarded\",\n    \"action_label\": \"Discarded\",\n    \"blemished_condition\": null,\n    \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Disposition Policy","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]},"description":"Update an existing disposition policy. Send the full set of fields (same shape as create).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (string, required, max 255) — human-readable policy name\n- action (string, required) — disposition to apply when this policy matches. One of: added_to_stock, discarded, new_blemished_sku\n- is_active (boolean, optional, default true) — only active policies are evaluated at resolve time\n- priority (integer, optional, min 0) — lower numbers are evaluated first; ties broken by id\n- match_product_id (integer, optional, nullable) — restrict to a single product\n- match_product_category_id (integer, optional, nullable) — restrict to a product category (matches the product's category and any ancestor category)\n- match_return_reason_id (integer, optional, nullable) — restrict to a return reason\n- match_warehouse_id (integer, optional, nullable) — restrict to a warehouse\n- match_condition_grade (string, optional, nullable) — restrict to a condition grade. One of: A, B, C, unsellable\n- blemished_condition (string, optional, nullable, max 255) — condition note applied when action is new_blemished_sku\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.","body":{"mode":"raw","raw":"{\n  \"name\": \"Damaged electronics → discard\",\n  \"action\": \"discarded\",\n  \"is_active\": true,\n  \"priority\": 0,\n  \"match_product_id\": null,\n  \"match_product_category_id\": 12,\n  \"match_return_reason_id\": 4,\n  \"match_warehouse_id\": null,\n  \"match_condition_grade\": \"unsellable\",\n  \"blemished_condition\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Damaged electronics → discard\",\n    \"is_active\": true,\n    \"priority\": 0,\n    \"match_product_id\": null,\n    \"match_product_category_id\": 12,\n    \"match_product_category\": {\n      \"id\": 12,\n      \"name\": \"Electronics\"\n    },\n    \"match_return_reason_id\": 4,\n    \"match_return_reason\": {\n      \"id\": 4,\n      \"name\": \"Arrived damaged\"\n    },\n    \"match_warehouse_id\": null,\n    \"match_condition_grade\": \"unsellable\",\n    \"match_condition_grade_label\": \"Unsellable\",\n    \"action\": \"discarded\",\n    \"action_label\": \"Discarded\",\n    \"blemished_condition\": null,\n    \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n  },\n  \"message\": \"Disposition Policy updated successfully\"\n}"}]},{"name":"Delete Disposition Policy","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]},"description":"Delete a disposition policy. Already-received receipt lines retain their assigned disposition; only future return-receiving evaluation is affected.\n\nAuthentication: Requires Bearer token.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/return-disposition-policies/{returnDispositionPolicy}","host":["{{baseUrl}}"],"path":["api","return-disposition-policies",":returnDispositionPolicy"],"variable":[{"key":"returnDispositionPolicy","value":"3","description":"Disposition policy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Disposition Policy deleted successfully\"\n}"}]},{"name":"Reorder Disposition Policies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/return-disposition-policies/reorder","host":["{{baseUrl}}"],"path":["api","return-disposition-policies","reorder"]},"description":"Persist a new precedence order for the disposition policies. The position of each id in the ordered_ids array becomes its priority (first = priority 0, evaluated first).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ordered_ids (array of integers, required, min 1) — policy IDs in the desired evaluation order. Must be distinct and each must exist.\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ordered_ids\": [\n    2,\n    1,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/return-disposition-policies/reorder","host":["{{baseUrl}}"],"path":["api","return-disposition-policies","reorder"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Like-new returns → restock\",\n      \"is_active\": true,\n      \"priority\": 0,\n      \"match_product_id\": null,\n      \"match_product_category_id\": null,\n      \"match_return_reason_id\": null,\n      \"match_warehouse_id\": null,\n      \"match_condition_grade\": \"A\",\n      \"match_condition_grade_label\": \"Grade A — Like New\",\n      \"action\": \"added_to_stock\",\n      \"action_label\": \"Added to Stock\",\n      \"blemished_condition\": null,\n      \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Grade B → blemished SKU\",\n      \"is_active\": true,\n      \"priority\": 1,\n      \"match_product_id\": null,\n      \"match_product_category_id\": null,\n      \"match_return_reason_id\": null,\n      \"match_warehouse_id\": null,\n      \"match_condition_grade\": \"B\",\n      \"match_condition_grade_label\": \"Grade B — Good\",\n      \"action\": \"new_blemished_sku\",\n      \"action_label\": \"New Blemished SKU\",\n      \"blemished_condition\": \"Open box — good condition\",\n      \"created_at\": \"2026-06-09T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-09T09:00:00.000000Z\"\n    }\n  ],\n  \"message\": \"Disposition policy order updated.\"\n}"}]},{"name":"Get Returns Summary KPIs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/analytics/summary","host":["{{baseUrl}}"],"path":["api","returns","analytics","summary"]},"description":"KPI summary: return rate, returned/shipped units, RMA count, restock recovery rate, recovered COGS value, discard rate, and average days to disposition.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All query params are optional; dates are app-timezone and converted to UTC. warehouse_ids / product_ids are comma-separated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/analytics/summary","host":["{{baseUrl}}"],"path":["api","returns","analytics","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"return_rate\": 0.084,\n    \"returned_units\": 412,\n    \"shipped_units\": 4904,\n    \"rma_count\": 118,\n    \"restock_recovery_rate\": 0.74,\n    \"recovered_value\": 12480.5,\n    \"discard_rate\": 0.18,\n    \"avg_days_to_disposition\": 6.2\n  }\n}"}]},{"name":"Get Returns by Reason","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/analytics/by-reason","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-reason"]},"description":"Counts and units grouped by return reason, ordered by units desc.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All query params are optional; dates are app-timezone and converted to UTC. warehouse_ids / product_ids are comma-separated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/analytics/by-reason","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-reason"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"reason_id\": 3,\n      \"reason\": \"Defective\",\n      \"line_count\": 48,\n      \"units\": 169\n    },\n    {\n      \"reason_id\": 1,\n      \"reason\": \"Wrong size\",\n      \"line_count\": 31,\n      \"units\": 107\n    }\n  ]\n}"}]},{"name":"Get Returns by Disposition","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/analytics/by-disposition","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-disposition"]},"description":"Units grouped by disposition action (added_to_stock / discarded / new_blemished_sku).\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All query params are optional; dates are app-timezone and converted to UTC. warehouse_ids / product_ids are comma-separated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/analytics/by-disposition","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-disposition"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"action\": \"added_to_stock\",\n      \"label\": \"Add to Stock\",\n      \"line_count\": 210,\n      \"units\": 305\n    },\n    {\n      \"action\": \"discarded\",\n      \"label\": \"Discard\",\n      \"line_count\": 60,\n      \"units\": 74\n    }\n  ]\n}"}]},{"name":"Get Top Returned Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/analytics/by-product","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-product"]},"description":"Top returned products by units (limit 20).\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All query params are optional; dates are app-timezone and converted to UTC. warehouse_ids / product_ids are comma-separated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/analytics/by-product","host":["{{baseUrl}}"],"path":["api","returns","analytics","by-product"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 10,\n      \"sku\": \"WIDGET-BLK\",\n      \"name\": \"Widget - Black\",\n      \"line_count\": 40,\n      \"units\": 88\n    }\n  ]\n}"}]},{"name":"Get Returns Trend","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/analytics/trend","host":["{{baseUrl}}"],"path":["api","returns","analytics","trend"]},"description":"Returns over time, grouped by week (Monday-start) or month.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All query params are optional; dates are app-timezone and converted to UTC. warehouse_ids / product_ids are comma-separated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/analytics/trend","host":["{{baseUrl}}"],"path":["api","returns","analytics","trend"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"period\": \"2026-05-04\",\n      \"units\": 61,\n      \"receipt_count\": 22\n    },\n    {\n      \"period\": \"2026-05-11\",\n      \"units\": 58,\n      \"receipt_count\": 19\n    }\n  ]\n}"}]},{"name":"List Returns Inbox","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/inbox","host":["{{baseUrl}}"],"path":["api","returns","inbox"]},"description":"Paginated, enriched marketplace returns across channels. Each row has link status (an RMA already linked via external_source/external_return_id) and, when unlinked, a suggested order match.\n\n**Required scope: `returns:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. All filters optional."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/inbox","host":["{{baseUrl}}"],"path":["api","returns","inbox"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"source\": \"trackstar\",\n      \"integration_instance_id\": 4,\n      \"external_return_id\": \"TS-10293\",\n      \"channel_order_id\": \"SO-10293\",\n      \"status\": \"requested\",\n      \"customer_name\": \"Acme Co\",\n      \"returned_at\": \"2026-06-01T10:00:00.000000Z\",\n      \"is_linked\": false,\n      \"linked_rma_id\": null,\n      \"linked_rma_number\": null,\n      \"suggested_order_id\": 42,\n      \"suggested_order_number\": \"SO-10293\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Bulk Link Returns","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/returns/inbox/bulk-link","host":["{{baseUrl}}"],"path":["api","returns","inbox","bulk-link"]},"description":"Link the selected marketplace returns to RMAs (creating/linking per the match service; idempotent and conflict-safe).\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- returns[] (required): { source (shopify|walmart|trackstar), external_return_id, channel_order_id? }","body":{"mode":"raw","raw":"{\n  \"returns\": [\n    {\n      \"source\": \"trackstar\",\n      \"external_return_id\": \"TS-10293\",\n      \"channel_order_id\": \"SO-10293\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/returns/inbox/bulk-link","host":["{{baseUrl}}"],"path":["api","returns","inbox","bulk-link"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 1,\n    \"linked\": 0,\n    \"conflict\": 0,\n    \"no_match\": 0,\n    \"already_linked\": 0\n  },\n  \"message\": \"Linked 1 return(s): 1 new RMA(s), 0 existing, 0 unmatched, 0 conflicts.\"\n}"}]},{"name":"Match Returns Now","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/returns/inbox/match-now","host":["{{baseUrl}}"],"path":["api","returns","inbox","match-now"]},"description":"Dispatch the tracked auto-match job for unlinked marketplace returns (optionally scoped to a source / integration). Returns a tracked_job_log_id; progress shows via the tracked job log endpoints. Job name: \"Match Marketplace Returns\".\n\n**Required scope: `returns:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. source and integration_instance_id are optional (omit for all).","body":{"mode":"raw","raw":"{\n  \"source\": \"trackstar\",\n  \"integration_instance_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/returns/inbox/match-now","host":["{{baseUrl}}"],"path":["api","returns","inbox","match-now"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4310\n  },\n  \"message\": \"Matching marketplace returns — track progress in the job tray.\"\n}"}]},{"name":"List Unmatched Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/reconciliation/unmatched","host":["{{baseUrl}}"],"path":["api","returns","reconciliation","unmatched"]},"description":"Paginated list of received returns that are not yet linked to a return authorization (RMA) — returns received without a matching authorization, plus ambiguous matches flagged for review. Use it to reconcile or write off aged, unmatched returns. Filter by warehouse, reconciliation status, aging, received date, or product, and search by SKU/name.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/reconciliation/unmatched","host":["{{baseUrl}}"],"path":["api","returns","reconciliation","unmatched"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"received_at\": \"2026-07-21T02:14:00.000000Z\",\n      \"age_days\": 0,\n      \"reconciliation_status\": {\n        \"value\": \"blind_unmatched\",\n        \"label\": \"Unmatched\"\n      },\n      \"needs_review\": false,\n      \"is_blind\": true,\n      \"notes\": null,\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Returns Warehouse\"\n      },\n      \"received_by\": {\n        \"id\": 3,\n        \"name\": \"Warehouse Operator\"\n      },\n      \"rma\": null,\n      \"lines\": [\n        {\n          \"id\": 9901,\n          \"product_id\": 55,\n          \"sku\": \"BRIEF-BUR-M\",\n          \"product_name\": \"Burgundy Brief M\",\n          \"quantity\": 1,\n          \"unexpected_item\": false\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/returns/reconciliation/unmatched?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/returns/reconciliation/unmatched?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/returns/reconciliation/unmatched\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Recently Received Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/returns/reconciliation/recent?warehouse_id=12","host":["{{baseUrl}}"],"path":["api","returns","reconciliation","recent"],"query":[{"key":"warehouse_id","value":"12","description":"Warehouse to list recent returns for (required).","disabled":true}]},"description":"Returns committed in a warehouse within the given window (today, or the last 7 days), across all operators — for confirming what has been received. Read-only.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/returns/reconciliation/recent?warehouse_id=12","host":["{{baseUrl}}"],"path":["api","returns","reconciliation","recent"],"query":[{"key":"warehouse_id","value":"12","description":"Warehouse to list recent returns for (required).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"received_at\": \"2026-07-21T02:14:00.000000Z\",\n      \"age_days\": 0,\n      \"reconciliation_status\": {\n        \"value\": \"blind_unmatched\",\n        \"label\": \"Unmatched\"\n      },\n      \"needs_review\": false,\n      \"is_blind\": true,\n      \"notes\": null,\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Returns Warehouse\"\n      },\n      \"received_by\": {\n        \"id\": 3,\n        \"name\": \"Warehouse Operator\"\n      },\n      \"rma\": null,\n      \"lines\": [\n        {\n          \"id\": 9901,\n          \"product_id\": 55,\n          \"sku\": \"BRIEF-BUR-M\",\n          \"product_name\": \"Burgundy Brief M\",\n          \"quantity\": 1,\n          \"unexpected_item\": false\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Link Return Receipt to RMA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/returns/reconciliation/{returnReceipt}/link","host":["{{baseUrl}}"],"path":["api","returns","reconciliation",":returnReceipt","link"],"variable":[{"key":"returnReceipt","value":"","description":"The return receipt ID."}]},"description":"Link an unmatched return receipt to a return authorization (RMA), recording its received quantity without adding inventory a second time (the goods were already received). Provide exactly one of rma_id or sales_order_id; with sales_order_id the single open, unreceived RMA on that order is used. Fails with 422 if the target RMA is already received (which would double-count) or the order has zero/multiple open RMAs.\n\nRequires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"rma_id\": 812\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/returns/reconciliation/{returnReceipt}/link","host":["{{baseUrl}}"],"path":["api","returns","reconciliation",":returnReceipt","link"],"variable":[{"key":"returnReceipt","value":"","description":"The return receipt ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Return receipt linked.\",\n  \"data\": {\n    \"id\": 4821,\n    \"received_at\": \"2026-07-21T02:14:00.000000Z\",\n    \"age_days\": 0,\n    \"reconciliation_status\": {\n      \"value\": \"matched\",\n      \"label\": \"Matched\"\n    },\n    \"needs_review\": false,\n    \"is_blind\": false,\n    \"notes\": null,\n    \"warehouse\": {\n      \"id\": 12,\n      \"name\": \"Returns Warehouse\"\n    },\n    \"received_by\": {\n      \"id\": 3,\n      \"name\": \"Warehouse Operator\"\n    },\n    \"rma\": {\n      \"id\": 812,\n      \"rma_number\": \"RMA-2026-15452\",\n      \"sales_order_id\": 7781,\n      \"link_route\": \"/rma/812\",\n      \"link_type_label\": \"RMA\",\n      \"link_reference\": \"RMA-2026-15452\"\n    },\n    \"lines\": [\n      {\n        \"id\": 9901,\n        \"product_id\": 55,\n        \"sku\": \"BRIEF-BUR-M\",\n        \"product_name\": \"Burgundy Brief M\",\n        \"quantity\": 1,\n        \"unexpected_item\": false\n      }\n    ]\n  }\n}"}]}]},{"name":"Inventory Adjustments","item":[{"name":"List Inventory Adjustments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of inventory adjustments.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"product_id\": 15,\n      \"warehouse_id\": 2,\n      \"quantity\": -5,\n      \"reason\": \"Damaged\",\n      \"created_at\": \"2024-03-10T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 10,\n  \"per_page\": 10,\n  \"total\": 95\n}"}]},{"name":"Search Inventory Adjustments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments"]},"description":"Returns the same paginated list of inventory adjustments as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against id, notes, SKU, product name, and warehouse.\n\nText columns (`notes`, `sku`, `product_name`, `warehouse`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `quantity`, `adjustment_date`, `created_at`, `updated_at`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. The `direction` filter accepts `positive` or `negative`, `is_correction` accepts `yes` or `no`, and `archived` toggles archived records.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, adjustment_date, quantity, archived_at, created_at, updated_at. Results default to `-created_at`. `per_page` is capped at 100.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-adjustment_date\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"direction\",\n          \"operator\": \"is\",\n          \"value\": \"negative\"\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"adjustment_date\",\n          \"operator\": \"between\",\n          \"value\": [\n            \"2026-06-01\",\n            \"2026-06-30\"\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55231,\n      \"adjustment_date\": \"2026-06-15T00:00:00.000000Z\",\n      \"product_id\": 3312,\n      \"sku\": \"WIDGET-BLUE-01\",\n      \"product_name\": \"Blue Widget\",\n      \"stock_uom_code\": \"EA\",\n      \"is_lot_tracked\": false,\n      \"lot_tracking_method\": null,\n      \"product_average_cost\": 13.75,\n      \"quantity\": -4,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"notes\": \"Damaged in receiving\",\n      \"reason\": \"damaged\",\n      \"is_correction\": false,\n      \"type\": {\n        \"link_type\": \"App\\\\Models\\\\InventoryAdjustment\",\n        \"link_id\": 55231,\n        \"parent_link_type\": null,\n        \"parent_link_id\": null\n      },\n      \"reference\": 55231,\n      \"unit_cost\": 13.75,\n      \"archived_at\": null,\n      \"created_at\": \"2026-06-15T08:41:00.000000Z\",\n      \"updated_at\": \"2026-06-15T08:41:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 9,\n  \"total\": 214,\n  \"next_page_url\": \"https://api.example.com/api/v2/inventory-adjustments?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Export Inventory Adjustments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments/export","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments","export"]},"description":"Exports inventory adjustments as a CSV file.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments/export","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,product_id,warehouse_id,quantity,reason,created_at\n1,15,2,-5,Damaged,2024-03-10 10:00:00"}]},{"name":"Show Inventory Adjustment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments/{inventoryAdjustment}","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments",":inventoryAdjustment"],"variable":[{"key":"inventoryAdjustment","value":"1","description":"Inventory Adjustment ID"}]},"description":"Returns a single inventory adjustment.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-adjustments/{inventoryAdjustment}","host":["{{baseUrl}}"],"path":["api","v2","inventory-adjustments",":inventoryAdjustment"],"variable":[{"key":"inventoryAdjustment","value":"1","description":"Inventory Adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 15,\n    \"warehouse_id\": 2,\n    \"quantity\": -5,\n    \"reason\": \"Damaged\",\n    \"created_at\": \"2024-03-10T10:00:00.000000Z\"\n  }\n}"}]}]},{"name":"Inventory Movements","item":[{"name":"List Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-movements?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","inventory-movements"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of inventory movements.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-movements?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","inventory-movements"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"type\": \"fulfillment\",\n      \"quantity\": -5,\n      \"inventory_status\": \"committed\",\n      \"warehouse_id\": 2,\n      \"product_id\": 15,\n      \"created_at\": \"2024-03-12T11:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 50,\n  \"per_page\": 10,\n  \"total\": 498\n}"}]},{"name":"Search Inventory Movements","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-movements","host":["{{baseUrl}}"],"path":["api","v2","inventory-movements"]},"description":"Returns the same paginated inventory movement audit trail as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against id, SKU, product name, warehouse, and reference.\n\nText columns (`type`, `inventory_status`, `link_type`, `reference`, `product_name`, `sku`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `quantity`, `inventory_movement_date`, `created_at`, `updated_at`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. The `warehouse` filter narrows by warehouse.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, inventory_movement_date, quantity, type, inventory_status, reference, created_at, updated_at, warehouse_name, sku, product_name. Results default to `-inventory_movement_date`.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-inventory_movement_date\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"type\",\n          \"operator\": \"is_one_of\",\n          \"value\": [\n            \"sale\",\n            \"adjustment\"\n          ]\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"quantity\",\n          \"operator\": \"less_than\",\n          \"value\": 0\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-movements","host":["{{baseUrl}}"],"path":["api","v2","inventory-movements"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 442190,\n      \"inventory_movement_date\": \"2026-06-30T09:15:00.000000Z\",\n      \"product_id\": 3312,\n      \"sku\": \"WIDGET-BLUE-01\",\n      \"barcode\": \"8801234567890\",\n      \"product_name\": \"Blue Widget\",\n      \"stock_uom_code\": \"EA\",\n      \"type\": {\n        \"name\": \"sale\",\n        \"link_type\": \"App\\\\Models\\\\SalesOrderLine\",\n        \"link_id\": 88231,\n        \"parent_link_id\": 6021,\n        \"detail_link_id\": null\n      },\n      \"inventory_status\": \"available\",\n      \"quantity\": -3,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"layer\": {\n        \"fifo_layer_id\": 90312,\n        \"name\": \"PO-1042\"\n      },\n      \"fifo_layer_id\": 90312,\n      \"reference\": \"SO-6021\",\n      \"created_at\": \"2026-06-30T09:15:00.000000Z\",\n      \"updated_at\": \"2026-06-30T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 120,\n  \"total\": 2984,\n  \"next_page_url\": \"https://api.example.com/api/v2/inventory-movements?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Export Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-movements/list/export?format=xlsx&scope=filtered","host":["{{baseUrl}}"],"path":["api","v2","inventory-movements","list","export"],"query":[{"key":"format","value":"xlsx","description":"Output format: xlsx (default) or csv","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: all (ignore filters), filtered (apply current filters/search/sort), current_page (rows on the current page), selected (specific IDs via the ids parameter)","disabled":true}]},"description":"Exports inventory movements as an XLSX or CSV file download. Reuses the same Spatie QueryBuilder filters and sorts as the List Inventory Movements endpoint when scope=filtered.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nScopes:\n- all: ignore active filters/sort and export every record\n- filtered (default): apply the current filter/sort/search query params\n- current_page: export the rows on the current page (matches the visible table)\n- selected: export only the IDs supplied via the ids query param\n\nThe response is a binary file (xlsx or csv); Content-Type is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet or text/csv. Authentication: Requires Bearer token.\n\n**Requires permission:** `inventory.export`"}}]},{"name":"Listings","item":[{"name":"List Listings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","listings"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of channel listings (products listed on sales channels).\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","listings"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"product_id\": 15,\n      \"sales_channel_id\": 5,\n      \"channel_product_id\": \"shopify-12345\",\n      \"status\": \"active\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 20,\n  \"per_page\": 10,\n  \"total\": 195\n}"}]},{"name":"Listings Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/summary","host":["{{baseUrl}}"],"path":["api","v2","listings","summary"]},"description":"Returns summary counts for listings by status.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/summary","host":["{{baseUrl}}"],"path":["api","v2","listings","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 195,\n    \"active\": 180,\n    \"archived\": 15\n  }\n}"}]},{"name":"Bulk Archive Listings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-archive","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-archive"]},"description":"Archives multiple listings.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-archive","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 listings archived successfully.\"\n}"}]},{"name":"Bulk Unarchive Listings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-unarchive"]},"description":"Unarchives multiple listings.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 listings unarchived successfully.\"\n}"}]},{"name":"Fetch Listings for Bulk Edit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-edit-fetch?ids=1201,1202,1203","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-edit-fetch"],"query":[{"key":"ids","value":"1201,1202,1203","description":"Comma-separated listing ids to fetch","disabled":true}]},"description":"Fetches a specific set of listings by id together with their current inventory settings, ready to populate a bulk-edit form. Pass the listing ids as a comma-separated string. For each listing you get its SKU, title, FBA flag, integration instance name, master-of-stock source, selected warehouse ids, fulfillment latency and whether it inherits settings from its integration.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-edit-fetch?ids=1201,1202,1203","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-edit-fetch"],"query":[{"key":"ids","value":"1201,1202,1203","description":"Comma-separated listing ids to fetch","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1201,\n      \"listing_sku\": \"ACME-WIDGET-BLU\",\n      \"title\": \"Acme Widget - Blue\",\n      \"is_fba\": false,\n      \"integration_instance_name\": \"Shopify US\",\n      \"master_of_stock\": \"sku.io\",\n      \"warehouse_ids\": [\n        3,\n        7\n      ],\n      \"fulfillment_latency\": 2,\n      \"inherit_settings\": false\n    },\n    {\n      \"id\": 1202,\n      \"listing_sku\": \"ACME-WIDGET-RED\",\n      \"title\": \"Acme Widget - Red\",\n      \"is_fba\": false,\n      \"integration_instance_name\": \"Shopify US\",\n      \"master_of_stock\": null,\n      \"warehouse_ids\": [],\n      \"fulfillment_latency\": null,\n      \"inherit_settings\": true\n    }\n  ],\n  \"status\": \"success\"\n}"}]}]},{"name":"Product Listings","item":[{"name":"List Channel Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory"]},"description":"Returns paginated channel inventory, aggregated to one row per listing across all of that listing's channel locations. Each row compares the quantity calculated by SKU.io (total_sku_quantity) against the quantity last reported by the sales channel (total_channel_quantity) and exposes the variance between them. Archived listings are excluded.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRows are ordered by listing ID descending; custom sorting is not supported on this endpoint.\n\nFilters: filter[search] (listing SKU / title / channel listing ID / product SKU; numeric values also match the listing ID), filter[integration_instance_id], filter[integration_id], filter[is_fba] (true/false), filter[is_sku_recalculation_needed] (true/false), filter[sync_status] (in_sync, mismatch, never_synced, pending_recalc), filter[product_listing_id].\n\nPagination: page, per_page (default: 15).\n\nmaster_of_stock resolves the effective value: a listing-level override wins, otherwise the value is inherited from the channel account's settings.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 4521,\n      \"product_listing_id\": 4521,\n      \"total_sku_quantity\": 120,\n      \"total_channel_quantity\": 118,\n      \"total_variance\": 2,\n      \"location_count\": 2,\n      \"any_recalc_needed\": false,\n      \"oldest_synced_at\": \"2026-07-05 14:22:10\",\n      \"latest_sku_qty_updated\": \"2026-07-06 02:15:44\",\n      \"listing_sku\": \"WIDGET-BLUE-01\",\n      \"listing_title\": \"Blue Widget - 2 Pack\",\n      \"sales_channel_listing_id\": \"B0B12345XY\",\n      \"is_fba\": false,\n      \"master_of_stock\": \"sku.io\",\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-BLUE\",\n      \"product_name\": \"Blue Widget\",\n      \"integration_id\": 3,\n      \"integration_name\": \"Amazon\",\n      \"integration_instance_id\": 7,\n      \"integration_instance_name\": \"Amazon US\",\n      \"created_at\": \"2025-11-02T09:14:33.000000Z\",\n      \"updated_at\": \"2026-07-06T02:15:44.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/v2/listings/channel-inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 349,\n  \"last_page_url\": \"https://example.sku.io/api/v2/listings/channel-inventory?page=349\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.sku.io/api/v2/listings/channel-inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.sku.io/api/v2/listings/channel-inventory?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://example.sku.io/api/v2/listings/channel-inventory?page=2\",\n  \"path\": \"https://example.sku.io/api/v2/listings/channel-inventory\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 5231\n}"}]},{"name":"Export Channel Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/export","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","export"]},"description":"Streams a CSV file download of channel inventory records (one row per listing location, not aggregated per listing). Archived listings are excluded.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response is a file download with Content-Type text/csv and a Content-Disposition attachment filename of the form channel-inventory-YYYY-MM-DD.csv.\n\nColumns: ID, Listing SKU, Listing ID, Title, Product SKU, Product Name, Integration, Channel, Location ID, SKU Qty, Channel Qty, Variance, Needs Recalc, FBA, Master of Stock, SKU Qty Updated, Last Synced.\n\nSupported filters: filter[search], filter[integration_instance_id], filter[integration_id], filter[sync_status] (in_sync, mismatch, never_synced, pending_recalc).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/export","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"ID,Listing SKU,Listing ID,Title,Product SKU,Product Name,Integration,Channel,Location ID,SKU Qty,Channel Qty,Variance,Needs Recalc,FBA,Master of Stock,SKU Qty Updated,Last Synced\n88213,WIDGET-BLUE-01,B0B12345XY,Blue Widget - 2 Pack,WIDGET-BLUE,Blue Widget,Amazon,Amazon US,12345678,120,118,2,No,No,sku.io,2026-07-06 02:15:44,2026-07-05 14:22:10\n"}]},{"name":"Get Channel Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/summary","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","summary"]},"description":"Returns channel inventory counts grouped by integration, the list of connected channel accounts (integration instances) that have at least one active listing, and a breakdown of inventory records by sync status.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nstatus_counts fields: in_sync (SKU.io and channel quantities match and no recalculation is pending), mismatch (quantities differ or a recalculation is pending), never_synced (the channel has never reported a quantity), pending_recalc (flagged for quantity recalculation).\n\nIntegrations with listings but no channel inventory records yet (fresh setup) still appear with a count of 0. Archived listings are excluded throughout.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/summary","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 5231,\n    \"integrations\": [\n      {\n        \"integration_name\": \"Amazon\",\n        \"integration_id\": 3,\n        \"count\": 3120\n      },\n      {\n        \"integration_name\": \"Shopify\",\n        \"integration_id\": 5,\n        \"count\": 1685\n      },\n      {\n        \"integration_name\": \"Walmart\",\n        \"integration_id\": 9,\n        \"count\": 426\n      }\n    ],\n    \"instances\": [\n      {\n        \"integration_instance_id\": 7,\n        \"integration_instance_name\": \"Amazon US\",\n        \"integration_id\": 3\n      },\n      {\n        \"integration_instance_id\": 8,\n        \"integration_instance_name\": \"Shopify Main Store\",\n        \"integration_id\": 5\n      },\n      {\n        \"integration_instance_id\": 12,\n        \"integration_instance_name\": \"Walmart US\",\n        \"integration_id\": 9\n      }\n    ],\n    \"status_counts\": {\n      \"in_sync\": 4655,\n      \"mismatch\": 310,\n      \"never_synced\": 221,\n      \"pending_recalc\": 45\n    }\n  }\n}"}]},{"name":"Export Listings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/export","host":["{{baseUrl}}"],"path":["api","v2","listings","export"]},"description":"Streams a CSV file download of all non-archived listings across every connected sales channel. This endpoint does not accept filters — it always exports the full active listing set, ordered by most recently created first.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response is a file download with Content-Type text/csv and a Content-Disposition attachment filename of the form listings-YYYY-MM-DD.csv.\n\nColumns: ID, Listing SKU, Listing ID, Title, Product SKU, Product Name, Integration, Channel, Price, Quantity, FBA, Master of Price, Master of Stock, Inherit from Integration, Warehouses, Fulfillment Latency (days), Max Rule Type, Max Rule Value, Min Rule Type, Min Rule Value, Buffer Stock, ASIN, Shopify Status, Walmart WPID, Archived At, Created At, Updated At.\n\nWarehouse IDs from each listing's inventory settings are resolved to warehouse names.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/export","host":["{{baseUrl}}"],"path":["api","v2","listings","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"ID,Listing SKU,Listing ID,Title,Product SKU,Product Name,Integration,Channel,Price,Quantity,FBA,Master of Price,Master of Stock,Inherit from Integration,Warehouses,Fulfillment Latency (days),Max Rule Type,Max Rule Value,Min Rule Type,Min Rule Value,Buffer Stock,ASIN,Shopify Status,Walmart WPID,Archived At,Created At,Updated At\n4521,WIDGET-BLUE-01,B0B12345XY,Blue Widget - 2 Pack,WIDGET-BLUE,Blue Widget,Amazon,Amazon US,24.99,120,No,Inherited,sku.io,No,\"Main Warehouse, East Coast FC\",2,Fixed Allocation,100,None,,10,B0B12345XY,,,,2025-11-02T09:14:33.000000Z,2026-07-06T02:15:44.000000Z\n"}]},{"name":"Download Inventory Settings Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/inventory-settings-import-template","host":["{{baseUrl}}"],"path":["api","v2","listings","inventory-settings-import-template"]},"description":"Downloads an XLSX import template for bulk-editing listing inventory settings via spreadsheet import.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe workbook contains sample rows (a full settings override, a partial update, and a reset-to-inherit example) plus a reference sheet listing the valid values for your account: warehouse names, connected channel names, master-of-stock values (sku.io, sales_channel, neither), rule types (None, Fixed Allocation, % of Available), and up to 50 sample listing SKUs.\n\nThe response is a file download with Content-Type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and a filename of the form listing-inventory-settings-import-template-YYYY-MM-DD.xlsx.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/inventory-settings-import-template","host":["{{baseUrl}}"],"path":["api","v2","listings","inventory-settings-import-template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file download)"}]},{"name":"List Listing Inventory Caches","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/{productListing}/inventory-caches","host":["{{baseUrl}}"],"path":["api","v2","listings",":productListing","inventory-caches"],"variable":[{"key":"productListing","value":"4521","description":"Product listing ID"}]},"description":"Returns the per-location channel inventory records for a single listing, ordered by channel location ID. Each record compares the quantity calculated by SKU.io (sku_quantity) against the quantity last reported by the sales channel (sales_channel_quantity) and includes the variance.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nlocation_name is resolved from the channel account's configured inventory locations and is null when the location is not configured there. variance is null when the channel has never reported a quantity.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/{productListing}/inventory-caches","host":["{{baseUrl}}"],"path":["api","v2","listings",":productListing","inventory-caches"],"variable":[{"key":"productListing","value":"4521","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"sales_channel_location_id\": \"12345678\",\n      \"location_name\": \"Default Location\",\n      \"sku_quantity\": 120,\n      \"sales_channel_quantity\": 118,\n      \"variance\": 2,\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-07-06T02:15:44.000000Z\",\n      \"sales_channel_quantity_synced_at\": \"2026-07-05T14:22:10.000000Z\"\n    },\n    {\n      \"id\": 88214,\n      \"sales_channel_location_id\": \"87654321\",\n      \"location_name\": \"East Coast FC\",\n      \"sku_quantity\": 45,\n      \"sales_channel_quantity\": null,\n      \"variance\": null,\n      \"is_sku_recalculation_needed\": true,\n      \"sku_quantity_updated_at\": \"2026-07-06T02:15:44.000000Z\",\n      \"sales_channel_quantity_synced_at\": null\n    }\n  ]\n}"}]},{"name":"Preview Bulk Listing Inventory Settings Update","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-edit-inventory-preview","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-edit-inventory-preview"]},"description":"Dry run for Bulk Update Listing Inventory Settings. Computes exactly which listings would change and what each field's old and new values would be, without applying anything. Use it to validate a bulk update before committing it.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (required, array of integers) — listing IDs to evaluate\n- inventory_settings (required, object) — the settings that would be applied\n\ninventory_settings fields (all optional within the object):\n- inherit (boolean) — when true, clears all listing-level overrides so the listing inherits settings from its channel account; all other settings fields are ignored\n- master_of_stock (string|null) — one of: sku.io, sales_channel, amazon, neither\n- warehouse_ids (array of integers|null) — warehouse IDs used for the listing's available quantity\n- warehouse_action (string) — how warehouse_ids are applied: replace (default), add, or clear\n- fulfillment_latency (integer|null, 0-30) — handling time in days\n- max_rule_type (string|null) — one of: None, Fixed Allocation, % of Available\n- max_rule_value (number|null, min 0) — value paired with max_rule_type\n- min_rule_type (string|null) — one of: None, Fixed Allocation, % of Available\n- min_rule_value (number|null, min 0) — value paired with min_rule_type\n- subtract_buffer_stock (integer|null, min 0) — buffer quantity subtracted from availability\n\nFBA listings are excluded from the evaluation (their inventory is managed by the fulfillment network); the count of excluded listings is returned as skipped_fba. Listings whose settings already match report no changes and are not included in the changes array.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4521,\n    4522,\n    4523\n  ],\n  \"inventory_settings\": {\n    \"inherit\": false,\n    \"master_of_stock\": \"sku.io\",\n    \"warehouse_ids\": [\n      1,\n      4\n    ],\n    \"warehouse_action\": \"replace\",\n    \"fulfillment_latency\": 2,\n    \"max_rule_type\": \"Fixed Allocation\",\n    \"max_rule_value\": 100,\n    \"min_rule_type\": \"None\",\n    \"min_rule_value\": null,\n    \"subtract_buffer_stock\": 10\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-edit-inventory-preview","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-edit-inventory-preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_listings\": 3,\n    \"affected_listings\": 2,\n    \"skipped_fba\": 1,\n    \"changes\": [\n      {\n        \"id\": 4521,\n        \"listing_sku\": \"WIDGET-BLUE-01\",\n        \"title\": \"Blue Widget - 2 Pack\",\n        \"changes\": [\n          {\n            \"field\": \"Master of Stock\",\n            \"old_value\": \"Not set\",\n            \"new_value\": \"SKU.io\"\n          },\n          {\n            \"field\": \"Fulfillment Latency\",\n            \"old_value\": \"Not set\",\n            \"new_value\": \"2 days\"\n          },\n          {\n            \"field\": \"Warehouses\",\n            \"old_value\": \"0 warehouse(s)\",\n            \"new_value\": \"2 warehouse(s) (Replace)\"\n          },\n          {\n            \"field\": \"Max Rule\",\n            \"old_value\": \"None\",\n            \"new_value\": \"Fixed Allocation: 100\"\n          },\n          {\n            \"field\": \"Buffer Stock\",\n            \"old_value\": \"0\",\n            \"new_value\": \"10\"\n          }\n        ]\n      },\n      {\n        \"id\": 4522,\n        \"listing_sku\": \"WIDGET-RED-01\",\n        \"title\": \"Red Widget - 2 Pack\",\n        \"changes\": [\n          {\n            \"field\": \"Master of Stock\",\n            \"old_value\": \"Sales Channel\",\n            \"new_value\": \"SKU.io\"\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Update Listing Inventory Settings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-update-inventory-settings","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-update-inventory-settings"]},"description":"Applies inventory settings to many listings at once. Runs synchronously — the response reports the number of listings updated.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargeting (one of):\n- ids (array of integers, required unless apply_to_all is true) — explicit listing IDs\n- apply_to_all: true — target every listing matching the optional filters object: search (listing SKU / title / channel listing ID), integration_id, is_fba (true/false). Only non-archived listings are targeted in this mode.\n\ninventory_settings (required, object):\ninventory_settings fields (all optional within the object):\n- inherit (boolean) — when true, clears all listing-level overrides so the listing inherits settings from its channel account; all other settings fields are ignored\n- master_of_stock (string|null) — one of: sku.io, sales_channel, amazon, neither\n- warehouse_ids (array of integers|null) — warehouse IDs used for the listing's available quantity\n- warehouse_action (string) — how warehouse_ids are applied: replace (default), add, or clear\n- fulfillment_latency (integer|null, 0-30) — handling time in days\n- max_rule_type (string|null) — one of: None, Fixed Allocation, % of Available\n- max_rule_value (number|null, min 0) — value paired with max_rule_type\n- min_rule_type (string|null) — one of: None, Fixed Allocation, % of Available\n- min_rule_value (number|null, min 0) — value paired with min_rule_type\n- subtract_buffer_stock (integer|null, min 0) — buffer quantity subtracted from availability\n\nBehavior notes:\n- Only the fields present in inventory_settings are changed; omitted fields keep their current values.\n- inherit: true is destructive — it deletes all listing-level overrides so the listing inherits from its channel account; any other settings sent alongside it are ignored.\n- warehouse_action controls how warehouse_ids merge with existing selections: replace (default) overwrites, add unions, clear empties the selection.\n- FBA listings are always skipped (their inventory is managed by the fulfillment network) and do not count toward the affected total.\n\nUse Preview Bulk Listing Inventory Settings Update first for a dry run of the same payload.\n\nAuthentication: Requires Bearer token.\n\nNote: inventory_settings.inherit = true resets the listing's inventory overrides but PRESERVES any per-listing FBM Backup rule (inventory_rules.fbmBackup) — that rule is orthogonal to inventory inheritance.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4521,\n    4522,\n    4523\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"search\": \"WIDGET\",\n    \"integration_id\": 3,\n    \"is_fba\": false\n  },\n  \"inventory_settings\": {\n    \"inherit\": false,\n    \"master_of_stock\": \"sku.io\",\n    \"warehouse_ids\": [\n      1,\n      4\n    ],\n    \"warehouse_action\": \"replace\",\n    \"fulfillment_latency\": 2,\n    \"max_rule_type\": \"Fixed Allocation\",\n    \"max_rule_value\": 100,\n    \"min_rule_type\": \"None\",\n    \"min_rule_value\": null,\n    \"subtract_buffer_stock\": 10\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listings/bulk-update-inventory-settings","host":["{{baseUrl}}"],"path":["api","v2","listings","bulk-update-inventory-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Updated inventory settings for 2 listing(s).\",\n  \"data\": {\n    \"affected\": 2\n  }\n}"}]},{"name":"Trigger Channel Inventory Recalculation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/trigger-recalc","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","trigger-recalc"]},"description":"Flags channel inventory records for quantity recalculation. This is asynchronous: the request only marks the records; the quantities are recalculated by a scheduled background process on its next cycle, not immediately within this request.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargeting modes (checked in this order):\n- apply_to_all: true — flag every record matching the optional filters object (search, integration_instance_id, integration_id, is_sku_recalculation_needed). Archived listings are excluded.\n- product_listing_ids (array of integers) — flag all channel inventory records belonging to the given listing IDs.\n- ids (array of integers) — flag specific channel inventory record IDs.\n\nAll body fields are optional, but supply at least one targeting mode; otherwise 0 records are affected.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    88213,\n    88214\n  ],\n  \"product_listing_ids\": [\n    4521\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"search\": \"WIDGET\",\n    \"integration_instance_id\": 7,\n    \"integration_id\": 3,\n    \"is_sku_recalculation_needed\": false\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listings/channel-inventory/trigger-recalc","host":["{{baseUrl}}"],"path":["api","v2","listings","channel-inventory","trigger-recalc"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Marked 3 record(s) for recalculation.\",\n  \"data\": {\n    \"affected\": 3\n  }\n}"}]},{"name":"Get Product Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]},"description":"Returns a single product listing with its sales channel, integration, pricing tier, inventory cache, and document relations loaded. The integration-specific resource class is used based on the sales channel.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFBM Backup Mode (Amazon MFN listings only): send inventory_rules.fbmBackup = { inherit: bool, enabled: bool, fbaThreshold: int>=0, scope: \"same_country\"|\"all_marketplaces\" }. inherit:true (or omitting fbmBackup) inherits the Amazon integration default; inherit:false is a per-listing override. The response fbm_backup carries the EFFECTIVE config, `inherited` (bool), the `integration_default`, and (when effectively enabled) the live gate status. Enabling an override on a non-Amazon or FBA listing returns 422. fbm_backup is null only for non-Amazon-MFN listings."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"product_sku\": \"WIDGET-001\",\n    \"product_name\": \"Premium Widget\",\n    \"channel_name\": \"Amazon US - Main\",\n    \"integration_name\": \"amazon\",\n    \"integration_instance_id\": 2,\n    \"listing_sku\": \"WIDGET-001-MFN\",\n    \"sales_channel_listing_id\": \"B0EXAMPLE12\",\n    \"document_id\": 4501,\n    \"listing_url\": \"https://www.amazon.com/dp/B0EXAMPLE12?psc=1\",\n    \"title\": \"Premium Widget\",\n    \"price\": 149.99,\n    \"is_fba\": false,\n    \"price_inherit\": false,\n    \"master_of_price\": \"sku.io\",\n    \"pricing_tier_id\": 2,\n    \"pricing_tier_name\": \"Retail\",\n    \"master_of_price_override\": \"sku.io\",\n    \"product_pricing_tier_id_override\": 2,\n    \"stock_inherit\": true,\n    \"master_of_stock\": \"sku.io\",\n    \"fulfillment_latency\": 2,\n    \"inventory_rules\": {\n      \"fbmBackup\": {\n        \"inherit\": false,\n        \"enabled\": true,\n        \"fbaThreshold\": 0,\n        \"scope\": \"same_country\"\n      }\n    },\n    \"sales_channel_settings\": {\n      \"inventory\": {\n        \"masterOfStock\": \"sku.io\",\n        \"selectedWarehouses\": [\n          1,\n          2\n        ],\n        \"fulfillmentLatency\": 2\n      }\n    },\n    \"inventory_caches\": [\n      {\n        \"id\": 901,\n        \"sales_channel_location_id\": 0,\n        \"sku_quantity\": 50,\n        \"sales_channel_quantity\": 0,\n        \"is_sku_recalculation_needed\": false,\n        \"sku_quantity_updated_at\": \"2026-07-16T10:00:00.000000Z\",\n        \"sales_channel_quantity_updated_at\": \"2026-07-16T10:04:00.000000Z\",\n        \"sales_channel_quantity_synced_at\": \"2026-07-16T10:04:00.000000Z\"\n      }\n    ],\n    \"quantity\": 50,\n    \"fbm_backup\": {\n      \"enabled\": true,\n      \"fba_threshold\": 0,\n      \"scope\": \"same_country\",\n      \"inherited\": false,\n      \"integration_default\": {\n        \"enabled\": true,\n        \"fbaThreshold\": 0,\n        \"scope\": \"same_country\"\n      },\n      \"gate_active\": true,\n      \"fba_available_total\": 142,\n      \"pushed_quantity\": 0,\n      \"warning\": null,\n      \"fba_listings\": [\n        {\n          \"listing_id\": 4512,\n          \"listing_sku\": \"WIDGET-001-FBA\",\n          \"country_code\": \"US\",\n          \"available\": 142\n        }\n      ]\n    },\n    \"archived_at\": null,\n    \"created_at\": \"2026-01-15T08:30:00.000000Z\",\n    \"updated_at\": \"2026-07-16T10:04:00.000000Z\"\n  }\n}"}]},{"name":"Update Product Listing","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]},"description":"Updates a product listing. If master_of_price or product_pricing_tier_id change, the price is pushed to the sales channel.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nmaster_of_price / master_of_stock accept sku.io, sales_channel, or neither (null inherits). The effective master_of_stock is driven by inventory_rules.masterOfStock.\n\nAuthentication: Requires Bearer token.\n\nFBM Backup Mode (Amazon MFN listings only): send inventory_rules.fbmBackup = { inherit: bool, enabled: bool, fbaThreshold: int>=0, scope: \"same_country\"|\"all_marketplaces\" }. inherit:true (or omitting fbmBackup) inherits the Amazon integration default; inherit:false is a per-listing override. The response fbm_backup carries the EFFECTIVE config, `inherited` (bool), the `integration_default`, and (when effectively enabled) the live gate status. Enabling an override on a non-Amazon or FBA listing returns 422. fbm_backup is null only for non-Amazon-MFN listings.\n\nInventory modification rules: send inventory_rules.inventoryModificationRules = { maxRuleType: string, maxRuleTypeValue: numeric|null, minRuleType: string, minRuleTypeValue: numeric|null, subtractBufferStock: numeric|null }. All value fields are nullable; subtractBufferStock subtracts a buffer from the quantity pushed to the channel (null/0 = no buffer).","body":{"mode":"raw","raw":"{\n  \"master_of_price\": \"sku.io\",\n  \"product_pricing_tier_id\": 2,\n  \"inventory_rules\": {\n    \"masterOfStock\": \"sku.io\",\n    \"selectedWarehouses\": [\n      1,\n      2\n    ],\n    \"inventoryModificationRules\": {\n      \"maxRuleType\": \"None\",\n      \"maxRuleTypeValue\": null,\n      \"minRuleType\": \"None\",\n      \"minRuleTypeValue\": null,\n      \"subtractBufferStock\": null\n    },\n    \"fbmBackup\": {\n      \"inherit\": false,\n      \"enabled\": true,\n      \"fbaThreshold\": 0,\n      \"scope\": \"same_country\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product listing updated successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"product_sku\": \"WIDGET-001\",\n    \"product_name\": \"Premium Widget\",\n    \"channel_name\": \"Amazon US - Main\",\n    \"integration_name\": \"amazon\",\n    \"integration_instance_id\": 2,\n    \"listing_sku\": \"WIDGET-001-MFN\",\n    \"sales_channel_listing_id\": \"B0EXAMPLE12\",\n    \"document_id\": 4501,\n    \"listing_url\": \"https://www.amazon.com/dp/B0EXAMPLE12?psc=1\",\n    \"title\": \"Premium Widget\",\n    \"price\": 149.99,\n    \"is_fba\": false,\n    \"price_inherit\": false,\n    \"master_of_price\": \"sku.io\",\n    \"pricing_tier_id\": 2,\n    \"pricing_tier_name\": \"Retail\",\n    \"master_of_price_override\": \"sku.io\",\n    \"product_pricing_tier_id_override\": 2,\n    \"stock_inherit\": false,\n    \"master_of_stock\": \"sku.io\",\n    \"fulfillment_latency\": null,\n    \"inventory_rules\": {\n      \"masterOfStock\": \"sku.io\",\n      \"selectedWarehouses\": [\n        1,\n        2\n      ],\n      \"inventoryModificationRules\": {\n        \"maxRuleType\": \"None\",\n        \"maxRuleTypeValue\": null,\n        \"minRuleType\": \"None\",\n        \"minRuleTypeValue\": null,\n        \"subtractBufferStock\": null\n      },\n      \"fbmBackup\": {\n        \"inherit\": false,\n        \"enabled\": true,\n        \"fbaThreshold\": 0,\n        \"scope\": \"same_country\"\n      }\n    },\n    \"sales_channel_settings\": {\n      \"inventory\": {\n        \"masterOfStock\": \"sku.io\",\n        \"selectedWarehouses\": [\n          1,\n          2\n        ],\n        \"fulfillmentLatency\": 2\n      }\n    },\n    \"inventory_caches\": [\n      {\n        \"id\": 901,\n        \"sales_channel_location_id\": 0,\n        \"sku_quantity\": 50,\n        \"sales_channel_quantity\": 0,\n        \"is_sku_recalculation_needed\": false,\n        \"sku_quantity_updated_at\": \"2026-07-16T10:00:00.000000Z\",\n        \"sales_channel_quantity_updated_at\": \"2026-07-16T10:04:00.000000Z\",\n        \"sales_channel_quantity_synced_at\": \"2026-07-16T10:04:00.000000Z\"\n      }\n    ],\n    \"quantity\": 50,\n    \"fbm_backup\": {\n      \"enabled\": true,\n      \"fba_threshold\": 0,\n      \"scope\": \"same_country\",\n      \"inherited\": false,\n      \"integration_default\": {\n        \"enabled\": true,\n        \"fbaThreshold\": 0,\n        \"scope\": \"same_country\"\n      },\n      \"gate_active\": true,\n      \"fba_available_total\": 142,\n      \"pushed_quantity\": 0,\n      \"warning\": null,\n      \"fba_listings\": [\n        {\n          \"listing_id\": 4512,\n          \"listing_sku\": \"WIDGET-001-FBA\",\n          \"country_code\": \"US\",\n          \"available\": 142\n        }\n      ]\n    },\n    \"archived_at\": null,\n    \"created_at\": \"2026-01-15T08:30:00.000000Z\",\n    \"updated_at\": \"2026-07-16T10:04:00.000000Z\"\n  }\n}"}]},{"name":"List Drafts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts"],"query":[{"key":"page","value":"1","description":"Page number.","disabled":true},{"key":"per_page","value":"25","description":"Items per page (max 100, default 25).","disabled":true}]},"description":"Paginated listing drafts for the drafts list. Slim payload — the heavy `fields[]` array is only served by show/update/validate.\n\nSearch covers draft ID, product name/SKU, and channel name (resolved through the channel's integration instance). Advanced `filter_groups` trees support nested AND/OR groups over the columns listed on the parameter.\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts"],"query":[{"key":"page","value":"1","description":"Page number.","disabled":true},{"key":"per_page","value":"25","description":"Items per page (max 100, default 25).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 181,\n      \"product_id\": 99,\n      \"sales_channel_id\": 34,\n      \"sales_channel_category_id\": 26,\n      \"sales_channel_product_template_id\": null,\n      \"sales_channel_listing_profile_id\": null,\n      \"product_listing_id\": null,\n      \"purpose\": \"create\",\n      \"state\": \"ready\",\n      \"scheduled_at\": null,\n      \"image_urls\": [],\n      \"validation_errors\": null,\n      \"channel_errors\": null,\n      \"published_at\": null,\n      \"created_at\": \"2026-07-06T05:16:00+00:00\",\n      \"updated_at\": \"2026-07-06T07:19:00+00:00\",\n      \"product\": {\n        \"id\": 99,\n        \"name\": \"Tiny Threads Cardigan\",\n        \"sku\": \"TT019\"\n      },\n      \"sales_channel\": {\n        \"id\": 34,\n        \"name\": \"BigCommerce2\",\n        \"integration_name\": \"BigCommerce\"\n      },\n      \"category\": {\n        \"id\": 26,\n        \"name\": \"General (Baseline)\",\n        \"path\": \"General (Baseline)\",\n        \"external_id\": \"23\"\n      },\n      \"variation_theme\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 11,\n  \"per_page\": 25,\n  \"total\": 259,\n  \"from\": 1,\n  \"to\": 25\n}"}]},{"name":"Create Draft","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts"]},"description":"Create a listing draft.\n\nFields:\n- `purpose` (required, `create` | `update`) — `create` builds a new-listing draft; `update` seeds a draft from an existing live listing.\n- `product_id` (required if purpose=create, integer) — product to list.\n- `sales_channel_id` (required if purpose=create, integer) — target channel.\n- `sales_channel_category_id` (nullable, integer) — channel category driving the field schema. A draft without a category records a `missing_category` validation error and stays in `draft` state — it can never reach `ready` until a category is set.\n- `sales_channel_product_template_id` (nullable, integer) — template pre-mapping category fields. Optional: a draft is fully publishable without one (fill fields via overrides).\n- `sales_channel_listing_profile_id` (nullable, integer) — channel listing profile.\n- `product_listing_id` (required if purpose=update, integer) — live listing to seed from.\n\nThe draft is resolved + validated on creation; the response includes `fields[]` (schema + resolved value + provenance + raw `override`), `resolved_values` and `validation_errors`.\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled.","body":{"mode":"raw","raw":"{\n  \"purpose\": \"create\",\n  \"product_id\": 88,\n  \"sales_channel_id\": 30,\n  \"sales_channel_category_id\": 7,\n  \"sales_channel_product_template_id\": null,\n  \"sales_channel_listing_profile_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"product_id\": 88,\n  \"sales_channel_id\": 30,\n  \"sales_channel_category_id\": 7,\n  \"sales_channel_product_template_id\": null,\n  \"sales_channel_listing_profile_id\": null,\n  \"product_listing_id\": null,\n  \"purpose\": \"create\",\n  \"state\": \"ready\",\n  \"scheduled_at\": null,\n  \"image_urls\": [\n    \"https://cdn.example.com/img/beanie-1.jpg\"\n  ],\n  \"validation_errors\": null,\n  \"channel_errors\": null,\n  \"published_at\": null,\n  \"created_at\": \"2026-07-06T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-06T12:05:00+00:00\",\n  \"product\": {\n    \"id\": 88,\n    \"name\": \"Tiny Threads Beanie\",\n    \"sku\": \"TT008\"\n  },\n  \"sales_channel\": {\n    \"id\": 30,\n    \"name\": \"eBay Store\",\n    \"integration_name\": \"Ebay\"\n  },\n  \"category\": {\n    \"id\": 7,\n    \"name\": \"Hoodies\",\n    \"path\": \"QA / Hoodies\",\n    \"external_id\": \"155184\"\n  },\n  \"template\": null,\n  \"listing_profile\": null,\n  \"variation_theme\": null,\n  \"variation_data\": null,\n  \"fields\": [\n    {\n      \"name\": \"Brand\",\n      \"label\": \"Brand\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\",\n      \"has_override\": true,\n      \"override\": {\n        \"source_type\": \"product_field\",\n        \"source_value\": \"brand\"\n      },\n      \"errors\": []\n    },\n    {\n      \"name\": \"Color\",\n      \"label\": \"Color\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Sage\",\n      \"provenance\": \"template\",\n      \"has_override\": false,\n      \"override\": null,\n      \"errors\": []\n    }\n  ],\n  \"field_overrides\": {\n    \"Brand\": {\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    }\n  },\n  \"resolved_values\": {\n    \"Brand\": {\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\"\n    },\n    \"Color\": {\n      \"value\": \"Sage\",\n      \"provenance\": \"template\"\n    }\n  }\n}"}]},{"name":"List Mappable Product Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/mappable-product-fields","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts","mappable-product-fields"]},"description":"Product columns usable as a `product_field` mapping source in draft field_overrides and template field defaults. Served from the resolver whitelist (ListingValueResolver) so pickers never offer a column the resolver won't read.\n\n`brand` resolves through the product's brand relation (ProductBrand::name); `price` resolves through the default pricing tier accessor; all other values are direct product columns.\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled.\n\nEach item includes `type` — the column's data type (`text` or `number`) — so the mapping picker can show what kind of value a column carries."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/mappable-product-fields","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts","mappable-product-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"value\": \"name\",\n      \"label\": \"Name\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"sku\",\n      \"label\": \"SKU\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"barcode\",\n      \"label\": \"Barcode (UPC / EAN)\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"mpn\",\n      \"label\": \"MPN\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"brand\",\n      \"label\": \"Brand\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"price\",\n      \"label\": \"Price (default tier)\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"weight\",\n      \"label\": \"Weight\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"weight_unit\",\n      \"label\": \"Weight unit\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"length\",\n      \"label\": \"Length\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"width\",\n      \"label\": \"Width\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"height\",\n      \"label\": \"Height\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"dimension_unit\",\n      \"label\": \"Dimension unit\",\n      \"type\": \"text\"\n    },\n    {\n      \"value\": \"case_quantity\",\n      \"label\": \"Case quantity\",\n      \"type\": \"number\"\n    },\n    {\n      \"value\": \"fba_prep_instructions\",\n      \"label\": \"FBA prep instructions\",\n      \"type\": \"text\"\n    }\n  ]\n}"}]},{"name":"Get Draft","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]},"description":"Show a draft with the full per-field payload.\n\nEach `fields[]` row merges the cached category schema with the draft's resolved value:\n- `value` — resolved value after the precedence chain (override > template > channel mapping > integration mapping > blank)\n- `provenance` — where the value came from (`override`, `template`, `channel_mapping`, `integration_mapping`, `blank`)\n- `has_override` — whether the draft overrides this field\n- `override` — the raw override: a literal value, or a mapped source object `{source_type, source_value}`\n- `errors` — validation/channel errors scoped to this field\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"product_id\": 88,\n  \"sales_channel_id\": 30,\n  \"sales_channel_category_id\": 7,\n  \"sales_channel_product_template_id\": null,\n  \"sales_channel_listing_profile_id\": null,\n  \"product_listing_id\": null,\n  \"purpose\": \"create\",\n  \"state\": \"ready\",\n  \"scheduled_at\": null,\n  \"image_urls\": [\n    \"https://cdn.example.com/img/beanie-1.jpg\"\n  ],\n  \"validation_errors\": null,\n  \"channel_errors\": null,\n  \"published_at\": null,\n  \"created_at\": \"2026-07-06T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-06T12:05:00+00:00\",\n  \"product\": {\n    \"id\": 88,\n    \"name\": \"Tiny Threads Beanie\",\n    \"sku\": \"TT008\"\n  },\n  \"sales_channel\": {\n    \"id\": 30,\n    \"name\": \"eBay Store\",\n    \"integration_name\": \"Ebay\"\n  },\n  \"category\": {\n    \"id\": 7,\n    \"name\": \"Hoodies\",\n    \"path\": \"QA / Hoodies\",\n    \"external_id\": \"155184\"\n  },\n  \"template\": null,\n  \"listing_profile\": null,\n  \"variation_theme\": null,\n  \"variation_data\": null,\n  \"fields\": [\n    {\n      \"name\": \"Brand\",\n      \"label\": \"Brand\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\",\n      \"has_override\": true,\n      \"override\": {\n        \"source_type\": \"product_field\",\n        \"source_value\": \"brand\"\n      },\n      \"errors\": []\n    },\n    {\n      \"name\": \"Color\",\n      \"label\": \"Color\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Sage\",\n      \"provenance\": \"template\",\n      \"has_override\": false,\n      \"override\": null,\n      \"errors\": []\n    }\n  ],\n  \"field_overrides\": {\n    \"Brand\": {\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    }\n  },\n  \"resolved_values\": {\n    \"Brand\": {\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\"\n    },\n    \"Color\": {\n      \"value\": \"Sage\",\n      \"provenance\": \"template\"\n    }\n  }\n}"}]},{"name":"Update Draft (overrides, images, structure)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]},"description":"Update a draft — saves `field_overrides`, `image_urls`, and structural changes (`sales_channel_category_id`, `sales_channel_product_template_id`, `sales_channel_listing_profile_id`), then re-resolves and re-validates. The draft transitions to `ready` when no validation errors remain.\n\n`field_overrides` values come in two shapes:\n- **Literal value** (string / number / bool / array for multiselect) — used verbatim, provenance `override`.\n- **Mapped source** — an object `{\"source_type\": ..., \"source_value\": ...}` that re-resolves from product data on every validate/publish. `source_type` must be one of `product_field` (whitelisted product columns — see GET /api/v2/listing-drafts/mappable-product-fields), `product_attribute` (an Attribute id), `static` (literal string), or `expression` (mustache tokens, e.g. `{{product.sku}} - {{product.name}}`). A mapped override that resolves to null stays null (no fall-through to template/mapping values) so required-field validation can flag it.\n\nPassing an invalid `source_type`, or a `source_value` that is not a scalar, returns 422.\n\nFields:\n- `field_overrides` (nullable, object) — map of field name to literal value or mapped source (see above).\n- `sales_channel_category_id` (nullable, integer)\n- `sales_channel_product_template_id` (nullable, integer)\n- `sales_channel_listing_profile_id` (nullable, integer)\n- `image_urls` (nullable, array of strings)\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled.","body":{"mode":"raw","raw":"{\n  \"field_overrides\": {\n    \"Brand\": {\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    },\n    \"Color\": \"Sage\",\n    \"Title\": {\n      \"source_type\": \"expression\",\n      \"source_value\": \"{{product.sku}} - {{product.name}}\"\n    }\n  },\n  \"image_urls\": [\n    \"https://cdn.example.com/img/beanie-1.jpg\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"product_id\": 88,\n  \"sales_channel_id\": 30,\n  \"sales_channel_category_id\": 7,\n  \"sales_channel_product_template_id\": null,\n  \"sales_channel_listing_profile_id\": null,\n  \"product_listing_id\": null,\n  \"purpose\": \"create\",\n  \"state\": \"ready\",\n  \"scheduled_at\": null,\n  \"image_urls\": [\n    \"https://cdn.example.com/img/beanie-1.jpg\"\n  ],\n  \"validation_errors\": null,\n  \"channel_errors\": null,\n  \"published_at\": null,\n  \"created_at\": \"2026-07-06T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-06T12:05:00+00:00\",\n  \"product\": {\n    \"id\": 88,\n    \"name\": \"Tiny Threads Beanie\",\n    \"sku\": \"TT008\"\n  },\n  \"sales_channel\": {\n    \"id\": 30,\n    \"name\": \"eBay Store\",\n    \"integration_name\": \"Ebay\"\n  },\n  \"category\": {\n    \"id\": 7,\n    \"name\": \"Hoodies\",\n    \"path\": \"QA / Hoodies\",\n    \"external_id\": \"155184\"\n  },\n  \"template\": null,\n  \"listing_profile\": null,\n  \"variation_theme\": null,\n  \"variation_data\": null,\n  \"fields\": [\n    {\n      \"name\": \"Brand\",\n      \"label\": \"Brand\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\",\n      \"has_override\": true,\n      \"override\": {\n        \"source_type\": \"product_field\",\n        \"source_value\": \"brand\"\n      },\n      \"errors\": []\n    },\n    {\n      \"name\": \"Color\",\n      \"label\": \"Color\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Sage\",\n      \"provenance\": \"template\",\n      \"has_override\": false,\n      \"override\": null,\n      \"errors\": []\n    }\n  ],\n  \"field_overrides\": {\n    \"Brand\": {\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    }\n  },\n  \"resolved_values\": {\n    \"Brand\": {\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\"\n    },\n    \"Color\": {\n      \"value\": \"Sage\",\n      \"provenance\": \"template\"\n    }\n  }\n}"}]},{"name":"Validate Draft","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}/validate","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft","validate"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]},"description":"Re-resolve the draft's values against current product data + mappings and re-run validation. Mapped overrides (`{source_type, source_value}`) are re-evaluated against the product on every call. State transitions to `ready` when validation passes, back to `draft` when errors appear. A draft without a category records a `missing_category` validation error.\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}/validate","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft","validate"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"product_id\": 88,\n  \"sales_channel_id\": 30,\n  \"sales_channel_category_id\": 7,\n  \"sales_channel_product_template_id\": null,\n  \"sales_channel_listing_profile_id\": null,\n  \"product_listing_id\": null,\n  \"purpose\": \"create\",\n  \"state\": \"ready\",\n  \"scheduled_at\": null,\n  \"image_urls\": [\n    \"https://cdn.example.com/img/beanie-1.jpg\"\n  ],\n  \"validation_errors\": null,\n  \"channel_errors\": null,\n  \"published_at\": null,\n  \"created_at\": \"2026-07-06T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-06T12:05:00+00:00\",\n  \"product\": {\n    \"id\": 88,\n    \"name\": \"Tiny Threads Beanie\",\n    \"sku\": \"TT008\"\n  },\n  \"sales_channel\": {\n    \"id\": 30,\n    \"name\": \"eBay Store\",\n    \"integration_name\": \"Ebay\"\n  },\n  \"category\": {\n    \"id\": 7,\n    \"name\": \"Hoodies\",\n    \"path\": \"QA / Hoodies\",\n    \"external_id\": \"155184\"\n  },\n  \"template\": null,\n  \"listing_profile\": null,\n  \"variation_theme\": null,\n  \"variation_data\": null,\n  \"fields\": [\n    {\n      \"name\": \"Brand\",\n      \"label\": \"Brand\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\",\n      \"has_override\": true,\n      \"override\": {\n        \"source_type\": \"product_field\",\n        \"source_value\": \"brand\"\n      },\n      \"errors\": []\n    },\n    {\n      \"name\": \"Color\",\n      \"label\": \"Color\",\n      \"schema\": {\n        \"type\": \"text\",\n        \"usage\": \"required\",\n        \"cardinality\": 1,\n        \"allowed_values\": null,\n        \"allows_custom_value\": true,\n        \"max_length\": null,\n        \"min_length\": null,\n        \"object_schema\": null\n      },\n      \"value\": \"Sage\",\n      \"provenance\": \"template\",\n      \"has_override\": false,\n      \"override\": null,\n      \"errors\": []\n    }\n  ],\n  \"field_overrides\": {\n    \"Brand\": {\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    }\n  },\n  \"resolved_values\": {\n    \"Brand\": {\n      \"value\": \"Tiny Threads\",\n      \"provenance\": \"override\"\n    },\n    \"Color\": {\n      \"value\": \"Sage\",\n      \"provenance\": \"template\"\n    }\n  }\n}"}]},{"name":"Preview Draft Against Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}/preview-against-product","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft","preview-against-product"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]},"description":"Resolve this draft's mappings (its template + field overrides) against a DIFFERENT product, returning the value each channel field would receive for that product — with no persistence. Useful for a \"preview against another product\" control: mapped fields (`product_field` / `product_attribute` / `expression`) re-evaluate against the given product, while typed literal values stay as-is.\n\nRequest body:\n- `product_id` (integer, required) — the product to resolve against; must exist.\n\nResponse: `data.product` echoes the previewed product, and `data.values` is keyed by channel field name, each with the resolved `value` and its `provenance` (override / template / channel_mapping / integration_mapping / channel_default / blank).\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled.","body":{"mode":"raw","raw":"{\n  \"product_id\": 87\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/listing-drafts/{draft}/preview-against-product","host":["{{baseUrl}}"],"path":["api","v2","listing-drafts",":draft","preview-against-product"],"variable":[{"key":"draft","value":"42","description":"Listing draft ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 87,\n      \"name\": \"Blue Widget - 2 Pack\",\n      \"sku\": \"WIDGET-BLUE-2PK\"\n    },\n    \"values\": {\n      \"Brand\": {\n        \"value\": \"Acme\",\n        \"provenance\": \"override\"\n      },\n      \"Color\": {\n        \"value\": \"Blue\",\n        \"provenance\": \"template\"\n      },\n      \"Size\": {\n        \"value\": null,\n        \"provenance\": \"blank\"\n      }\n    }\n  }\n}"}]},{"name":"Get Inventory for Product Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/get-inventory","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","get-inventory"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]},"description":"Returns the available inventory for a product listing across all warehouses / sales channel inventory locations.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/get-inventory","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","get-inventory"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"available\": 150,\n    \"on_hand\": 200,\n    \"allocated\": 50,\n    \"warehouses\": [\n      {\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"available\": 100\n      },\n      {\n        \"warehouse_id\": 2,\n        \"warehouse_name\": \"East Warehouse\",\n        \"available\": 50\n      }\n    ]\n  }\n}"}]},{"name":"Link to Subscription Offering","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/link-offering","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","link-offering"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]},"description":"Links a product listing to a subscription offering. Used for subscription-based sales channels.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"subscription_offering_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/link-offering","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","link-offering"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated Product Listing 1\",\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"sales_channel_id\": 5,\n    \"subscription_offering\": {\n      \"id\": 3,\n      \"name\": \"Monthly Plan\"\n    }\n  }\n}"}]},{"name":"Unlink from Subscription Offering","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/unlink-offering","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","unlink-offering"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]},"description":"Unlinks a product listing from a subscription offering.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-listings/{productListing}/unlink-offering","host":["{{baseUrl}}"],"path":["api","product-listings",":productListing","unlink-offering"],"variable":[{"key":"productListing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated Product Listing 1\",\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"sales_channel_id\": 5,\n    \"subscription_offering\": null\n  }\n}"}]},{"name":"Show Product Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-listings/{product_listing}","host":["{{baseUrl}}"],"path":["api","product-listings",":product_listing"],"variable":[{"key":"product_listing","value":"1","description":"Product listing ID"}]},"description":"Returns a single product listing with its sales channel, integration, pricing tier, inventory cache, and document relations loaded. The integration-specific resource class is used based on the sales channel.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-listings/{product_listing}","host":["{{baseUrl}}"],"path":["api","product-listings",":product_listing"],"variable":[{"key":"product_listing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"product_id\": 42,\n  \"sales_channel_id\": 5,\n  \"sales_channel_listing_id\": \"7823456789012\",\n  \"listing_sku\": \"PROD-001\",\n  \"title\": \"Premium Widget\",\n  \"master_of_price\": true,\n  \"master_of_stock\": true,\n  \"product_pricing_tier_id\": null,\n  \"sales_channel\": {\n    \"id\": 5,\n    \"name\": \"Shopify Store\",\n    \"integration_instance\": {\n      \"id\": 2,\n      \"name\": \"My Shopify\",\n      \"integration\": {\n        \"name\": \"shopify\"\n      }\n    }\n  },\n  \"inventory_cache\": {\n    \"available_quantity\": 150\n  }\n}"}]},{"name":"Update Product Listing","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-listings/{product_listing}","host":["{{baseUrl}}"],"path":["api","product-listings",":product_listing"],"variable":[{"key":"product_listing","value":"1","description":"Product listing ID"}]},"description":"Updates a product listing. If master_of_price or product_pricing_tier_id change, the price is pushed to the sales channel. If inventoryLocations is provided, inventory is synced to the channel.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"master_of_price\": true,\n  \"master_of_stock\": false,\n  \"product_pricing_tier_id\": 2,\n  \"inventoryLocations\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-listings/{product_listing}","host":["{{baseUrl}}"],"path":["api","product-listings",":product_listing"],"variable":[{"key":"product_listing","value":"1","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated Product Listing 7823456789012\",\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"sales_channel_id\": 5,\n    \"sales_channel_listing_id\": \"7823456789012\",\n    \"listing_sku\": \"PROD-001\",\n    \"master_of_price\": true,\n    \"master_of_stock\": false,\n    \"product_pricing_tier_id\": 2\n  }\n}"}]},{"name":"Get Publish-Readiness Snapshot","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/publish-readiness","host":["{{baseUrl}}"],"path":["api","v2","products",":product","publish-readiness"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Per-product, multi-channel publish readiness snapshot. Returns one entry per publish-capable, connected sales channel, grouped by bucket (live / ready / warn / idle / publishing / scheduled / draft) so the publish dialog can render confidence groups without orchestrating N parallel calls.\n\nRead-only: does NOT speculatively create drafts. Channels with no draft and no live listing land in `idle` and surface recommended next actions (pick a template, create one, etc.).\n\nBucket resolution:\n- `live` — a non-archived `ProductListing` exists for this product on the channel\n- `ready` — open draft in state `ready`\n- `scheduled` — open draft in state `scheduled`\n- `publishing` — open draft in state `publishing` or `validating`\n- `warn` — open draft in state `error`, OR `draft` with validation errors\n- `draft` — open draft in state `draft` with no validation errors\n- `idle` — no open draft and no live listing\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled.\n\n**`quantity_to_push`** (int|null, per channel entry) — the stock a publish to this channel would seed right now, computed through the same SalesChannelInventoryCalculator rules the standing inventory sync uses (max/min/buffer, locations, bundles). `null` when quantity seeding is gated off (listing-publishing `push_quantity_on_publish` setting disabled, SKU.io not master of stock for the instance, no inventory rules configured) or the bucket cannot publish (`live` / `publishing`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/publish-readiness","host":["{{baseUrl}}"],"path":["api","v2","products",":product","publish-readiness"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"channel\": {\n        \"id\": 12,\n        \"name\": \"My Shopify Store\",\n        \"integration_name\": \"Shopify\",\n        \"integration_instance_id\": 3\n      },\n      \"bucket\": \"ready\",\n      \"existing_listing\": null,\n      \"draft\": {\n        \"id\": 88,\n        \"state\": \"ready\",\n        \"sales_channel_category_id\": 41,\n        \"sales_channel_product_template_id\": 5,\n        \"sales_channel_listing_profile_id\": 2,\n        \"scheduled_at\": null,\n        \"validation_errors_count\": 0,\n        \"missing_required\": [],\n        \"template\": {\n          \"id\": 5,\n          \"name\": \"Hoodies — Standard\"\n        },\n        \"category\": {\n          \"id\": 41,\n          \"name\": \"Hoodies\",\n          \"path\": \"Apparel / Hoodies\"\n        },\n        \"updated_at\": \"2026-06-22T14:31:22+00:00\"\n      },\n      \"available_templates_count\": 3,\n      \"issues_count\": 0,\n      \"quantity_to_push\": 42\n    },\n    {\n      \"channel\": {\n        \"id\": 7,\n        \"name\": \"My eBay Store\",\n        \"integration_name\": \"Ebay\",\n        \"integration_instance_id\": 1\n      },\n      \"bucket\": \"warn\",\n      \"existing_listing\": null,\n      \"draft\": {\n        \"id\": 92,\n        \"state\": \"draft\",\n        \"sales_channel_category_id\": 318,\n        \"sales_channel_product_template_id\": 11,\n        \"sales_channel_listing_profile_id\": null,\n        \"scheduled_at\": null,\n        \"validation_errors_count\": 3,\n        \"missing_required\": [\n          {\n            \"field\": \"Brand\",\n            \"label\": \"Item Specifics: Brand\"\n          },\n          {\n            \"field\": \"Condition\",\n            \"label\": \"Item Condition\"\n          },\n          {\n            \"field\": \"Color\",\n            \"label\": \"Color\"\n          }\n        ],\n        \"template\": {\n          \"id\": 11,\n          \"name\": \"eBay Hoodie — Default\"\n        },\n        \"category\": {\n          \"id\": 318,\n          \"name\": \"Hoodies\",\n          \"path\": \"Clothing / Men / Hoodies\"\n        },\n        \"updated_at\": \"2026-06-22T14:18:04+00:00\"\n      },\n      \"available_templates_count\": 2,\n      \"issues_count\": 3,\n      \"quantity_to_push\": 42\n    },\n    {\n      \"channel\": {\n        \"id\": 22,\n        \"name\": \"Walmart US\",\n        \"integration_name\": \"Walmart\",\n        \"integration_instance_id\": 5\n      },\n      \"bucket\": \"idle\",\n      \"existing_listing\": null,\n      \"draft\": null,\n      \"available_templates_count\": 0,\n      \"issues_count\": 0,\n      \"quantity_to_push\": 42\n    },\n    {\n      \"channel\": {\n        \"id\": 4,\n        \"name\": \"Etsy\",\n        \"integration_name\": \"Etsy\",\n        \"integration_instance_id\": 2\n      },\n      \"bucket\": \"live\",\n      \"existing_listing\": {\n        \"id\": 9412,\n        \"sales_channel_listing_id\": \"1394820392\",\n        \"listing_sku\": \"AC-HOODIE-BLK-M\",\n        \"updated_at\": \"2026-06-22T14:27:11+00:00\"\n      },\n      \"draft\": null,\n      \"available_templates_count\": 0,\n      \"issues_count\": 0,\n      \"quantity_to_push\": null\n    }\n  ]\n}"}]},{"name":"Get Catalog Coverage Matrix","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/listings/coverage","host":["{{baseUrl}}"],"path":["api","v2","listings","coverage"]},"description":"Catalog-wide publish coverage matrix. Returns a paginated list of products with per-channel publish state (bucket) for each publish-capable connected channel. Returns catalog-wide publish coverage per product across channels.\n\n**One row per product**, with `channels[]` listing all publish-capable channels and their current bucket (`live` / `ready` / `warn` / `idle` / `scheduled` / `publishing` / `draft`). The `channel_buckets` map is a convenience for matrix cell rendering (channel_id → bucket string).\n\n`totals` aggregates bucket counts across the ENTIRE catalog (every product × publish-capable channel) — this is what the summary cards above the matrix display. `page_totals` is the same aggregation scoped to only the products on the current page (retained for page-level tallies).\n\nAuthentication: Requires Bearer token.\nFeature flag: requires `listing-publishing` to be enabled. `channel_totals` breaks the same catalog-wide counts down per channel — each entry lists the channel (channel_id, name, integration_name), its total product count, and a count in each status bucket."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/listings/coverage","host":["{{baseUrl}}"],"path":["api","v2","listings","coverage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product\": {\n        \"id\": 4,\n        \"sku\": \"BB004\",\n        \"name\": \"Baby Bumble Hoodie\",\n        \"brand\": \"Baby Bumble\",\n        \"primary_image_url\": \"https://cdn.example.com/img/beanie-1.jpg\",\n        \"product_type\": \"bundle\",\n        \"is_bundle\": true,\n        \"bundle_component_count\": 3\n      },\n      \"channels\": [\n        {\n          \"channel\": {\n            \"id\": 3,\n            \"name\": \"My Shopify Store\",\n            \"integration_name\": \"Shopify\",\n            \"integration_instance_id\": 1\n          },\n          \"bucket\": \"live\",\n          \"existing_listing\": {\n            \"id\": 9412,\n            \"sales_channel_listing_id\": \"abc123\",\n            \"listing_sku\": \"BB004\",\n            \"updated_at\": \"2026-06-22T14:27:11+00:00\"\n          },\n          \"draft\": null,\n          \"available_templates_count\": 2,\n          \"issues_count\": 0\n        },\n        {\n          \"channel\": {\n            \"id\": 25,\n            \"name\": \"Amazon\",\n            \"integration_name\": \"Amazon\",\n            \"integration_instance_id\": 3\n          },\n          \"bucket\": \"ready\",\n          \"existing_listing\": null,\n          \"draft\": {\n            \"id\": 88,\n            \"state\": \"ready\",\n            \"sales_channel_category_id\": 41,\n            \"sales_channel_product_template_id\": 5,\n            \"sales_channel_listing_profile_id\": null,\n            \"scheduled_at\": null,\n            \"validation_errors_count\": 0,\n            \"missing_required\": [],\n            \"template\": {\n              \"id\": 5,\n              \"name\": \"Amazon Hoodie — FBA\"\n            },\n            \"category\": {\n              \"id\": 41,\n              \"name\": \"Hoodies\",\n              \"path\": \"Apparel / Hoodies\"\n            },\n            \"updated_at\": \"2026-06-22T14:31:22+00:00\"\n          },\n          \"available_templates_count\": 4,\n          \"issues_count\": 0\n        },\n        {\n          \"channel\": {\n            \"id\": 30,\n            \"name\": \"eBay Store\",\n            \"integration_name\": \"Ebay\",\n            \"integration_instance_id\": 1\n          },\n          \"bucket\": \"warn\",\n          \"existing_listing\": null,\n          \"draft\": {\n            \"id\": 92,\n            \"state\": \"draft\",\n            \"sales_channel_category_id\": 318,\n            \"sales_channel_product_template_id\": 11,\n            \"sales_channel_listing_profile_id\": null,\n            \"scheduled_at\": null,\n            \"validation_errors_count\": 3,\n            \"missing_required\": [\n              {\n                \"field\": \"Brand\",\n                \"label\": \"Brand\"\n              },\n              {\n                \"field\": \"Color\",\n                \"label\": \"Color\"\n              },\n              {\n                \"field\": \"Item_Condition\",\n                \"label\": \"Item Condition\"\n              }\n            ],\n            \"template\": {\n              \"id\": 11,\n              \"name\": \"eBay Hoodie — Default\"\n            },\n            \"category\": {\n              \"id\": 318,\n              \"name\": \"Hoodies\",\n              \"path\": \"Clothing / Men / Hoodies\"\n            },\n            \"updated_at\": \"2026-06-22T14:18:04+00:00\"\n          },\n          \"available_templates_count\": 2,\n          \"issues_count\": 3\n        },\n        {\n          \"channel\": {\n            \"id\": 26,\n            \"name\": \"Walmart US\",\n            \"integration_name\": \"Walmart\",\n            \"integration_instance_id\": 5\n          },\n          \"bucket\": \"idle\",\n          \"existing_listing\": null,\n          \"draft\": null,\n          \"available_templates_count\": 0,\n          \"issues_count\": 0\n        }\n      ],\n      \"channel_buckets\": {\n        \"3\": \"live\",\n        \"25\": \"ready\",\n        \"26\": \"idle\",\n        \"30\": \"warn\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 11,\n  \"per_page\": 20,\n  \"total\": 218,\n  \"from\": 1,\n  \"to\": 20,\n  \"first_page_url\": \"https://example.test/api/v2/listings/coverage?page=1\",\n  \"last_page_url\": \"https://example.test/api/v2/listings/coverage?page=11\",\n  \"next_page_url\": \"https://example.test/api/v2/listings/coverage?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/v2/listings/coverage\",\n  \"totals\": {\n    \"live\": 130,\n    \"ready\": 18,\n    \"warn\": 22,\n    \"idle\": 46,\n    \"scheduled\": 2,\n    \"publishing\": 0,\n    \"draft\": 0\n  },\n  \"page_totals\": {\n    \"live\": 41,\n    \"ready\": 6,\n    \"warn\": 8,\n    \"idle\": 25,\n    \"scheduled\": 0,\n    \"publishing\": 0,\n    \"draft\": 0\n  },\n  \"channel_totals\": [\n    {\n      \"channel_id\": 3,\n      \"name\": \"My Shopify Store\",\n      \"integration_name\": \"Shopify\",\n      \"total\": 109,\n      \"live\": 78,\n      \"ready\": 9,\n      \"removed\": 0,\n      \"warn\": 11,\n      \"idle\": 10,\n      \"scheduled\": 1,\n      \"publishing\": 0,\n      \"draft\": 0\n    },\n    {\n      \"channel_id\": 5,\n      \"name\": \"My eBay Store\",\n      \"integration_name\": \"eBay\",\n      \"total\": 109,\n      \"live\": 41,\n      \"ready\": 6,\n      \"removed\": 0,\n      \"warn\": 8,\n      \"idle\": 53,\n      \"scheduled\": 1,\n      \"publishing\": 0,\n      \"draft\": 0\n    }\n  ]\n}"}]},{"name":"List Channels for Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/channels?product_ids[]=1","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","channels"],"query":[{"key":"product_ids[]","value":"1","description":"Product id to include (repeat for each product). Required.","disabled":true}]},"description":"List the sales channels the given products are currently listed on, with how many of the selected products are listed vs not listed on each channel, and whether the channel supports bulk archive / recover / delete.\n\nUse this to build a channel picker before running a bulk channel action. Pass the product ids you want to act on as a repeated `product_ids[]` query parameter.\n\n`supports_archive` is true when the channel can deactivate a listing; `supports_lifecycle` is true when it can also recover (reactivate/restore) and permanently delete a listing. TikTok Shop is the first channel to support the full lifecycle.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/channels?product_ids[]=1","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","channels"],"query":[{"key":"product_ids[]","value":"1","description":"Product id to include (repeat for each product). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_selected\": 2,\n    \"channels\": [\n      {\n        \"sales_channel_id\": 5,\n        \"integration_instance_id\": 12,\n        \"name\": \"TikTok Shop — US\",\n        \"integration_name\": \"TikTok Shop\",\n        \"integration_image_url\": \"https://cdn.sku.io/integrations/tiktok-shop.png\",\n        \"listed_count\": 2,\n        \"not_listed_count\": 0,\n        \"supports_archive\": true,\n        \"supports_lifecycle\": true\n      },\n      {\n        \"sales_channel_id\": 3,\n        \"integration_instance_id\": 7,\n        \"name\": \"Shopify — US\",\n        \"integration_name\": \"Shopify\",\n        \"integration_image_url\": \"https://cdn.sku.io/integrations/shopify.png\",\n        \"listed_count\": 1,\n        \"not_listed_count\": 1,\n        \"supports_archive\": true,\n        \"supports_lifecycle\": false\n      }\n    ]\n  }\n}"}]},{"name":"Get Channel Action Eligibility","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/eligibility?sales_channel_id=5&product_ids[]=1","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","eligibility"],"query":[{"key":"sales_channel_id","value":"5","description":"The sales channel to evaluate against. Required.","disabled":true},{"key":"product_ids[]","value":"1","description":"Product id to include (repeat for each product). Required.","disabled":true}]},"description":"Return the per-state breakdown of the selected products on a single sales channel plus, for each action, how many products are eligible and whether the channel supports it.\n\n`breakdown` counts the selected products by their state on the channel: `live`, `pending`, `archived`, `missing`, `unknown`, and `not_listed`. Each entry in `actions` reports the action (`publish`, `archive`, `recover`, `delete`), its `eligible_count`, whether it is `destructive`, whether it runs as a bulk background action here (`dispatchable`), and whether the channel `supported` it.\n\nOnly archive, recover and delete are dispatchable; publish is handled by the bulk publish flow.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/eligibility?sales_channel_id=5&product_ids[]=1","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","eligibility"],"query":[{"key":"sales_channel_id","value":"5","description":"The sales channel to evaluate against. Required.","disabled":true},{"key":"product_ids[]","value":"1","description":"Product id to include (repeat for each product). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_selected\": 60,\n    \"breakdown\": {\n      \"live\": 42,\n      \"pending\": 0,\n      \"archived\": 6,\n      \"missing\": 0,\n      \"unknown\": 0,\n      \"not_listed\": 12\n    },\n    \"actions\": [\n      {\n        \"action\": \"publish\",\n        \"label\": \"Publish\",\n        \"eligible_count\": 12,\n        \"destructive\": false,\n        \"dispatchable\": false,\n        \"supported\": true\n      },\n      {\n        \"action\": \"archive\",\n        \"label\": \"Archive\",\n        \"eligible_count\": 42,\n        \"destructive\": false,\n        \"dispatchable\": true,\n        \"supported\": true\n      },\n      {\n        \"action\": \"recover\",\n        \"label\": \"Recover\",\n        \"eligible_count\": 6,\n        \"destructive\": false,\n        \"dispatchable\": true,\n        \"supported\": true\n      },\n      {\n        \"action\": \"delete\",\n        \"label\": \"Delete\",\n        \"eligible_count\": 48,\n        \"destructive\": true,\n        \"dispatchable\": true,\n        \"supported\": true\n      }\n    ]\n  }\n}"}]},{"name":"Run Bulk Channel Action","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/dispatch","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","dispatch"]},"description":"Run a bulk channel action (archive, recover or delete) against the eligible listings of the selected products on a sales channel. The action runs in the background and the response returns a `tracked_job_log_id` you can poll for progress and a per-product success/failure summary.\n\nOnly `archive`, `recover` and `delete` are accepted here — publishing new listings uses the bulk publish flow. Products with no eligible listing for the chosen action are skipped; the request returns 422 when none of the selected products are eligible.\n\n- `archive` deactivates the listing on the channel (reversible).\n- `recover` reactivates an archived listing or restores a deleted one.\n- `delete` permanently removes the listing from the channel.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sales_channel_id\": 5,\n  \"action\": \"archive\",\n  \"product_ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/channel-lifecycle/dispatch","host":["{{baseUrl}}"],"path":["api","v2","products","channel-lifecycle","dispatch"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9174\n  },\n  \"message\": \"Bulk Archive started — track progress with the tracked job log id.\"\n}"}]}]},{"name":"Sales Credits","item":[{"name":"List Sales Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-credits?page=1&limit=10&sort=&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","v2","sales-credits"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"","description":"Sort field and direction (prefix with - for descending). Common fields: id, credit_date, sales_credit_number, created_at, updated_at, archived_at","disabled":true},{"key":"search","value":"","description":"Full-text search across sales credit number, customer name, order number, SKU","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"IDs to force include in results","disabled":true},{"key":"excluded[]","value":"","description":"IDs to force exclude from results","disabled":true}]},"description":"Returns a paginated list of sales credits using the standard list interface. Supports search, archiving filter, and column selection.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThis endpoint uses the standard list interface. Common filters are passed as query parameters directly.\n\nResponse is wrapped with table_specifications metadata when table_specifications parameter is provided.\n\nTotals fields:\n- total: total credit amount\n- refund_payments_total: sum of cash/card refunds against the credit (always positive)\n- applied_to_other_total: sum of credit consumed by Loop Returns EXC-* exchange orders (always positive)\n- fees_retained_total: sum of fees Loop withheld out of the customer's credit — return shipping, restocking, etc. (always positive)\n- outstanding_amount: total minus (refund_payments_total + applied_to_other_total + fees_retained_total), clamped to zero (i.e., the unrefunded, unapplied balance still owed back to the customer)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-credits?page=1&limit=10&sort=&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","v2","sales-credits"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"","description":"Sort field and direction (prefix with - for descending). Common fields: id, credit_date, sales_credit_number, created_at, updated_at, archived_at","disabled":true},{"key":"search","value":"","description":"Full-text search across sales credit number, customer name, order number, SKU","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"IDs to force include in results","disabled":true},{"key":"excluded[]","value":"","description":"IDs to force exclude from results","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sales_credit_number\": \"SC-00055\",\n      \"credit_date\": \"2025-04-10\",\n      \"is_for_overpayment\": false,\n      \"created_at\": \"2025-04-10T09:00:00.000000Z\",\n      \"updated_at\": \"2025-04-10T09:00:00.000000Z\",\n      \"archived_at\": null,\n      \"statuses\": {\n        \"credit_status\": \"open\",\n        \"return_status\": \"pending\"\n      },\n      \"additional_credit\": 0,\n      \"tax_credit\": 0,\n      \"product_total\": 150,\n      \"total\": 150,\n      \"refund_payments_total\": 0,\n      \"applied_to_other_total\": 0,\n      \"fees_retained_total\": 0,\n      \"outstanding_amount\": 150,\n      \"currency_code\": \"USD\",\n      \"sales_order_id\": 100,\n      \"has_products\": true,\n      \"has_rma\": false,\n      \"payments\": [],\n      \"exchange_orders\": []\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 5,\n  \"last_page\": 1\n}"}]},{"name":"Sales Credit Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-credits/{salesCredit}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","sales-credits",":salesCredit","activity-log"],"variable":[{"key":"salesCredit","value":"1","description":"Sales Credit ID"}]},"description":"Returns the activity log for a sales credit.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-credits/{salesCredit}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","sales-credits",":salesCredit","activity-log"],"variable":[{"key":"salesCredit","value":"1","description":"Sales Credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"action\": \"created\",\n      \"user\": {\n        \"id\": 1,\n        \"name\": \"John Smith\"\n      },\n      \"created_at\": \"2024-03-01T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Sales Credits Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-credits/filter-options","host":["{{baseUrl}}"],"path":["api","v2","sales-credits","filter-options"]},"description":"Returns available filter options (distinct values) for sales credits filtering.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-credits/filter-options","host":["{{baseUrl}}"],"path":["api","v2","sales-credits","filter-options"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"statuses\": [\n      \"draft\",\n      \"issued\",\n      \"applied\",\n      \"cancelled\"\n    ],\n    \"customers\": [\n      {\n        \"id\": 7,\n        \"name\": \"Acme Corp\"\n      }\n    ]\n  }\n}"}]},{"name":"List Sales Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits?page=1&limit=10&sort=&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","sales-credits"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"","description":"Sort field and direction (prefix with - for descending). Common fields: id, credit_date, sales_credit_number, created_at, updated_at, archived_at","disabled":true},{"key":"search","value":"","description":"Full-text search across sales credit number, customer name, order number, SKU","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"IDs to force include in results","disabled":true},{"key":"excluded[]","value":"","description":"IDs to force exclude from results","disabled":true}]},"description":"Returns a paginated list of sales credits with standard list query parameters. Supports search, archiving filter, and column selection.\n\nAuthentication: Requires Bearer token.\n\nThis endpoint uses standard list query parameters. Common filters are passed as query parameters directly.\n\nResponse is wrapped with table_specifications metadata when table_specifications parameter is provided.\n\nTotals fields:\n- total: total credit amount\n- refund_payments_total: sum of cash/card refunds against the credit (always positive)\n- applied_to_other_total: sum of credit consumed by Loop Returns EXC-* exchange orders (always positive)\n- fees_retained_total: sum of fees Loop withheld out of the customer's credit — return shipping, restocking, etc. (always positive)\n- outstanding_amount: total minus (refund_payments_total + applied_to_other_total + fees_retained_total), clamped to zero (i.e., the unrefunded, unapplied balance still owed back to the customer)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-credits?page=1&limit=10&sort=&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","sales-credits"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"","description":"Sort field and direction (prefix with - for descending). Common fields: id, credit_date, sales_credit_number, created_at, updated_at, archived_at","disabled":true},{"key":"search","value":"","description":"Full-text search across sales credit number, customer name, order number, SKU","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true},{"key":"included[]","value":"","description":"IDs to force include in results","disabled":true},{"key":"excluded[]","value":"","description":"IDs to force exclude from results","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sales_credit_number\": \"SC-00055\",\n      \"credit_date\": \"2025-04-10\",\n      \"is_for_overpayment\": false,\n      \"created_at\": \"2025-04-10T09:00:00.000000Z\",\n      \"updated_at\": \"2025-04-10T09:00:00.000000Z\",\n      \"archived_at\": null,\n      \"statuses\": {\n        \"credit_status\": \"open\",\n        \"return_status\": \"pending\"\n      },\n      \"additional_credit\": 0,\n      \"tax_credit\": 0,\n      \"product_total\": 150,\n      \"total\": 150,\n      \"refund_payments_total\": 0,\n      \"applied_to_other_total\": 0,\n      \"fees_retained_total\": 0,\n      \"outstanding_amount\": 150,\n      \"currency_code\": \"USD\",\n      \"sales_order_id\": 100,\n      \"has_products\": true,\n      \"has_rma\": false,\n      \"payments\": [],\n      \"exchange_orders\": []\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 5,\n  \"last_page\": 1\n}"}]},{"name":"Create Sales Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits","host":["{{baseUrl}}"],"path":["api","sales-credits"]},"description":"Creates a new sales credit. Must be linked to either a sales_order_id or a customer_id.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_order_id (required if no customer_id): Sales order ID to credit against\n- customer_id (required if no sales_order_id): Customer ID for non-order credits\n- sales_credit_number (optional, max 255): Custom credit number (auto-generated if omitted)\n- credit_date (optional, date): Credit date\n- store_id (optional): Store ID\n- to_warehouse_id (optional): Return destination warehouse ID\n- sales_credit_note (optional): Free-form note\n- currency_id (optional): Currency ID (defaults to account default)\n- currency_code (optional): Currency code (alternative to currency_id)\n- tax_rate_id (optional): Tax rate ID\n- is_tax_included (optional, boolean): Whether prices include tax. Default: false\n- is_product (optional, boolean): Whether this is a product return. Default: false\n- tax_lines (optional): Array of tax line objects\n- sales_credit_lines (optional): Array of credit lines — each with sales_order_line_id, quantity, and price","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 100,\n  \"sales_credit_number\": \"SC-MANUAL-001\",\n  \"credit_date\": \"2025-04-10\",\n  \"store_id\": 3,\n  \"to_warehouse_id\": 1,\n  \"sales_credit_note\": \"Customer returned damaged item\",\n  \"currency_id\": 1,\n  \"tax_rate_id\": null,\n  \"is_tax_included\": false,\n  \"is_product\": true,\n  \"tax_lines\": [],\n  \"sales_credit_lines\": [\n    {\n      \"sales_order_line_id\": 201,\n      \"quantity\": 2,\n      \"price\": 75,\n      \"financial_line_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits","host":["{{baseUrl}}"],"path":["api","sales-credits"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 56,\n    \"sales_credit_number\": \"SC-MANUAL-001\",\n    \"total\": 150,\n    \"currency_code\": \"USD\"\n  },\n  \"message\": \"sales credit created successfully\"\n}"}]},{"name":"Bulk Delete Sales Credits","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits","host":["{{baseUrl}}"],"path":["api","sales-credits"]},"description":"Bulk deletes sales credits by IDs or by applying current filters.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required if apply_to_all is false): Array of sales credit IDs to delete\n- apply_to_all (optional, boolean): If true, deletes all records matching the current filters instead of specific IDs\n- filters (optional): Filter set to apply when apply_to_all is true"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-credits","host":["{{baseUrl}}"],"path":["api","sales-credits"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credits bulk deleted successfully\"\n}"}]},{"name":"Get Sales Credit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Returns a single sales credit with all relations: lines, store with address, sales order, RMA with receipts, payments, allocations, and accounting transaction.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nTotals fields:\n- total: total credit amount\n- refund_payments_total: sum of cash/card refunds against the credit (always positive)\n- applied_to_other_total: sum of credit consumed by Loop Returns EXC-* exchange orders (always positive)\n- fees_retained_total: sum of fees Loop withheld out of the customer's credit — return shipping, restocking, etc. (always positive)\n- outstanding_amount: total minus (refund_payments_total + applied_to_other_total + fees_retained_total), clamped to zero (i.e., the unrefunded, unapplied balance still owed back to the customer)\n\nResponse field `metadata` (object|null): minimal credit-source metadata for channel-synced credits - `source` (e.g. `ebay`, `shopify`, `woocommerce`) and `sales_channel_refund_id` (the channel refund ID). `null` for manually created credits. Used by the UI for the source chip on the sales order Credits tab."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sales_credit_number\": \"SC-00055\",\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Main Store\",\n      \"email\": \"store@example.com\",\n      \"address\": {\n        \"address1\": \"123 Main St\",\n        \"city\": \"New York\",\n        \"province\": \"NY\",\n        \"zip\": \"10001\",\n        \"country\": \"United States\",\n        \"country_code\": \"US\"\n      }\n    },\n    \"credit_date\": \"2025-04-10\",\n    \"is_for_overpayment\": false,\n    \"integration\": \"Shopify\",\n    \"created_at\": \"2025-04-10T09:00:00.000000Z\",\n    \"updated_at\": \"2025-04-10T09:00:00.000000Z\",\n    \"archived_at\": null,\n    \"to_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"returns_receipt_date\": null,\n    \"returns_receipt_quantity\": 0,\n    \"statuses\": {\n      \"credit_status\": \"open\",\n      \"return_status\": \"pending\"\n    },\n    \"additional_credit\": 0,\n    \"tax_credit\": 5,\n    \"product_total\": 150,\n    \"total\": 155,\n    \"refund_payments_total\": 143.49,\n    \"applied_to_other_total\": 0,\n    \"fees_retained_total\": 0,\n    \"outstanding_amount\": 11.51,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"returns\"\n    ],\n    \"sales_order_id\": 100,\n    \"sales_order\": {\n      \"id\": 100,\n      \"sales_order_number\": \"SO-00100\"\n    },\n    \"sales_credit_lines\": [\n      {\n        \"id\": 201,\n        \"product_id\": 12,\n        \"quantity\": 2,\n        \"price\": 75\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 2,\n    \"first_line_sku\": \"WIDGET-A\",\n    \"exchange_orders\": [],\n    \"payments\": [],\n    \"has_products\": true,\n    \"has_rma\": false,\n    \"rma\": null,\n    \"tax_lines\": [],\n    \"tax_rate\": null,\n    \"calculated_tax_total\": 5,\n    \"sales_credit_note\": \"Customer damaged item\",\n    \"metadata\": {\n      \"source\": \"ebay\",\n      \"sales_channel_refund_id\": \"5012345678\"\n    },\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null\n  }\n}"}]},{"name":"Update Sales Credit","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Updates a sales credit including its lines. Lines array replaces all existing lines when provided; omit lines to leave them unchanged.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_credit_number (optional, max 255): Custom credit number\n- credit_date (optional, date): Credit date\n- store_id (optional): Store ID\n- to_warehouse_id (optional): Return destination warehouse ID\n- customer_id (optional): Customer ID\n- sales_credit_note (optional): Free-form note\n- currency_id (optional): Currency ID\n- currency_code (optional): Currency code\n- tax_rate_id (optional): Tax rate ID\n- is_tax_included (optional, boolean): Whether prices include tax\n- is_product (optional, boolean): Whether this is a product return\n- tax_lines (optional): Array of tax line objects\n- sales_credit_lines (optional): Array of credit lines to sync","body":{"mode":"raw","raw":"{\n  \"credit_date\": \"2025-04-12\",\n  \"sales_credit_note\": \"Updated note: partial return\",\n  \"to_warehouse_id\": 2,\n  \"tax_rate_id\": 3,\n  \"is_tax_included\": false,\n  \"sales_credit_lines\": [\n    {\n      \"sales_order_line_id\": 201,\n      \"quantity\": 1,\n      \"price\": 75\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sales_credit_number\": \"SC-00055\",\n    \"credit_date\": \"2025-04-12\",\n    \"total\": 75\n  },\n  \"message\": \"sales credit SC-00055 updated successfully\"\n}"}]},{"name":"Delete Sales Credit","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Deletes a single sales credit.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credit SC-00055 deleted successfully\"\n}"}]},{"name":"Bulk Archive Sales Credits","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/archive","host":["{{baseUrl}}"],"path":["api","sales-credits","archive"]},"description":"Bulk archives sales credits by IDs or by applying current filters.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required if apply_to_all is false): Array of sales credit IDs to archive\n- apply_to_all (optional, boolean): If true, archives all records matching current filters\n- filters (optional): Filter set to apply when apply_to_all is true","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    55,\n    56\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/archive","host":["{{baseUrl}}"],"path":["api","sales-credits","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credits bulk archived successfully\"\n}"}]},{"name":"Bulk Unarchive Sales Credits","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/unarchive","host":["{{baseUrl}}"],"path":["api","sales-credits","unarchive"]},"description":"Bulk unarchives sales credits by IDs or by applying current filters.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required if apply_to_all is false): Array of sales credit IDs to unarchive\n- apply_to_all (optional, boolean): If true, unarchives all records matching current filters\n- filters (optional): Filter set to apply when apply_to_all is true","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    55,\n    56\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/unarchive","host":["{{baseUrl}}"],"path":["api","sales-credits","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credits bulk unarchived successfully\"\n}"}]},{"name":"Check Sales Credits Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/deletable","host":["{{baseUrl}}"],"path":["api","sales-credits","deletable"]},"description":"Checks whether each specified sales credit can be deleted (i.e., is not used/linked to payments or other records). Returns deletability status and reason for each.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of sales credit IDs to check (min 1)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    55,\n    56,\n    57\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/deletable","host":["{{baseUrl}}"],"path":["api","sales-credits","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sales_credit_number\": \"SC-00055\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 56,\n      \"sales_credit_number\": \"SC-00056\",\n      \"deletable\": false,\n      \"reason\": \"Has associated payments\"\n    },\n    {\n      \"id\": 57,\n      \"sales_credit_number\": \"SC-00057\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Archive Sales Credit","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/archive","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","archive"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Archives a single sales credit. Returns a warning if already archived.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/archive","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","archive"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales credit SC-00055 archived successfully\"\n}"}]},{"name":"Unarchive Sales Credit","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","unarchived"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Unarchives a single sales credit. Returns a warning if not archived.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","unarchived"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sales_credit_number\": \"SC-00055\",\n    \"archived_at\": null\n  },\n  \"message\": \"sales credit SC-00055 unarchived successfully\"\n}"}]},{"name":"Record Sales Credit Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/paid","host":["{{baseUrl}}"],"path":["api","sales-credits","paid"]},"description":"Records a payment against a sales credit, marking it as paid.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_credit_id (required): Sales credit ID to record payment for\n- payment_type_id (required): Payment type ID\n- payment_date (optional, date): Date of payment\n- amount (required, numeric, > 0): Payment amount — must not exceed remaining balance\n- external_reference (optional, max 255): External reference number\n- currency_id (optional): Currency ID","body":{"mode":"raw","raw":"{\n  \"sales_credit_id\": 55,\n  \"payment_type_id\": 2,\n  \"payment_date\": \"2025-04-15\",\n  \"amount\": 150,\n  \"external_reference\": \"REF-123456\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/paid","host":["{{baseUrl}}"],"path":["api","sales-credits","paid"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sales_credit_number\": \"SC-00055\",\n    \"statuses\": {\n      \"credit_status\": \"paid\"\n    },\n    \"payments\": [\n      {\n        \"id\": 88,\n        \"amount\": 150,\n        \"payment_date\": \"2025-04-15\",\n        \"external_reference\": \"REF-123456\"\n      }\n    ]\n  },\n  \"message\": \"payment created successfully\"\n}"}]},{"name":"Update Payment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","payments",":payment"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"payment","value":"88","description":"The payment ID."}]},"description":"Updates an existing payment on a sales credit. All fields are optional (uses sometimes validation).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- payment_date (optional, date): Updated payment date\n- amount (optional, numeric, > 0): Updated payment amount\n- external_reference (optional, max 255): External reference number\n- currency_id (optional): Currency ID","body":{"mode":"raw","raw":"{\n  \"payment_date\": \"2025-04-16\",\n  \"amount\": 120,\n  \"external_reference\": \"REF-UPDATED\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","payments",":payment"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"payment","value":"88","description":"The payment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"payments\": [\n      {\n        \"id\": 88,\n        \"amount\": 120,\n        \"payment_date\": \"2025-04-16\"\n      }\n    ]\n  },\n  \"message\": \"payment created successfully\"\n}"}]},{"name":"Delete Payment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","payments",":payment"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"payment","value":"88","description":"The payment ID."}]},"description":"Deletes a payment from a sales credit and recalculates the payment status.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","payments",":payment"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"payment","value":"88","description":"The payment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"payments\": []\n  },\n  \"message\": \"payment deleted successfully\"\n}"}]},{"name":"List Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]},"description":"Returns a paginated list of notes for a sales credit, ordered by created_at descending. Includes the note author.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 33,\n      \"note\": \"Customer confirmed return shipment sent\",\n      \"created_at\": \"2025-04-11T10:00:00.000000Z\",\n      \"user\": {\n        \"id\": 1,\n        \"name\": \"Admin User\"\n      }\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Add Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]},"description":"Adds a note to a sales credit.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- note (required): Note text","body":{"mode":"raw","raw":"{\n  \"note\": \"Customer confirmed return shipment sent\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 34,\n    \"note\": \"Customer confirmed return shipment sent\",\n    \"created_at\": \"2025-04-23T10:00:00.000000Z\",\n    \"user\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    }\n  },\n  \"message\": \"note created successfully\"\n}"}]},{"name":"Delete Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes",":noteId"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"noteId","value":"33","description":"The note ID."}]},"description":"Deletes a note from a sales credit.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","notes",":noteId"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."},{"key":"noteId","value":"33","description":"The note ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 33 deleted successfully\"\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","generate-accounting-transaction"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]},"description":"Generates an accounting transaction for the sales credit (e.g., for syncing to accounting software like QuickBooks Online).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/{salesCredit}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","sales-credits",":salesCredit","generate-accounting-transaction"],"variable":[{"key":"salesCredit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 78,\n    \"reference\": \"SC-00055\",\n    \"amount\": 150\n  },\n  \"message\": \"Accounting transaction generated successfully.\"\n}"}]},{"name":"Preview Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/invoice/preview","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","invoice","preview"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]},"description":"Generates a PDF invoice preview for the sales credit and returns the URL to the generated file.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-credits/{sales_credit}/invoice/preview","host":["{{baseUrl}}"],"path":["api","sales-credits",":sales_credit","invoice","preview"],"variable":[{"key":"sales_credit","value":"55","description":"The sales credit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"path\": \"https://sku2.test/storage/reports/sales-credit-55-invoice.pdf\"\n  }\n}"}]},{"name":"Export Sales Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/list/export","host":["{{baseUrl}}"],"path":["api","sales-credits","list","export"]},"description":"Download an Excel/CSV export of sales credits.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope.rw:orders).\n\nResponse: a binary file download (xlsx or csv), NOT JSON. Columns: ID, Credit #, Sales Order #, Store, Customer, Customer Email, Credit Date, Status, Payment Status, Currency, Tax Total, Total Credit, Refunded, Note, Created At.\n\nQuery params:\n- format: xlsx (default) or csv\n- scope: 'filtered' (default) or 'selected'\n- ids: comma-separated IDs (only when scope=selected)"}},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-credits/import/template","host":["{{baseUrl}}"],"path":["api","sales-credits","import","template"]},"description":"Download a multi-sheet XLSX import template pre-filled with sample rows, a field guide, and reference data (stores, currencies, warehouses, tax rates, nominal codes) from your account.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope.rw:orders).\n\nResponse: a binary XLSX file download, NOT JSON. Fill the 'Import Here' sheet, then upload it in the import wizard."}},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/import/validate","host":["{{baseUrl}}"],"path":["api","sales-credits","import","validate"]},"description":"Validate and preview mapped import rows BEFORE importing. No database writes occur — safe to call repeatedly.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope.rw:orders).\n\nResolves customer / sales order / store / currency / warehouse / SKU / nominal code / tax rate names to IDs, groups flat rows into credits (by id, then sales_credit_number, then sales_order_number), and computes an upsert action per credit (create / update / blocked). Customers that don't exist are auto-created on import.\n\nEach row accepts all template columns: id, sales_credit_number, credit_date, sales_order_number, customer_email, customer_id, customer_name, customer_company, customer_phone, store_name, currency_code, to_warehouse_name, sales_credit_note, sku, sales_order_line_id, description, quantity, amount, unit_cost, nominal_code, tax_rate, is_product.\n\nMax 50000 rows per call.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"id\": \"\",\n      \"sales_credit_number\": \"SC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"sales_order_number\": \"\",\n      \"customer_email\": \"jane@example.com\",\n      \"customer_id\": \"\",\n      \"customer_name\": \"Jane Doe\",\n      \"customer_company\": \"\",\n      \"customer_phone\": \"\",\n      \"store_name\": \"\",\n      \"currency_code\": \"USD\",\n      \"to_warehouse_name\": \"Main Warehouse\",\n      \"sales_credit_note\": \"Returned item\",\n      \"sku\": \"WIDGET-001\",\n      \"sales_order_line_id\": \"\",\n      \"description\": \"Blue Widget - Large\",\n      \"quantity\": \"1\",\n      \"amount\": \"19.99\",\n      \"unit_cost\": \"\",\n      \"nominal_code\": \"\",\n      \"tax_rate\": \"\",\n      \"is_product\": \"true\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/import/validate","host":["{{baseUrl}}"],"path":["api","sales-credits","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"sales_credits\": [\n    {\n      \"group_key\": \"scn:sc-001\",\n      \"id\": null,\n      \"sales_credit_number\": \"SC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"sales_credit_note\": \"Returned item\",\n      \"action\": \"create\",\n      \"match_reason\": null,\n      \"block_reason\": null,\n      \"existing_sales_credit\": null,\n      \"sales_order\": null,\n      \"customer\": {\n        \"id\": null,\n        \"email\": \"jane@example.com\",\n        \"name\": \"Jane Doe\",\n        \"will_create\": true\n      },\n      \"store\": null,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"errors\": [],\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 845,\n          \"product_name\": \"Blue Widget - Large\",\n          \"sales_order_line_id\": null,\n          \"description\": \"Blue Widget - Large\",\n          \"quantity\": 1,\n          \"amount\": 19.99,\n          \"unit_cost\": null,\n          \"nominal_code_id\": null,\n          \"tax_rate_id\": null,\n          \"is_product\": true,\n          \"line_total\": 19.99,\n          \"errors\": []\n        }\n      ],\n      \"total_quantity\": 1,\n      \"total_amount\": 19.99\n    }\n  ],\n  \"summary\": {\n    \"total_sales_credits\": 1,\n    \"total_line_items\": 1,\n    \"total_errors\": 0,\n    \"total_will_create\": 1,\n    \"total_will_update\": 0,\n    \"total_blocked\": 0,\n    \"customers_created\": 1\n  }\n}"}]},{"name":"Import Sales Credits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-credits/import","host":["{{baseUrl}}"],"path":["api","sales-credits","import"]},"description":"Execute the import — upsert sales credits from validated data (typically the output of the Validate Import endpoint).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope.rw:orders).\n\nUpsert behavior:\n- Rows with no matched existing credit are CREATED (customers are auto-created when needed).\n- Rows matching an existing editable credit are UPDATED.\n- Rows with action=blocked are rejected (paid / allocated / closed / Shopify-origin credits cannot be updated via import).\n\ncontinue_on_error (default false): when true, each credit is imported in its own transaction and failures are collected into 'skipped'. When false, the entire import runs in one transaction.\n\nReturns 201 when any credit was created, otherwise 200.","body":{"mode":"raw","raw":"{\n  \"continue_on_error\": false,\n  \"sales_credits\": [\n    {\n      \"group_key\": \"scn:sc-001\",\n      \"id\": null,\n      \"action\": \"create\",\n      \"match_reason\": null,\n      \"block_reason\": null,\n      \"existing_sales_credit\": null,\n      \"sales_credit_number\": \"SC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"sales_credit_note\": \"Returned item\",\n      \"sales_order\": null,\n      \"customer\": {\n        \"id\": null,\n        \"email\": \"jane@example.com\",\n        \"name\": \"Jane Doe\"\n      },\n      \"store\": null,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 845,\n          \"product_name\": \"Blue Widget - Large\",\n          \"sales_order_line_id\": null,\n          \"description\": \"Blue Widget - Large\",\n          \"quantity\": 1,\n          \"amount\": 19.99,\n          \"unit_cost\": null,\n          \"nominal_code_id\": null,\n          \"tax_rate_id\": null,\n          \"is_product\": true\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-credits/import","host":["{{baseUrl}}"],"path":["api","sales-credits","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"created\": [\n    {\n      \"id\": 301,\n      \"sales_credit_number\": \"SC-001\"\n    }\n  ],\n  \"updated\": [],\n  \"skipped\": [],\n  \"customers_created\": [\n    {\n      \"id\": 99,\n      \"name\": \"Jane Doe\",\n      \"email\": \"jane@example.com\"\n    }\n  ],\n  \"summary\": {\n    \"total\": 1,\n    \"created\": 1,\n    \"updated\": 0,\n    \"skipped\": 0,\n    \"customers_created\": 1\n  }\n}"}]}]},{"name":"Reporting","item":[{"name":"Ship By Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/reporting/ship-by-schedule","host":["{{baseUrl}}"],"path":["api","v2","reporting","ship-by-schedule"]},"description":"Returns ship-by schedule report data showing orders that need to be shipped by specific dates.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/reporting/ship-by-schedule","host":["{{baseUrl}}"],"path":["api","v2","reporting","ship-by-schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"ship_by_date\": \"2024-03-25\",\n      \"order_count\": 12,\n      \"total_units\": 48,\n      \"overdue\": false\n    },\n    {\n      \"ship_by_date\": \"2024-03-20\",\n      \"order_count\": 3,\n      \"total_units\": 9,\n      \"overdue\": true\n    }\n  ]\n}"}]},{"name":"Get Inventory Planning Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}]},"description":"Returns a paginated inventory planning report with replenishment data per product. Supports warehouse filtering via filter[warehouse_id], filter[warehouse_id][is], or base64-encoded filter_groups tree.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nPagination: Default per page from request or manager default\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"barcode\": \"1234567890\",\n      \"type\": \"standard\",\n      \"brand\": \"Acme\",\n      \"brand_id\": 5,\n      \"available_qty\": 150,\n      \"available_to_sell\": 150,\n      \"total_stock_qty\": 180,\n      \"reserved_qty\": 20,\n      \"in_transit_qty\": 10,\n      \"inbound_qty\": 50,\n      \"projected_total\": 200,\n      \"active_backorder_qty\": 0,\n      \"net_available\": 150,\n      \"supplier_name\": \"Widget Co\",\n      \"supplier_id\": 10,\n      \"supplier_sku\": \"WC-WIDGET-001\",\n      \"supplier_price\": 8.5,\n      \"supplier_currency_code\": \"USD\",\n      \"average_cost\": 9.25,\n      \"stock_value\": 1665,\n      \"estimated_landed_cost\": 10.2,\n      \"gross_margin_pct\": 0.42,\n      \"length\": 10,\n      \"width\": 5,\n      \"height\": 3,\n      \"dimension_unit\": \"cm\",\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"cbm\": 0.00015,\n      \"volume\": 0.00015,\n      \"volume_unit\": \"CBM\",\n      \"qty_sold_30d\": 45,\n      \"qty_sold_60d\": 90,\n      \"qty_sold_90d\": 135,\n      \"qty_sold_180d\": 270,\n      \"monthly_avg_sales\": 45,\n      \"daily_avg_sales\": 1.5,\n      \"revenue_180d\": 4050,\n      \"demand_trend_pct\": 12.5,\n      \"demand_trend_direction\": \"stable\",\n      \"demand_trend_confidence\": \"high\",\n      \"days_of_stock\": 100,\n      \"days_until_stockout\": 133.3,\n      \"stockout_risk\": \"low\",\n      \"stockout_risk_color\": \"success\",\n      \"abc_classification\": \"A\",\n      \"xyz_classification\": \"X\",\n      \"abc_xyz_cell\": \"AX\",\n      \"sell_through_rate\": 0.643,\n      \"inventory_turnover\": 3,\n      \"revenue_at_risk\": 0,\n      \"overstock_qty\": 0,\n      \"overstock_value\": 0,\n      \"is_dead_stock\": false,\n      \"dead_stock_value\": null,\n      \"lead_time\": 30,\n      \"avg_actual_lead_time\": 28.5,\n      \"lead_time_reliability_pct\": 0.92,\n      \"lead_time_variance\": 3.2,\n      \"min_order_qty\": 50,\n      \"target_stock_days\": 60,\n      \"min_stock_level\": 20,\n      \"reorder_point\": 65,\n      \"suggested_reorder_qty\": 50,\n      \"case_quantity\": 12,\n      \"suggested_cases\": 5,\n      \"adjusted_reorder_qty\": 60,\n      \"reorder_cbm\": 0.009,\n      \"reorder_cost\": 510,\n      \"reorder_landed_cost\": 612,\n      \"next_po_date\": \"2024-07-15\",\n      \"next_po_qty\": 100,\n      \"days_until_relief\": 21,\n      \"velocity_computed_at\": \"2024-06-14T08:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 25,\n  \"total\": 342,\n  \"unfiltered_total\": 2103,\n  \"last_page\": 14\n}"}]},{"name":"Get Inventory Planning Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/summary","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","summary"]},"description":"Returns summary metrics for the inventory planning report header cards (counts of items at risk, overstocked, out of stock, etc.).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/summary","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_products\": 342,\n    \"high_risk\": 12,\n    \"medium_risk\": 28,\n    \"low_risk\": 302,\n    \"out_of_stock\": 5,\n    \"dead_stock\": 8,\n    \"total_stock_value\": 125400,\n    \"total_reorder_cost\": 38200\n  }\n}"}]},{"name":"Export Inventory Planning Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/export?format=csv","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","export"],"query":[{"key":"format","value":"csv","description":"csv (default) | xlsx","disabled":true}]},"description":"Exports the inventory planning report as CSV or XLSX. Supports column selection and warehouse filtering.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet file download"}},{"name":"Refresh Velocity Data","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/refresh-velocity","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","refresh-velocity"]},"description":"Dispatches a tracked background job to recompute product velocity cache and supplier lead time reliability. Returns a tracked_job_log_id for monitoring via the tracked job log endpoints.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/refresh-velocity","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","refresh-velocity"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 87\n  },\n  \"message\": \"Velocity cache refresh started. Track progress in the job tray.\"\n}"}]},{"name":"Refresh Sales Financials","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/refresh-financials","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","refresh-financials"]},"description":"Dispatches a tracked background job to refresh sales financials data used by the inventory planning report. Returns a tracked_job_log_id for monitoring via the tracked job log endpoints.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/refresh-financials","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","refresh-financials"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 88\n  },\n  \"message\": \"Sales financials refresh started. Track progress in the job tray.\"\n}"}]},{"name":"Create Draft PO from Planning","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/create-po","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","create-po"]},"description":"Creates a draft purchase order from reorder suggestions in the inventory planning report.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequired fields:\n- supplier_id: integer (must exist)\n- product_ids: array of integers (min 1, must exist)\n\nOptional fields:\n- quantities: object keyed by product_id with integer values (min 1)\n- use_adjusted_qty: boolean (default: true) — use the adjusted reorder qty\n- order_status: 'draft' | 'open' (default: 'draft')\n- destination_warehouse_id: integer (must exist)","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 10,\n  \"product_ids\": [\n    42,\n    43,\n    44\n  ],\n  \"use_adjusted_qty\": true,\n  \"order_status\": \"draft\",\n  \"destination_warehouse_id\": 1,\n  \"quantities\": {\n    \"42\": 100,\n    \"43\": 50\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/create-po","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","create-po"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purchase_order_id\": 350,\n    \"purchase_order_number\": \"PO-350\",\n    \"line_count\": 3,\n    \"total_cost\": 2550,\n    \"order_status\": \"draft\",\n    \"destination_warehouse\": \"Main Warehouse\"\n  },\n  \"message\": \"Purchase order created\"\n}"}]},{"name":"List Scheduled Reports","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules"]},"description":"Returns all scheduled reports for the authenticated user for the inventory_planning report type.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Weekly Inventory Report\",\n      \"report_type\": \"inventory_planning\",\n      \"frequency\": \"weekly\",\n      \"day_of_week\": 1,\n      \"day_of_month\": null,\n      \"time\": \"08:00\",\n      \"timezone\": \"America/New_York\",\n      \"format\": \"xlsx\",\n      \"recipients\": [\n        \"manager@example.com\"\n      ],\n      \"filters\": {\n        \"warehouse_id\": 1\n      },\n      \"columns\": [\n        \"sku\",\n        \"name\",\n        \"available_qty\",\n        \"suggested_reorder_qty\"\n      ],\n      \"is_active\": true,\n      \"last_sent_at\": \"2024-06-10T08:00:00+00:00\",\n      \"next_run_at\": \"2024-06-17T08:00:00+00:00\",\n      \"created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"updated_at\": \"2024-06-10T08:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Scheduled Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules"]},"description":"Creates a new scheduled inventory planning report for the authenticated user.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequired fields:\n- name: string (max 255)\n- frequency: daily | weekly | monthly\n- time: HH:MM (24h format)\n- timezone: valid timezone string\n- format: csv | xlsx\n- recipients: array of emails (min 1)\n\nConditional required:\n- day_of_week: integer 0-6 (required when frequency=weekly)\n- day_of_month: integer 1-28 (required when frequency=monthly)\n\nOptional:\n- filters: object of filter values\n- columns: array of column names","body":{"mode":"raw","raw":"{\n  \"name\": \"Weekly Inventory Report\",\n  \"frequency\": \"weekly\",\n  \"day_of_week\": 1,\n  \"time\": \"08:00\",\n  \"timezone\": \"America/New_York\",\n  \"format\": \"xlsx\",\n  \"recipients\": [\n    \"manager@example.com\",\n    \"buyer@example.com\"\n  ],\n  \"filters\": {\n    \"warehouse_id\": 1\n  },\n  \"columns\": [\n    \"sku\",\n    \"name\",\n    \"available_qty\",\n    \"suggested_reorder_qty\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Weekly Inventory Report\",\n    \"report_type\": \"inventory_planning\",\n    \"frequency\": \"weekly\",\n    \"day_of_week\": 1,\n    \"time\": \"08:00\",\n    \"timezone\": \"America/New_York\",\n    \"format\": \"xlsx\",\n    \"recipients\": [\n      \"manager@example.com\"\n    ],\n    \"is_active\": true,\n    \"created_at\": \"2024-06-15T10:00:00+00:00\"\n  },\n  \"message\": \"Scheduled report created\"\n}"}]},{"name":"Delete Scheduled Report","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules/{scheduledReport}","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules",":scheduledReport"],"variable":[{"key":"scheduledReport","value":"1","description":"Scheduled Report ID"}]},"description":"Deletes a scheduled report. Only the owner can delete their own scheduled reports.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/reporting/inventory-planning/schedules/{scheduledReport}","host":["{{baseUrl}}"],"path":["api","reporting","inventory-planning","schedules",":scheduledReport"],"variable":[{"key":"scheduledReport","value":"1","description":"Scheduled Report ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Profitability Trend","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/trend?group_by=brand&interval=month&limit=12&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","profitability","trend"],"query":[{"key":"group_by","value":"brand","description":"Required. Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"interval","value":"month","description":"Required. Time interval: day | week | month | quarter | year","disabled":true},{"key":"limit","value":"12","description":"Optional. Number of periods to return","disabled":true},{"key":"sort","value":"desc","description":"Optional. Sort order: asc | desc","disabled":true}]},"description":"Returns trend data (per-interval metrics) grouped by a dimension. When indirect costs are included (default), per-interval total cost and profit reflect cost-entry allocations; period allocations are day-prorated across intervals. Margin-ladder metrics are available: gross_profit / gross_margin (revenue minus COGS), contribution_margin / contribution_margin_pct (after channel and indirect costs), plus ad_spend and tacos for sku, brand, and supplier groupings.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRows may include {interval}_indirect_cost keys and a 'Non-Product / Unallocated' row (is_unallocated: true) for amounts that cannot be attributed to the chosen grouping.\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/trend?group_by=brand&interval=month&limit=12&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","profitability","trend"],"query":[{"key":"group_by","value":"brand","description":"Required. Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"interval","value":"month","description":"Required. Time interval: day | week | month | quarter | year","disabled":true},{"key":"limit","value":"12","description":"Optional. Number of periods to return","disabled":true},{"key":"sort","value":"desc","description":"Optional. Sort order: asc | desc","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"period\": \"2024-06\",\n      \"dimension_value\": \"Acme Brand\",\n      \"revenue\": 15200,\n      \"cogs\": 8500,\n      \"total_cost\": 9200,\n      \"profit\": 6000,\n      \"quantity\": 320,\n      \"num_orders\": 45,\n      \"margin\": 39.47\n    }\n  ]\n}"}]},{"name":"Get Profitability Cost Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/cost-breakdown?group_by=brand","host":["{{baseUrl}}"],"path":["api","reporting","profitability","cost-breakdown"],"query":[{"key":"group_by","value":"brand","description":"Required. Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true}]},"description":"Returns cost breakdown rows per dimension with financial line type columns, indirect costs (cost-entry allocations), and the margin ladder: gross_profit / gross_margin, contribution_margin / contribution_margin_pct, and company-level operating_profit (contribution margin minus unallocated indirect costs).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIndirect costs attribute direct dimension-target allocations plus product-target allocations rolled up to the grouping; unattributable amounts appear on the 'Non-Product / Unallocated' row so grand totals cover all allocations in range. For sku, brand, and supplier groupings, rows also carry ad_spend, acos, and tacos (a breakout of indirect costs — already included in the totals, never added twice).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/cost-breakdown?group_by=brand","host":["{{baseUrl}}"],"path":["api","reporting","profitability","cost-breakdown"],"query":[{"key":"group_by","value":"brand","description":"Required. Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimensions\": [\n      {\n        \"rowLabel\": \"Acme Brand\",\n        \"revenue\": 45000,\n        \"cogs\": 25000,\n        \"cost_allocated\": 3200,\n        \"indirect_cost\": 1800,\n        \"indirect_cost_by_type\": {\n          \"2\": 1200,\n          \"5\": 600\n        },\n        \"total_cost\": 30000,\n        \"profit\": 15000,\n        \"margin\": 33.33,\n        \"gross_profit\": 20000,\n        \"gross_margin\": 44.44,\n        \"contribution_margin\": 15000,\n        \"contribution_margin_pct\": 33.33,\n        \"flt_values\": {\n          \"1\": 3200\n        },\n        \"is_unallocated\": false\n      },\n      {\n        \"rowLabel\": \"Non-Product / Unallocated\",\n        \"revenue\": 0,\n        \"cogs\": 0,\n        \"cost_allocated\": 0,\n        \"indirect_cost\": 500,\n        \"indirect_cost_by_type\": {\n          \"2\": 500\n        },\n        \"total_cost\": 500,\n        \"profit\": -500,\n        \"margin\": null,\n        \"gross_profit\": 0,\n        \"gross_margin\": null,\n        \"contribution_margin\": -500,\n        \"contribution_margin_pct\": null,\n        \"flt_values\": {},\n        \"is_unallocated\": true\n      }\n    ],\n    \"financial_line_types\": [\n      {\n        \"id\": 1,\n        \"name\": \"Shipping\",\n        \"classification\": \"COST\",\n        \"total\": 3200\n      }\n    ],\n    \"indirect_cost_types\": [\n      {\n        \"id\": 2,\n        \"name\": \"Marketing\",\n        \"total\": 1700\n      },\n      {\n        \"id\": 5,\n        \"name\": \"Software\",\n        \"total\": 600\n      }\n    ],\n    \"grand_totals\": {\n      \"revenue\": 45000,\n      \"cogs\": 25000,\n      \"total_cost\": 30500,\n      \"profit\": 14500,\n      \"margin\": 32.22,\n      \"gross_profit\": 20000,\n      \"gross_margin\": 44.44,\n      \"indirect_cost\": 2300,\n      \"contribution_margin\": 14500,\n      \"contribution_margin_pct\": 32.22,\n      \"unallocated_indirect_cost\": 750,\n      \"operating_profit\": 13750\n    },\n    \"comparison\": {\n      \"mode\": \"previous_period\",\n      \"window\": {\n        \"start_date\": \"2026-05-01\",\n        \"end_date\": \"2026-05-31\"\n      },\n      \"revenue\": 41000,\n      \"cogs\": 23500,\n      \"total_cost\": 28100,\n      \"profit\": 12900,\n      \"margin\": 31.46,\n      \"gross_profit\": 17500,\n      \"gross_margin\": 42.68,\n      \"indirect_cost\": 2100,\n      \"contribution_margin\": 12900,\n      \"contribution_margin_pct\": 31.46,\n      \"unallocated_indirect_cost\": 600,\n      \"operating_profit\": 12300,\n      \"ad_spend\": 900\n    }\n  }\n}"}]},{"name":"Get Profitability Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/drilldown?dimension=brand&dimension_value=Acme","host":["{{baseUrl}}"],"path":["api","reporting","profitability","drilldown"],"query":[{"key":"dimension","value":"brand","description":"Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags (nullable). customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Acme","description":"Value of the dimension to filter by (nullable)","disabled":true}]},"description":"Returns paginated order-level drilldown for a specific dimension value, showing revenue, COGS, total cost, profit, and margin per order. Includes financial line type column values when flt_ids[] is provided.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/drilldown?dimension=brand&dimension_value=Acme","host":["{{baseUrl}}"],"path":["api","reporting","profitability","drilldown"],"query":[{"key":"dimension","value":"brand","description":"Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags (nullable). customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Acme","description":"Value of the dimension to filter by (nullable)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"sales_order_number\": \"SO-1001\",\n      \"order_date\": \"2024-06-10\",\n      \"sales_channel\": \"Shopify\",\n      \"product_revenue\": 150,\n      \"revenue\": 162,\n      \"cogs\": 80,\n      \"total_cost\": 95,\n      \"profit\": 67,\n      \"margin\": 41.36,\n      \"flt_values\": {\n        \"1\": 12,\n        \"2\": 3\n      }\n    }\n  ],\n  \"per_page\": 25,\n  \"total\": 145,\n  \"last_page\": 6,\n  \"totals\": {\n    \"revenue\": 23490,\n    \"cogs\": 11500,\n    \"total_cost\": 13775,\n    \"profit\": 9715,\n    \"margin\": 41.36\n  },\n  \"flt_headers\": [\n    {\n      \"id\": 1,\n      \"name\": \"Shipping\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Fulfilment Fee\"\n    }\n  ]\n}"}]},{"name":"Get Order Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/drilldown/{salesOrder}/breakdown","host":["{{baseUrl}}"],"path":["api","reporting","profitability","drilldown",":salesOrder","breakdown"],"variable":[{"key":"salesOrder","value":"1001","description":"Sales Order ID"}]},"description":"Returns a full financial breakdown for a single order, including all line items, COGS, allocated costs, and financial line type values.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nEach line's financials and the order summary include indirect_cost_allocated (this order's revenue-weighted share of cost-entry / overhead allocations) and contribution_profit (profit minus that indirect share). These are standalone figures layered on top of profit — profit and total_cost are unchanged by them."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/drilldown/{salesOrder}/breakdown","host":["{{baseUrl}}"],"path":["api","reporting","profitability","drilldown",":salesOrder","breakdown"],"variable":[{"key":"salesOrder","value":"1001","description":"Sales Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"order\": {\n    \"id\": 123,\n    \"sales_order_number\": \"SO-00123\",\n    \"order_date\": \"2026-06-15\",\n    \"sales_channel\": \"Shopify US\"\n  },\n  \"lines\": [\n    {\n      \"id\": 5541,\n      \"product_id\": 88,\n      \"sku\": \"WGT-001\",\n      \"name\": \"Widget A\",\n      \"quantity\": 3,\n      \"financials\": {\n        \"revenue\": 150,\n        \"revenue_allocated\": 0,\n        \"credits\": 0,\n        \"discount\": 0,\n        \"total_revenue\": 150,\n        \"cogs\": 60,\n        \"cost_allocated\": 12,\n        \"cogs_returned\": 0,\n        \"total_cost\": 72,\n        \"profit\": 78,\n        \"profit_margin\": 52,\n        \"indirect_cost_allocated\": 9.5,\n        \"contribution_profit\": 68.5\n      }\n    }\n  ],\n  \"financial_lines\": [],\n  \"summary\": {\n    \"total_revenue\": 150,\n    \"total_cogs\": 60,\n    \"revenue_lines_total\": 0,\n    \"cost_lines_total\": 12,\n    \"total_cost\": 72,\n    \"profit\": 78,\n    \"margin\": 52,\n    \"indirect_cost_allocated\": 9.5,\n    \"contribution_profit\": 68.5,\n    \"contribution_margin\": 45.67\n  }\n}"}]},{"name":"Get Financial Line Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/financial-line-types","host":["{{baseUrl}}"],"path":["api","reporting","profitability","financial-line-types"]},"description":"Returns all financial line types configured for the current tenant. Used to populate the drilldown column selector.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/financial-line-types","host":["{{baseUrl}}"],"path":["api","reporting","profitability","financial-line-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Shipping\",\n      \"type\": \"cost\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Fulfilment Fee\",\n      \"type\": \"cost\"\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Platform Fee\",\n      \"type\": \"cost\"\n    }\n  ]\n}"}]},{"name":"List Indirect Cost Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/indirect-cost-types","host":["{{baseUrl}}"],"path":["api","reporting","profitability","indirect-cost-types"]},"description":"Lists the indirect cost types that have cost-entry allocation activity inside the report window, with allocated totals. Drives the per-type breakdown columns and the indirect cost type filter. Type id 0 represents allocations whose cost entry has no type (Uncategorized).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/indirect-cost-types","host":["{{baseUrl}}"],"path":["api","reporting","profitability","indirect-cost-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"name\": \"Marketing\",\n      \"total\": 1700\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Software\",\n      \"total\": 600\n    },\n    {\n      \"id\": 0,\n      \"name\": \"Uncategorized\",\n      \"total\": 120\n    }\n  ]\n}"}]},{"name":"Get Indirect Cost Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/profitability/indirect-cost-drilldown?group_by=brand&dimension_value=Acme Brand","host":["{{baseUrl}}"],"path":["api","reporting","profitability","indirect-cost-drilldown"],"query":[{"key":"group_by","value":"brand","description":"Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | attribute | customer_tags. Required unless scope=unallocated. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Acme Brand","description":"The dimension row value to drill into (use 'Non-Product / Unallocated' for the unattributed row). Required unless scope=unallocated.","disabled":true}]},"description":"Itemizes the cost-entry activity behind a Profitability Report figure.\n\nscope=allocated returns the cost allocations attributed to one dimension row (matching the row's indirect cost amount exactly). scope=unallocated returns cost entries with an unallocated remainder in the window — the amount deducted from Contribution Margin to derive Operating Profit. Draft cost entries are excluded.\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/profitability/indirect-cost-drilldown?group_by=brand&dimension_value=Acme Brand","host":["{{baseUrl}}"],"path":["api","reporting","profitability","indirect-cost-drilldown"],"query":[{"key":"group_by","value":"brand","description":"Dimension: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | attribute | customer_tags. Required unless scope=unallocated. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Acme Brand","description":"The dimension row value to drill into (use 'Non-Product / Unallocated' for the unattributed row). Required unless scope=unallocated.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"cost_allocation_id\": 991,\n      \"cost_entry_id\": 123,\n      \"description\": \"June Marketing Campaign\",\n      \"cost_entry_type\": {\n        \"id\": 2,\n        \"name\": \"Marketing\"\n      },\n      \"allocatable_type\": \"Product\",\n      \"allocatable_label\": \"WGT-001 — Widget A\",\n      \"allocation_date\": \"2026-06-30\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"proration_strategy\": \"revenue_based\",\n      \"amount_in_tenant_currency\": 1200\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 3,\n  \"last_page\": 1\n}"}]},{"name":"Get Contribution Margin Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/summary","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","summary"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns the account-wide profitability summary as a single `Overall` row: total revenue, COGS, allocated costs, gross profit, contribution dollars, margin percentages, units sold, and order count. Entity filters (product, brand, supplier, sales channel) narrow the underlying sales data; `cost_entry_type_id` narrows the allocated-cost figures.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/summary","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimension\": \"summary\",\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"total_revenue\": 262480,\n    \"total_cogs\": 141739.2,\n    \"total_allocated_costs\": 26248,\n    \"total_gross_profit\": 120740.8,\n    \"total_contribution_dollars\": 94492.8,\n    \"overall_gross_profit_margin\": 46,\n    \"overall_contribution_margin\": 36,\n    \"total_units_sold\": 10499,\n    \"total_order_count\": 8321,\n    \"total_ad_spend\": 0,\n    \"total_attributed_sales\": 0,\n    \"overall_acos\": null,\n    \"overall_tacos\": 0,\n    \"overall_break_even_acos\": 36,\n    \"lines\": [\n      {\n        \"entity_id\": null,\n        \"entity_name\": \"Overall\",\n        \"entity_type\": \"summary\",\n        \"revenue\": 262480,\n        \"cogs\": 141739.2,\n        \"allocated_costs\": 26248,\n        \"gross_profit\": 120740.8,\n        \"contribution_dollars\": 94492.8,\n        \"gross_profit_margin\": 46,\n        \"contribution_margin\": 36,\n        \"units_sold\": 10499,\n        \"order_count\": 8321,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 36,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Contribution Margin by Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-product","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-product"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns a profitability breakdown per product. Each row includes the product's SKU, brand, and default supplier alongside revenue, COGS, allocated costs, gross profit, contribution dollars, and margin percentages. Products that received cost allocations but had no sales in the period also appear, with zero revenue and negative contribution — so allocated spend never silently disappears from the report.\n\nWith `include_ad_metrics=true`, each row also carries Amazon Ads spend, ad-attributed sales, ACoS (ad spend ÷ attributed sales), TACoS (ad spend ÷ total revenue), and break-even ACoS (the ACoS at which the product's contribution reaches zero).\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-product","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-product"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimension\": \"product\",\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"total_revenue\": 78375,\n    \"total_cogs\": 38281.25,\n    \"total_allocated_costs\": 8682.5,\n    \"total_gross_profit\": 40093.75,\n    \"total_contribution_dollars\": 31411.25,\n    \"overall_gross_profit_margin\": 51.16,\n    \"overall_contribution_margin\": 40.08,\n    \"total_units_sold\": 2532,\n    \"total_order_count\": 2302,\n    \"total_ad_spend\": 3990,\n    \"total_attributed_sales\": 31250,\n    \"overall_acos\": 12.77,\n    \"overall_tacos\": 5.09,\n    \"overall_break_even_acos\": 45.17,\n    \"lines\": [\n      {\n        \"entity_id\": 812,\n        \"entity_name\": \"5m LED Light Strip - RGB\",\n        \"entity_type\": \"product\",\n        \"revenue\": 48250,\n        \"cogs\": 21712.5,\n        \"allocated_costs\": 5430,\n        \"gross_profit\": 26537.5,\n        \"contribution_dollars\": 21107.5,\n        \"gross_profit_margin\": 55,\n        \"contribution_margin\": 43.75,\n        \"units_sold\": 1930,\n        \"order_count\": 1712,\n        \"ad_spend\": 2410,\n        \"attributed_sales\": 19850,\n        \"acos\": 12.14,\n        \"tacos\": 4.99,\n        \"break_even_acos\": 48.74,\n        \"sku\": \"LED-STRIP-5M-RGB\",\n        \"brand_name\": \"Lumina\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Shenzhen Lumina Electronics\"\n      },\n      {\n        \"entity_id\": 654,\n        \"entity_name\": \"Desk Glow Lamp - Walnut\",\n        \"entity_type\": \"product\",\n        \"revenue\": 30125,\n        \"cogs\": 16568.75,\n        \"allocated_costs\": 3012.5,\n        \"gross_profit\": 13556.25,\n        \"contribution_dollars\": 10543.75,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 602,\n        \"order_count\": 590,\n        \"ad_spend\": 1520,\n        \"attributed_sales\": 11400,\n        \"acos\": 13.33,\n        \"tacos\": 5.05,\n        \"break_even_acos\": 40.05,\n        \"sku\": \"GLOW-DESK-WAL\",\n        \"brand_name\": \"NovaGlow\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Pacific Coast Distributors\"\n      },\n      {\n        \"entity_id\": 977,\n        \"entity_name\": \"Solar Path Light 4-Pack\",\n        \"entity_type\": \"product\",\n        \"revenue\": 0,\n        \"cogs\": 0,\n        \"allocated_costs\": 240,\n        \"gross_profit\": 0,\n        \"contribution_dollars\": -240,\n        \"gross_profit_margin\": 0,\n        \"contribution_margin\": 0,\n        \"units_sold\": 0,\n        \"order_count\": 0,\n        \"ad_spend\": 60,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": null,\n        \"break_even_acos\": null,\n        \"sku\": \"SOLAR-PATH-4PK\",\n        \"brand_name\": \"Lumina\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Shenzhen Lumina Electronics\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Contribution Margin by Brand","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-brand","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-brand"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns a profitability breakdown per brand. Allocated costs include both costs allocated directly to a brand and product-level allocations rolled up to the product's brand. Sales of products without a brand are grouped under a `No Brand` row with `entity_id: 0`. Brands with cost allocations but no sales in the period also appear with zero revenue. `include_ad_metrics=true` adds Amazon Ads spend and attributed sales rolled up to brand level.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-brand","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-brand"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimension\": \"brand\",\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"total_revenue\": 168120,\n    \"total_cogs\": 85277.2,\n    \"total_allocated_costs\": 16288,\n    \"total_gross_profit\": 82842.8,\n    \"total_contribution_dollars\": 66554.8,\n    \"overall_gross_profit_margin\": 49.28,\n    \"overall_contribution_margin\": 39.59,\n    \"total_units_sold\": 5619,\n    \"total_order_count\": 5003,\n    \"total_ad_spend\": 0,\n    \"total_attributed_sales\": 0,\n    \"overall_acos\": null,\n    \"overall_tacos\": 0,\n    \"overall_break_even_acos\": 39.59,\n    \"lines\": [\n      {\n        \"entity_id\": 14,\n        \"entity_name\": \"Lumina\",\n        \"entity_type\": \"brand\",\n        \"revenue\": 96410,\n        \"cogs\": 45312.7,\n        \"allocated_costs\": 9641,\n        \"gross_profit\": 51097.3,\n        \"contribution_dollars\": 41456.3,\n        \"gross_profit_margin\": 53,\n        \"contribution_margin\": 43,\n        \"units_sold\": 3960,\n        \"order_count\": 3421,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 43,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 22,\n        \"entity_name\": \"NovaGlow\",\n        \"entity_type\": \"brand\",\n        \"revenue\": 61230,\n        \"cogs\": 33676.5,\n        \"allocated_costs\": 6123,\n        \"gross_profit\": 27553.5,\n        \"contribution_dollars\": 21430.5,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 1240,\n        \"order_count\": 1180,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 0,\n        \"entity_name\": \"No Brand\",\n        \"entity_type\": \"brand\",\n        \"revenue\": 10480,\n        \"cogs\": 6288,\n        \"allocated_costs\": 524,\n        \"gross_profit\": 4192,\n        \"contribution_dollars\": 3668,\n        \"gross_profit_margin\": 40,\n        \"contribution_margin\": 35,\n        \"units_sold\": 419,\n        \"order_count\": 402,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Contribution Margin by Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-supplier","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-supplier"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns a profitability breakdown per supplier. Products are attributed to their default supplier; sales of products without a default supplier are grouped under a `No Supplier` row with `entity_id: 0`. Allocated costs include both costs allocated directly to a supplier and product-level allocations rolled up via the product's default supplier. Suppliers with cost allocations but no sales in the period also appear with zero revenue. `include_ad_metrics=true` adds Amazon Ads spend and attributed sales rolled up to supplier level.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-supplier","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-supplier"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimension\": \"supplier\",\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"total_revenue\": 167370,\n    \"total_cogs\": 85444.7,\n    \"total_allocated_costs\": 16274.5,\n    \"total_gross_profit\": 81925.3,\n    \"total_contribution_dollars\": 65650.8,\n    \"overall_gross_profit_margin\": 48.95,\n    \"overall_contribution_margin\": 39.22,\n    \"total_units_sold\": 5695,\n    \"total_order_count\": 5110,\n    \"total_ad_spend\": 0,\n    \"total_attributed_sales\": 0,\n    \"overall_acos\": null,\n    \"overall_tacos\": 0,\n    \"overall_break_even_acos\": 39.22,\n    \"lines\": [\n      {\n        \"entity_id\": 31,\n        \"entity_name\": \"Shenzhen Lumina Electronics\",\n        \"entity_type\": \"supplier\",\n        \"revenue\": 102340,\n        \"cogs\": 49123.2,\n        \"allocated_costs\": 10234,\n        \"gross_profit\": 53216.8,\n        \"contribution_dollars\": 42982.8,\n        \"gross_profit_margin\": 52,\n        \"contribution_margin\": 42,\n        \"units_sold\": 4210,\n        \"order_count\": 3688,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 42,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 45,\n        \"entity_name\": \"Pacific Coast Distributors\",\n        \"entity_type\": \"supplier\",\n        \"revenue\": 55780,\n        \"cogs\": 30679,\n        \"allocated_costs\": 5578,\n        \"gross_profit\": 25101,\n        \"contribution_dollars\": 19523,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 1115,\n        \"order_count\": 1071,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 0,\n        \"entity_name\": \"No Supplier\",\n        \"entity_type\": \"supplier\",\n        \"revenue\": 9250,\n        \"cogs\": 5642.5,\n        \"allocated_costs\": 462.5,\n        \"gross_profit\": 3607.5,\n        \"contribution_dollars\": 3145,\n        \"gross_profit_margin\": 39,\n        \"contribution_margin\": 34,\n        \"units_sold\": 370,\n        \"order_count\": 351,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 34,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Contribution Margin by Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-sales-channel","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-sales-channel"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns a profitability breakdown per sales channel (e.g. Amazon, Shopify, eBay). The row name is the channel's connected store/integration name. Channels with cost allocations but no sales in the period also appear with zero revenue.\n\nNote: ad metrics (ad spend, attributed sales, ACoS/TACoS) are not computed for the sales-channel dimension — those fields are always zero/null here. Use the by-product or by-brand reports with `include_ad_metrics=true` for advertising performance.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/by-sales-channel","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","by-sales-channel"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dimension\": \"sales_channel\",\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"total_revenue\": 262480,\n    \"total_cogs\": 142010.8,\n    \"total_allocated_costs\": 26248,\n    \"total_gross_profit\": 120469.2,\n    \"total_contribution_dollars\": 94221.2,\n    \"overall_gross_profit_margin\": 45.9,\n    \"overall_contribution_margin\": 35.9,\n    \"total_units_sold\": 10499,\n    \"total_order_count\": 8321,\n    \"total_ad_spend\": 0,\n    \"total_attributed_sales\": 0,\n    \"overall_acos\": null,\n    \"overall_tacos\": 0,\n    \"overall_break_even_acos\": 35.9,\n    \"lines\": [\n      {\n        \"entity_id\": 3,\n        \"entity_name\": \"Amazon US\",\n        \"entity_type\": \"sales_channel\",\n        \"revenue\": 152480,\n        \"cogs\": 83864,\n        \"allocated_costs\": 15248,\n        \"gross_profit\": 68616,\n        \"contribution_dollars\": 53368,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 6099,\n        \"order_count\": 4881,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 5,\n        \"entity_name\": \"Shopify\",\n        \"entity_type\": \"sales_channel\",\n        \"revenue\": 78440,\n        \"cogs\": 40788.8,\n        \"allocated_costs\": 7844,\n        \"gross_profit\": 37651.2,\n        \"contribution_dollars\": 29807.2,\n        \"gross_profit_margin\": 48,\n        \"contribution_margin\": 38,\n        \"units_sold\": 3138,\n        \"order_count\": 2612,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 38,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      },\n      {\n        \"entity_id\": 8,\n        \"entity_name\": \"eBay\",\n        \"entity_type\": \"sales_channel\",\n        \"revenue\": 31560,\n        \"cogs\": 17358,\n        \"allocated_costs\": 3156,\n        \"gross_profit\": 14202,\n        \"contribution_dollars\": 11046,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 1262,\n        \"order_count\": 828,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": null,\n        \"brand_name\": null,\n        \"brand_id\": 3,\n        \"supplier_name\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Top Products by Contribution Margin","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/top-products","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","top-products"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns the products ranked by contribution dollars (gross profit minus allocated costs). Use `order=desc` (default) for your biggest profit contributors, or `order=asc` to surface the weakest performers. Each product row has the same shape as the by-product report lines, including SKU, brand, and default supplier.\n\nRanking note: candidates are drawn from the top revenue-generating products (twice the requested limit) before being re-ranked by contribution dollars, so a low-revenue product with very high margin can occasionally fall outside the candidate pool.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/top-products","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","top-products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"products\": [\n      {\n        \"entity_id\": 812,\n        \"entity_name\": \"5m LED Light Strip - RGB\",\n        \"entity_type\": \"product\",\n        \"revenue\": 48250,\n        \"cogs\": 21712.5,\n        \"allocated_costs\": 5430,\n        \"gross_profit\": 26537.5,\n        \"contribution_dollars\": 21107.5,\n        \"gross_profit_margin\": 55,\n        \"contribution_margin\": 43.75,\n        \"units_sold\": 1930,\n        \"order_count\": 1712,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 43.75,\n        \"sku\": \"LED-STRIP-5M-RGB\",\n        \"brand_name\": \"Lumina\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Shenzhen Lumina Electronics\"\n      },\n      {\n        \"entity_id\": 654,\n        \"entity_name\": \"Desk Glow Lamp - Walnut\",\n        \"entity_type\": \"product\",\n        \"revenue\": 30125,\n        \"cogs\": 16568.75,\n        \"allocated_costs\": 3012.5,\n        \"gross_profit\": 13556.25,\n        \"contribution_dollars\": 10543.75,\n        \"gross_profit_margin\": 45,\n        \"contribution_margin\": 35,\n        \"units_sold\": 602,\n        \"order_count\": 590,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 35,\n        \"sku\": \"GLOW-DESK-WAL\",\n        \"brand_name\": \"NovaGlow\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Pacific Coast Distributors\"\n      },\n      {\n        \"entity_id\": 721,\n        \"entity_name\": \"Smart Plug 2-Pack\",\n        \"entity_type\": \"product\",\n        \"revenue\": 18940,\n        \"cogs\": 9470,\n        \"allocated_costs\": 1894,\n        \"gross_profit\": 9470,\n        \"contribution_dollars\": 7576,\n        \"gross_profit_margin\": 50,\n        \"contribution_margin\": 40,\n        \"units_sold\": 947,\n        \"order_count\": 902,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": 40,\n        \"sku\": \"SMART-PLUG-2PK\",\n        \"brand_name\": \"Lumina\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Shenzhen Lumina Electronics\"\n      }\n    ]\n  }\n}"}]},{"name":"List Unprofitable Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/unprofitable-products","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","unprofitable-products"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns products whose contribution dollars are negative for the period — items where COGS plus allocated costs exceed revenue. This includes products with cost allocations but no sales at all (zero revenue, negative contribution). Each product row has the same shape as the by-product report lines; `count` is the number of unprofitable products returned.\n\nNote: `limit` bounds the revenue-ranked product pool that is scanned, not the number of unprofitable rows returned — with a small limit, unprofitable products outside the top-revenue pool may be missed.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/unprofitable-products","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","unprofitable-products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"count\": 2,\n    \"products\": [\n      {\n        \"entity_id\": 903,\n        \"entity_name\": \"Bluetooth Shower Speaker\",\n        \"entity_type\": \"product\",\n        \"revenue\": 4210,\n        \"cogs\": 3960,\n        \"allocated_costs\": 890,\n        \"gross_profit\": 250,\n        \"contribution_dollars\": -640,\n        \"gross_profit_margin\": 5.94,\n        \"contribution_margin\": -15.2,\n        \"units_sold\": 421,\n        \"order_count\": 415,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": 0,\n        \"break_even_acos\": -15.2,\n        \"sku\": \"BT-SHOWER-SPKR\",\n        \"brand_name\": \"NovaGlow\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Pacific Coast Distributors\"\n      },\n      {\n        \"entity_id\": 977,\n        \"entity_name\": \"Solar Path Light 4-Pack\",\n        \"entity_type\": \"product\",\n        \"revenue\": 0,\n        \"cogs\": 0,\n        \"allocated_costs\": 240,\n        \"gross_profit\": 0,\n        \"contribution_dollars\": -240,\n        \"gross_profit_margin\": 0,\n        \"contribution_margin\": 0,\n        \"units_sold\": 0,\n        \"order_count\": 0,\n        \"ad_spend\": 0,\n        \"attributed_sales\": 0,\n        \"acos\": null,\n        \"tacos\": null,\n        \"break_even_acos\": null,\n        \"sku\": \"SOLAR-PATH-4PK\",\n        \"brand_name\": \"Lumina\",\n        \"brand_id\": 3,\n        \"supplier_name\": \"Shenzhen Lumina Electronics\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Contribution Margin Cost Analysis","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/cost-analysis","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","cost-analysis"]},"description":"Contribution margin measures profitability after both cost of goods sold and allocated operating costs:\n- Gross Profit = Revenue − COGS\n- Contribution Dollars = Gross Profit − Allocated Costs\n- Contribution Margin % = Contribution Dollars ÷ Revenue × 100\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRevenue and COGS come from per-order-line financial records that are kept current by background financial calculations. Allocated costs come from the cost allocation system (cost entries prorated across products, orders, brands, suppliers, or sales channels).\n\nReturns an overview of all allocated costs feeding the contribution margin reports: the total amount allocated, how many individual allocations and distinct cost entries produced it, and three breakdowns —\n- `by_allocatable_type`: what kind of entity the costs were allocated to (products, orders, brands, suppliers, sales channels). `full_type` is the internal type identifier; `type` is its short name.\n- `by_cost_entry_type`: the user-defined cost categories (e.g. Amazon Advertising, Warehouse Rent). Allocations whose cost entry has no type are grouped under `Uncategorized`.\n- `by_proration_strategy`: how each allocation was split (`revenue_based`, `cost_based`, `weight_based`, `volume_based`, `quantity_based`, `specific_line`, or `manual`).\n\nAmounts are in the account's base currency. Breakdown rows are sorted by total amount, descending.\n\nDate filtering: `date_from` and `date_to` must BOTH be provided for date filtering to apply — if either is omitted the report covers all available history. Sales figures are filtered by order date; allocated costs are matched by their allocation period when one is set (any overlap with the requested range counts), otherwise by their allocation date.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/contribution-margin/cost-analysis","host":["{{baseUrl}}"],"path":["api","reporting","contribution-margin","cost-analysis"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"date_from\": \"2026-06-01\",\n    \"date_to\": \"2026-06-30\",\n    \"summary\": {\n      \"total_allocated\": 26248,\n      \"allocation_count\": 1842,\n      \"cost_entry_count\": 96\n    },\n    \"by_allocatable_type\": [\n      {\n        \"type\": \"Product\",\n        \"full_type\": \"App\\\\Models\\\\Product\",\n        \"allocation_count\": 1520,\n        \"total_amount\": 19870.5\n      },\n      {\n        \"type\": \"SalesChannel\",\n        \"full_type\": \"App\\\\Models\\\\SalesChannel\",\n        \"allocation_count\": 214,\n        \"total_amount\": 4562.25\n      },\n      {\n        \"type\": \"ProductBrand\",\n        \"full_type\": \"App\\\\Models\\\\ProductBrand\",\n        \"allocation_count\": 108,\n        \"total_amount\": 1815.25\n      }\n    ],\n    \"by_cost_entry_type\": [\n      {\n        \"type_id\": 4,\n        \"type_name\": \"Amazon Advertising\",\n        \"allocation_count\": 1180,\n        \"total_amount\": 14210\n      },\n      {\n        \"type_id\": 7,\n        \"type_name\": \"Warehouse Rent\",\n        \"allocation_count\": 402,\n        \"total_amount\": 8450\n      },\n      {\n        \"type_id\": null,\n        \"type_name\": \"Uncategorized\",\n        \"allocation_count\": 260,\n        \"total_amount\": 3588\n      }\n    ],\n    \"by_proration_strategy\": [\n      {\n        \"strategy\": \"revenue_based\",\n        \"allocation_count\": 1102,\n        \"total_amount\": 15980.75\n      },\n      {\n        \"strategy\": \"quantity_based\",\n        \"allocation_count\": 526,\n        \"total_amount\": 7412.25\n      },\n      {\n        \"strategy\": \"manual\",\n        \"allocation_count\": 214,\n        \"total_amount\": 2855\n      }\n    ]\n  }\n}"}]},{"name":"Get Sales Tax Liability","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/liability?date_from=2026-01-01&date_to=2026-03-31&group_by=state","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","liability"],"query":[{"key":"date_from","value":"2026-01-01","description":"Required. Start of the reporting period (date or datetime; treated as app timezone).","disabled":true},{"key":"date_to","value":"2026-03-31","description":"Required. End of the reporting period. Must be on or after date_from.","disabled":true},{"key":"group_by","value":"state","description":"Optional. Aggregation lens: state (one row per destination region) | in_state_out_of_state (collapses to two rows: In-State home jurisdiction vs Out-of-State) | responsibility (two rows: Seller-collected vs Marketplace facilitator) | state_responsibility (one row per state, each carrying a seller_net_tax / marketplace_net_tax split). Defaults to state.","disabled":true}]},"description":"Sales Tax Liability Report: tax collected and sales aggregated by destination jurisdiction (country + region), with a taxable / non-taxable split and Net Tax (tax collected minus refunded tax from credits). Amounts are converted to the tenant base currency.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports).\n\nRequired parameters:\n- date_from: report period start\n- date_to: report period end (>= date_from)\n\nOptional:\n- channel_ids[]: restrict to specific sales channels\n- country_code: destination country ISO code (max 3)\n- order_statuses[]: draft | reserved | open | closed (default open + closed)\n- province_code: destination region/state code (max 10)\n- group_by: state | in_state_out_of_state | responsibility | state_responsibility (default state)\n\nThe `responsibility` and `state_responsibility` lenses (Phase 2) split tax by who collects & remits it: the seller, or a marketplace facilitator (Amazon/eBay/Walmart/Temu/Faire by default). Rows then also carry tax_collection_responsibility, is_default_classification, seller_net_tax and marketplace_net_tax. The `is_home_state` flag marks the tenant's resolved home nexus jurisdiction. Rows are sorted by net_tax descending."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/liability?date_from=2026-01-01&date_to=2026-03-31&group_by=state","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","liability"],"query":[{"key":"date_from","value":"2026-01-01","description":"Required. Start of the reporting period (date or datetime; treated as app timezone).","disabled":true},{"key":"date_to","value":"2026-03-31","description":"Required. End of the reporting period. Must be on or after date_from.","disabled":true},{"key":"group_by","value":"state","description":"Optional. Aggregation lens: state (one row per destination region) | in_state_out_of_state (collapses to two rows: In-State home jurisdiction vs Out-of-State) | responsibility (two rows: Seller-collected vs Marketplace facilitator) | state_responsibility (one row per state, each carrying a seller_net_tax / marketplace_net_tax split). Defaults to state.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"country_code\": \"US\",\n      \"province_code\": \"CA\",\n      \"province\": \"California\",\n      \"is_home_state\": true,\n      \"order_count\": 142,\n      \"gross_sales\": \"48230.50\",\n      \"taxable_sales\": \"41200.00\",\n      \"non_taxable_sales\": \"7030.50\",\n      \"tax_collected\": \"3502.00\",\n      \"refunded_tax\": \"120.50\",\n      \"net_tax\": \"3381.50\"\n    },\n    {\n      \"country_code\": \"US\",\n      \"province_code\": \"NY\",\n      \"province\": \"New York\",\n      \"is_home_state\": false,\n      \"order_count\": 88,\n      \"gross_sales\": \"26110.00\",\n      \"taxable_sales\": \"24000.00\",\n      \"non_taxable_sales\": \"2110.00\",\n      \"tax_collected\": \"2040.00\",\n      \"refunded_tax\": \"0.00\",\n      \"net_tax\": \"2040.00\"\n    }\n  ],\n  \"totals\": {\n    \"order_count\": 230,\n    \"gross_sales\": \"74340.50\",\n    \"taxable_sales\": \"65200.00\",\n    \"non_taxable_sales\": \"9140.50\",\n    \"tax_collected\": \"5542.00\",\n    \"refunded_tax\": \"120.50\",\n    \"net_tax\": \"5421.50\"\n  },\n  \"currency\": \"USD\",\n  \"period\": {\n    \"date_from\": \"2026-01-01\",\n    \"date_to\": \"2026-03-31\"\n  }\n}"}]},{"name":"Get Sales Tax Transactions (Drill-Down)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/liability/transactions?date_from=2026-01-01&date_to=2026-03-31&page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","liability","transactions"],"query":[{"key":"date_from","value":"2026-01-01","description":"Required. Start of the reporting period (date or datetime; treated as app timezone).","disabled":true},{"key":"date_to","value":"2026-03-31","description":"Required. End of the reporting period. Must be on or after date_from.","disabled":true},{"key":"page","value":"1","description":"Optional. Page number (>= 1). Defaults to 1.","disabled":true},{"key":"per_page","value":"15","description":"Optional. Items per page (1-200). Defaults to 15.","disabled":true}]},"description":"Paginated transaction drill-down behind a single jurisdiction row of the liability report. Returns the underlying orders and credits (credit amounts are negative) that compose the aggregated row, filtered by the same parameters plus the selected province_code / country_code.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports).\n\nRequired parameters:\n- date_from, date_to\n\nOptional: channel_ids[], country_code, order_statuses[], province_code, page, per_page (1-200).\n\nResults are a UNION of sales orders and sales credits ordered by transaction date descending, returned in the standard Laravel pagination envelope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/liability/transactions?date_from=2026-01-01&date_to=2026-03-31&page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","liability","transactions"],"query":[{"key":"date_from","value":"2026-01-01","description":"Required. Start of the reporting period (date or datetime; treated as app timezone).","disabled":true},{"key":"date_to","value":"2026-03-31","description":"Required. End of the reporting period. Must be on or after date_from.","disabled":true},{"key":"page","value":"1","description":"Optional. Page number (>= 1). Defaults to 1.","disabled":true},{"key":"per_page","value":"15","description":"Optional. Items per page (1-200). Defaults to 15.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"document_type\": \"order\",\n      \"order_id\": 33421,\n      \"number\": \"SO-10044\",\n      \"date\": \"2026-03-28\",\n      \"channel\": \"Shopify US\",\n      \"customer_name\": \"Jane Doe\",\n      \"province_code\": \"CA\",\n      \"taxable_amount\": \"310.00\",\n      \"tax\": \"26.35\"\n    },\n    {\n      \"document_type\": \"credit\",\n      \"order_id\": 33380,\n      \"number\": \"CN-2051\",\n      \"date\": \"2026-03-20\",\n      \"channel\": \"Shopify US\",\n      \"customer_name\": \"John Smith\",\n      \"province_code\": \"CA\",\n      \"taxable_amount\": \"-45.00\",\n      \"tax\": \"-3.83\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 8,\n  \"per_page\": 15,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reporting/sales-tax/liability/transactions?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reporting/sales-tax/liability/transactions?page=8\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/reporting/sales-tax/liability/transactions?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/sales-tax/liability/transactions\"\n}"}]},{"name":"Export Sales Tax Liability","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/liability/export?date_from=2026-01-01&date_to=2026-03-31&group_by=state&format=csv","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","liability","export"],"query":[{"key":"date_from","value":"2026-01-01","description":"Required. Start of the reporting period (date or datetime; treated as app timezone).","disabled":true},{"key":"date_to","value":"2026-03-31","description":"Required. End of the reporting period. Must be on or after date_from.","disabled":true},{"key":"group_by","value":"state","description":"Optional. state | in_state_out_of_state (default state).","disabled":true},{"key":"format","value":"csv","description":"Optional. Export format: csv | xlsx | pdf. Defaults to csv.","disabled":true}]},"description":"Exports the Sales Tax Liability Report as a downloadable file (CSV, XLSX, or PDF). Accepts the same filter parameters as the liability report. The response is a binary file download (Content-Type varies: text/csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, or application/pdf), not JSON. Columns: Country, Region, Region Code, In-State, Orders, Gross Sales, Taxable Sales, Non-Taxable Sales, Tax Collected, Refunded Tax, Net Tax, with a trailing TOTAL row.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports)."}},{"name":"Get Channel Tax Responsibility","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/channel-responsibility","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","channel-responsibility"]},"description":"Lists every sales channel (integration instance) with its resolved tax-collection responsibility for the Sales Tax Liability Report (Phase 2). Each channel is classified as `seller` (Seller-collected) or `marketplace_facilitator` (Marketplace facilitator).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe `source` field indicates how the classification was resolved:\n- override: a manual per-channel override was saved (is_default = false)\n- default: resolved from the built-in marketplace-facilitator map (Amazon, eBay, Walmart, Temu, Faire => marketplace_facilitator; Shopify, WooCommerce, BigCommerce, API Sales Channel, SKU.io => seller)\n- unclassified: the channel's integration name is in neither map, so it defaulted conservatively to seller and is flagged for review (is_unclassified = true)\n\nThe top-level `has_unclassified` flag is true when at least one channel is unclassified, so the UI can surface a review banner.\n\nAuthentication: Requires Bearer token (scope rw:reports)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/channel-responsibility","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","channel-responsibility"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 12,\n      \"name\": \"Amazon US\",\n      \"integration_name\": \"Amazon\",\n      \"tax_collection_responsibility\": \"marketplace_facilitator\",\n      \"tax_collection_responsibility_label\": \"Marketplace facilitator\",\n      \"source\": \"default\",\n      \"is_default\": true,\n      \"is_unclassified\": false\n    },\n    {\n      \"integration_instance_id\": 8,\n      \"name\": \"Shopify US\",\n      \"integration_name\": \"Shopify\",\n      \"tax_collection_responsibility\": \"seller\",\n      \"tax_collection_responsibility_label\": \"Seller-collected\",\n      \"source\": \"default\",\n      \"is_default\": true,\n      \"is_unclassified\": false\n    },\n    {\n      \"integration_instance_id\": 21,\n      \"name\": \"TikTok Shop\",\n      \"integration_name\": \"TikTok\",\n      \"tax_collection_responsibility\": \"seller\",\n      \"tax_collection_responsibility_label\": \"Seller-collected\",\n      \"source\": \"unclassified\",\n      \"is_default\": true,\n      \"is_unclassified\": true\n    }\n  ],\n  \"has_unclassified\": true\n}"}]},{"name":"Update Channel Tax Responsibility","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/channel-responsibility/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","channel-responsibility",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"8","description":"Required. The integration instance (sales channel) id whose tax-collection responsibility is being overridden."}]},"description":"Overrides a single sales channel's tax-collection responsibility (Phase 2). Saving an override sets `source` to override and `is_default` to false for that channel; it persists to integration_instances.tax_collection_responsibility and immediately affects the responsibility / state_responsibility lenses of the Sales Tax Liability Report.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- tax_collection_responsibility (required): seller | marketplace_facilitator\n\nAuthentication: Requires Bearer token (scope rw:reports).","body":{"mode":"raw","raw":"{\n  \"tax_collection_responsibility\": \"marketplace_facilitator\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/channel-responsibility/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","channel-responsibility",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"8","description":"Required. The integration instance (sales channel) id whose tax-collection responsibility is being overridden."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 8,\n    \"name\": \"Shopify US\",\n    \"integration_name\": \"Shopify\",\n    \"tax_collection_responsibility\": \"marketplace_facilitator\",\n    \"tax_collection_responsibility_label\": \"Marketplace facilitator\",\n    \"source\": \"override\",\n    \"is_default\": false,\n    \"is_unclassified\": false\n  }\n}"}]},{"name":"Get Economic Nexus Exposure","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus"]},"description":"Economic Nexus Monitoring dashboard (Phase 3). Returns one row per destination jurisdiction (state/region) with measured sales and transaction counts compared against that jurisdiction's configured economic-nexus threshold, a computed status, and the percent-of-threshold.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nMeasured volume is computed per jurisdiction over that jurisdiction's own measurement window (rolling 12 months, calendar year, or previous-or-current calendar year), honouring each threshold's counts_marketplace_sales and counts_exempt_sales flags.\n\nStatus values:\n- registered: tenant is registered in the jurisdiction (reported regardless of volume).\n- threshold_met: measured volume meets/exceeds the threshold and the tenant is NOT registered.\n- approaching: measured volume is at or above warning_threshold_percent of the threshold but below it.\n- not_approaching: measured volume is comfortably below the threshold.\n- no_threshold: no threshold configured for the jurisdiction.\n\nResults are read from a per-tenant cache populated by the recompute job; computed_at is the cache timestamp (null if never computed).\n\nAuthentication: Requires Bearer token (scope rw:reports)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"country_code\": \"US\",\n      \"region_code\": \"CA\",\n      \"region\": \"California\",\n      \"measured_sales\": \"612450.00\",\n      \"measured_transactions\": 4120,\n      \"threshold_amount\": \"500000.00\",\n      \"threshold_transaction_count\": null,\n      \"measurement_period\": \"previous_or_current_calendar_year\",\n      \"measurement_period_label\": \"Previous or current calendar year\",\n      \"percent_of_threshold\": 122.49,\n      \"is_registered\": false,\n      \"status\": \"threshold_met\",\n      \"status_label\": \"Threshold met\"\n    },\n    {\n      \"country_code\": \"US\",\n      \"region_code\": \"TX\",\n      \"region\": \"Texas\",\n      \"measured_sales\": \"421000.00\",\n      \"measured_transactions\": 1890,\n      \"threshold_amount\": \"500000.00\",\n      \"threshold_transaction_count\": null,\n      \"measurement_period\": \"previous_or_current_calendar_year\",\n      \"measurement_period_label\": \"Previous or current calendar year\",\n      \"percent_of_threshold\": 84.2,\n      \"is_registered\": false,\n      \"status\": \"approaching\",\n      \"status_label\": \"Approaching\"\n    },\n    {\n      \"country_code\": \"US\",\n      \"region_code\": \"NY\",\n      \"region\": \"New York\",\n      \"measured_sales\": \"95300.00\",\n      \"measured_transactions\": 540,\n      \"threshold_amount\": \"500000.00\",\n      \"threshold_transaction_count\": 100,\n      \"measurement_period\": \"previous_or_current_calendar_year\",\n      \"measurement_period_label\": \"Previous or current calendar year\",\n      \"percent_of_threshold\": 540,\n      \"is_registered\": true,\n      \"status\": \"registered\",\n      \"status_label\": \"Registered\"\n    }\n  ],\n  \"currency\": \"USD\",\n  \"computed_at\": \"2026-06-09T14:05:22+00:00\"\n}"}]},{"name":"Recompute Economic Nexus Exposure","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/recompute","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","recompute"]},"description":"Dispatches the 'Recompute Nexus Exposure' tracked background job (Phase 3), which measures sales by jurisdiction and refreshes the per-tenant nexus exposure cache read by GET /api/reporting/sales-tax/nexus. Progress is reported through the tracked job log endpoints.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- country_code (optional): destination country ISO code; uppercased server-side. Defaults to US.\n\nReturns the tracked_job_log_id so the frontend can follow progress. A second dispatch is rejected with 409 while a recompute is already queued or running.\n\nAuthentication: Requires Bearer token (scope rw:reports).","body":{"mode":"raw","raw":"{\n  \"country_code\": \"US\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/recompute","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","recompute"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8842\n  },\n  \"message\": \"Nexus exposure recompute started.\"\n}"}]},{"name":"List Economic Nexus Thresholds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/thresholds","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","thresholds"]},"description":"Lists every configured economic-nexus threshold (Phase 3) — one per jurisdiction. Each threshold defines the dollar amount and/or transaction count, how they combine (threshold_logic), the measurement window, and whether marketplace-facilitated and exempt sales count toward the measured volume.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/thresholds","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","thresholds"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"country_code\": \"US\",\n      \"region_code\": \"CA\",\n      \"threshold_amount\": \"500000.00\",\n      \"threshold_transaction_count\": null,\n      \"threshold_logic\": \"or\",\n      \"threshold_logic_label\": \"Amount or transactions\",\n      \"measurement_period\": \"previous_or_current_calendar_year\",\n      \"measurement_period_label\": \"Previous or current calendar year\",\n      \"counts_marketplace_sales\": false,\n      \"counts_exempt_sales\": true,\n      \"effective_from\": \"2019-04-01\",\n      \"notes\": \"Wayfair economic nexus threshold.\"\n    },\n    {\n      \"id\": 12,\n      \"country_code\": \"US\",\n      \"region_code\": \"NY\",\n      \"threshold_amount\": \"500000.00\",\n      \"threshold_transaction_count\": 100,\n      \"threshold_logic\": \"and\",\n      \"threshold_logic_label\": \"Amount and transactions\",\n      \"measurement_period\": \"previous_or_current_calendar_year\",\n      \"measurement_period_label\": \"Previous or current calendar year\",\n      \"counts_marketplace_sales\": false,\n      \"counts_exempt_sales\": true,\n      \"effective_from\": \"2019-06-21\",\n      \"notes\": null\n    }\n  ]\n}"}]},{"name":"Update Economic Nexus Threshold","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/thresholds/{taxNexusThreshold}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","thresholds",":taxNexusThreshold"],"variable":[{"key":"taxNexusThreshold","value":"5","description":"Required. The economic-nexus threshold id being updated."}]},"description":"Updates a single jurisdiction's economic-nexus threshold config (Phase 3). All fields are optional; only the supplied fields change.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- threshold_amount (nullable, numeric >= 0): dollar threshold; null to disable the amount test.\n- threshold_transaction_count (nullable, integer >= 0): transaction-count threshold; null to disable the count test.\n- threshold_logic (sometimes): and | or — whether both or either test triggers nexus.\n- measurement_period (sometimes): rolling_12_months | calendar_year | previous_or_current_calendar_year.\n- counts_marketplace_sales (sometimes, boolean): whether marketplace-facilitated sales count toward measured volume.\n- counts_exempt_sales (sometimes, boolean): whether tax-exempt sales count toward measured volume.\n- effective_from (nullable, date): when the threshold takes effect.\n- notes (nullable, string <= 255).\n\nAuthentication: Requires Bearer token (scope rw:reports).","body":{"mode":"raw","raw":"{\n  \"threshold_amount\": 500000,\n  \"threshold_transaction_count\": 200,\n  \"threshold_logic\": \"or\",\n  \"measurement_period\": \"previous_or_current_calendar_year\",\n  \"counts_marketplace_sales\": false,\n  \"counts_exempt_sales\": true,\n  \"effective_from\": \"2019-04-01\",\n  \"notes\": \"Wayfair economic nexus threshold.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/thresholds/{taxNexusThreshold}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","thresholds",":taxNexusThreshold"],"variable":[{"key":"taxNexusThreshold","value":"5","description":"Required. The economic-nexus threshold id being updated."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"country_code\": \"US\",\n    \"region_code\": \"CA\",\n    \"threshold_amount\": \"500000.00\",\n    \"threshold_transaction_count\": 200,\n    \"threshold_logic\": \"or\",\n    \"threshold_logic_label\": \"Amount or transactions\",\n    \"measurement_period\": \"previous_or_current_calendar_year\",\n    \"measurement_period_label\": \"Previous or current calendar year\",\n    \"counts_marketplace_sales\": false,\n    \"counts_exempt_sales\": true,\n    \"effective_from\": \"2019-04-01\",\n    \"notes\": \"Wayfair economic nexus threshold.\"\n  }\n}"}]},{"name":"List Sales-Tax Registrations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations"]},"description":"Lists every sales-tax registration record (Phase 3). A registered jurisdiction is reported on the nexus dashboard with a 'registered' status regardless of measured volume (registration override).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"country_code\": \"US\",\n      \"region_code\": \"NY\",\n      \"is_registered\": true,\n      \"registration_date\": \"2024-01-15\",\n      \"registration_number\": \"NY-12345678\",\n      \"filing_frequency\": \"quarterly\",\n      \"filing_frequency_label\": \"Quarterly\",\n      \"notes\": \"Registered after crossing threshold in 2023.\"\n    }\n  ]\n}"}]},{"name":"Create Sales-Tax Registration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations"]},"description":"Creates a sales-tax registration record for a jurisdiction (Phase 3). The country+region pair must be unique.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- country_code (required, size:2): ISO country code; uppercased server-side.\n- region_code (required, <= 10 chars): state/region code; uppercased server-side. Unique per country.\n- is_registered (sometimes, boolean): whether the tenant is registered in the jurisdiction.\n- registration_date (nullable, date).\n- registration_number (nullable, <= 100 chars).\n- filing_frequency (nullable): monthly | quarterly | annually.\n- notes (nullable, <= 255 chars).\n\nAuthentication: Requires Bearer token (scope rw:reports).","body":{"mode":"raw","raw":"{\n  \"country_code\": \"US\",\n  \"region_code\": \"NY\",\n  \"is_registered\": true,\n  \"registration_date\": \"2024-01-15\",\n  \"registration_number\": \"NY-12345678\",\n  \"filing_frequency\": \"quarterly\",\n  \"notes\": \"Registered after crossing threshold in 2023.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"country_code\": \"US\",\n    \"region_code\": \"NY\",\n    \"is_registered\": true,\n    \"registration_date\": \"2024-01-15\",\n    \"registration_number\": \"NY-12345678\",\n    \"filing_frequency\": \"quarterly\",\n    \"filing_frequency_label\": \"Quarterly\",\n    \"notes\": \"Registered after crossing threshold in 2023.\"\n  }\n}"}]},{"name":"Update Sales-Tax Registration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations/{taxNexusRegistration}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations",":taxNexusRegistration"],"variable":[{"key":"taxNexusRegistration","value":"3","description":"Required. The sales-tax registration id being updated. The jurisdiction (country + region) is fixed once created."}]},"description":"Updates an existing sales-tax registration record (Phase 3). The jurisdiction (country + region) is fixed once created; only the registration details and status may change. All fields are optional.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- is_registered (sometimes, boolean).\n- registration_date (nullable, date).\n- registration_number (nullable, <= 100 chars).\n- filing_frequency (nullable): monthly | quarterly | annually.\n- notes (nullable, <= 255 chars).\n\nAuthentication: Requires Bearer token (scope rw:reports).","body":{"mode":"raw","raw":"{\n  \"is_registered\": true,\n  \"registration_date\": \"2024-01-15\",\n  \"registration_number\": \"NY-12345678\",\n  \"filing_frequency\": \"monthly\",\n  \"notes\": \"Switched to monthly filing for 2026.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations/{taxNexusRegistration}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations",":taxNexusRegistration"],"variable":[{"key":"taxNexusRegistration","value":"3","description":"Required. The sales-tax registration id being updated. The jurisdiction (country + region) is fixed once created."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"country_code\": \"US\",\n    \"region_code\": \"NY\",\n    \"is_registered\": true,\n    \"registration_date\": \"2024-01-15\",\n    \"registration_number\": \"NY-12345678\",\n    \"filing_frequency\": \"monthly\",\n    \"filing_frequency_label\": \"Monthly\",\n    \"notes\": \"Switched to monthly filing for 2026.\"\n  }\n}"}]},{"name":"Delete Sales-Tax Registration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations/{taxNexusRegistration}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations",":taxNexusRegistration"],"variable":[{"key":"taxNexusRegistration","value":"3","description":"Required. The sales-tax registration id being deleted."}]},"description":"Deletes a sales-tax registration record (Phase 3). The jurisdiction reverts to volume-based status on the nexus dashboard.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope rw:reports)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/reporting/sales-tax/nexus/registrations/{taxNexusRegistration}","host":["{{baseUrl}}"],"path":["api","reporting","sales-tax","nexus","registrations",":taxNexusRegistration"],"variable":[{"key":"taxNexusRegistration","value":"3","description":"Required. The sales-tax registration id being deleted."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Inventory Valuation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation"]},"description":"Returns the inventory valuation report summary grouped by warehouse/category.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_valuation\": 125400,\n    \"available_valuation\": 98500,\n    \"reserved_valuation\": 12800,\n    \"in_transit_valuation\": 14100,\n    \"groups\": [\n      {\n        \"key\": {\n          \"warehouse\": \"Main Warehouse\"\n        },\n        \"totals\": {\n          \"available\": 1200,\n          \"reserved\": 150,\n          \"in_transit\": 200,\n          \"total_qty\": 1550,\n          \"available_valuation\": 98500,\n          \"total_valuation\": 125400\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Export Inventory Valuation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/export","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","export"]},"description":"Streams the inventory valuation report as a CSV file download (Content-Type text/csv, attachment inventory-valuation.csv).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nColumns: the selected group_by dimensions (SKU, Warehouse, Supplier, Brand, COGS Nominal Code) followed by quantity/valuation pairs — Available, Allocated, On Hold, On Hand, On Hand Average Cost, In Transit, Inbound, Prepaid, and Average Cost. On Hand / On Hand Valuation are the physical on-hand position as of the report date (on_hand_active_qty x average cost) and include allocated & on-hold stock but exclude In Transit.\n\nResponse: CSV file download (not JSON)."}},{"name":"Get Inventory Valuation Drilldown by Category","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/category","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","category"]},"description":"Returns inventory valuation broken down by category.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/category","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","category"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"category\": \"Electronics\",\n      \"total_qty\": 450,\n      \"total_valuation\": 42500,\n      \"available_valuation\": 35000\n    }\n  ]\n}"}]},{"name":"Get Inventory Valuation Drilldown by Source","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/sources","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","sources"]},"description":"Returns inventory valuation broken down by source (purchase order, initial inventory, etc.).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/sources","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","sources"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"source\": \"Purchase Order\",\n      \"total_qty\": 1200,\n      \"total_valuation\": 98000\n    }\n  ]\n}"}]},{"name":"Get Inventory Valuation Drilldown by Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/transactions","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","transactions"]},"description":"Returns inventory valuation broken down by individual inventory transactions.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/inventory-valuation/drilldown/transactions","host":["{{baseUrl}}"],"path":["api","reporting","inventory-valuation","drilldown","transactions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"type\": \"receipt\",\n      \"quantity\": 100,\n      \"cost\": 9.25,\n      \"valuation\": 925,\n      \"date\": \"2024-05-01\"\n    }\n  ]\n}"}]},{"name":"Get Realtime Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/realtime-inventory","host":["{{baseUrl}}"],"path":["api","reporting","realtime-inventory"]},"description":"Returns real-time inventory levels per product per warehouse. Supports both application UI format (filter[search], filter[warehouse_id]) and legacy Vue 2 format (search, warehouse_id) — both are auto-normalized.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/realtime-inventory","host":["{{baseUrl}}"],"path":["api","reporting","realtime-inventory"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"inventory\": {\n        \"available\": 150,\n        \"allocated\": 20,\n        \"on_hold\": 5,\n        \"in_transit\": 10,\n        \"total\": 185,\n        \"inbound\": 50,\n        \"projected_total\": 235\n      }\n    }\n  ]\n}"}]},{"name":"Get Realtime Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/realtime-inventory/summary","host":["{{baseUrl}}"],"path":["api","reporting","realtime-inventory","summary"]},"description":"Returns aggregate summary totals for the realtime inventory report.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/realtime-inventory/summary","host":["{{baseUrl}}"],"path":["api","reporting","realtime-inventory","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_available\": 12500,\n    \"total_allocated\": 850,\n    \"total_in_transit\": 1200,\n    \"total_inbound\": 3400,\n    \"total_projected\": 17950\n  }\n}"}]},{"name":"Export Realtime Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/realtime-inventory/export","host":["{{baseUrl}}"],"path":["api","reporting","realtime-inventory","export"]},"description":"Exports real-time inventory data as a CSV file. Columns: SKU, Product Name, Warehouse, Available, Allocated, On Hold, In Transit, Total, Inbound, Projected Total.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download (realtime-inventory.csv)"}},{"name":"Get Financials by Brand","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-brand?interval=month&metric=revenue&limit=10&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-brand"],"query":[{"key":"interval","value":"month","description":"Required. Time interval: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required. Metric: revenue | profit | profit margin | units sold | # of orders","disabled":true},{"key":"limit","value":"10","description":"Optional. Number of results","disabled":true},{"key":"sort","value":"desc","description":"Optional. Sort: asc | desc","disabled":true}]},"description":"Returns financial summary data grouped by brand.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequired: interval (day|week|month|quarter|year), metric (revenue|profit|profit margin|units sold|# of orders)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-brand?interval=month&metric=revenue&limit=10&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-brand"],"query":[{"key":"interval","value":"month","description":"Required. Time interval: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required. Metric: revenue | profit | profit margin | units sold | # of orders","disabled":true},{"key":"limit","value":"10","description":"Optional. Number of results","disabled":true},{"key":"sort","value":"desc","description":"Optional. Sort: asc | desc","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"brand\": \"Acme\",\n      \"period\": \"2024-06\",\n      \"revenue\": 15200,\n      \"profit\": 6080,\n      \"units_sold\": 320,\n      \"num_orders\": 45\n    }\n  ]\n}"}]},{"name":"Get Financials by SKU","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sku?interval=month&metric=profit&limit=20&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sku"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"profit","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true},{"key":"limit","value":"20","description":"Optional","disabled":true},{"key":"sort","value":"desc","description":"Optional: asc | desc","disabled":true}]},"description":"Returns financial summary data grouped by SKU/product.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sku?interval=month&metric=profit&limit=20&sort=desc","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sku"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"profit","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true},{"key":"limit","value":"20","description":"Optional","disabled":true},{"key":"sort","value":"desc","description":"Optional: asc | desc","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"WIDGET-001\",\n      \"period\": \"2024-06\",\n      \"revenue\": 4500,\n      \"profit\": 1800\n    }\n  ]\n}"}]},{"name":"Get Financials by Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-supplier?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-supplier"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]},"description":"Returns financial summary data grouped by supplier.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-supplier?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-supplier"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier\": \"Widget Co\",\n      \"period\": \"2024-06\",\n      \"revenue\": 28000,\n      \"units_sold\": 600\n    }\n  ]\n}"}]},{"name":"Get Financials by Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sales-channel?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sales-channel"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]},"description":"Returns financial summary data grouped by sales channel.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sales-channel?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sales-channel"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_channel\": \"Shopify\",\n      \"period\": \"2024-06\",\n      \"revenue\": 12000,\n      \"num_orders\": 85\n    }\n  ]\n}"}]},{"name":"Get Financials by Sub-Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sub-sales-channel?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sub-sales-channel"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]},"description":"Returns financial summary data grouped by sub-sales channel.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-sub-sales-channel?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-sub-sales-channel"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sub_sales_channel\": \"Shopify US\",\n      \"period\": \"2024-06\",\n      \"revenue\": 8500\n    }\n  ]\n}"}]},{"name":"Get Financials by Product Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/financials-by-product-type?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-product-type"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]},"description":"Returns financial summary data grouped by product type (standard, blemished, kit).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/financials-by-product-type?interval=month&metric=revenue","host":["{{baseUrl}}"],"path":["api","reporting","financials-by-product-type"],"query":[{"key":"interval","value":"month","description":"Required: day | week | month | quarter | year","disabled":true},{"key":"metric","value":"revenue","description":"Required: revenue | profit | profit margin | units sold | # of orders","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_type\": \"standard\",\n      \"period\": \"2024-06\",\n      \"revenue\": 35000,\n      \"units_sold\": 780\n    }\n  ]\n}"}]},{"name":"Get Monthly COGS","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/cogs?year=2024","host":["{{baseUrl}}"],"path":["api","reporting","cogs"],"query":[{"key":"year","value":"2024","description":"Year to get COGS data for (default: current year)","disabled":true}]},"description":"Returns monthly COGS (cost of goods sold) data for a specific year.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/cogs?year=2024","host":["{{baseUrl}}"],"path":["api","reporting","cogs"],"query":[{"key":"year","value":"2024","description":"Year to get COGS data for (default: current year)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"month\": \"2024-06\",\n      \"total_cost\": 45200\n    },\n    {\n      \"month\": \"2024-05\",\n      \"total_cost\": 38900\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Purchase Summary by Period","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/purchases/summary-by-period?period=month&trailing_days=90","host":["{{baseUrl}}"],"path":["api","reporting","purchases","summary-by-period"],"query":[{"key":"period","value":"month","description":"Required. Period grouping: month | year","disabled":true},{"key":"trailing_days","value":"90","description":"Optional. Number of trailing days to include","disabled":true}]},"description":"Returns a summary of purchases grouped by period (month or year).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequired: period (month|year)\nOptional: trailing_days (integer)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/purchases/summary-by-period?period=month&trailing_days=90","host":["{{baseUrl}}"],"path":["api","reporting","purchases","summary-by-period"],"query":[{"key":"period","value":"month","description":"Required. Period grouping: month | year","disabled":true},{"key":"trailing_days","value":"90","description":"Optional. Number of trailing days to include","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"period_date\": \"2024-06\",\n      \"total\": 18500,\n      \"count\": 12\n    },\n    {\n      \"period_date\": \"2024-05\",\n      \"total\": 22100,\n      \"count\": 15\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Accounting COGS","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/accounting-cogs","host":["{{baseUrl}}"],"path":["api","reporting","accounting-cogs"]},"description":"Returns accounting COGS report data including average cost, quantities sold/returned/adjusted, and COGS totals (gross, returned, adjusted, net).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/accounting-cogs","host":["{{baseUrl}}"],"path":["api","reporting","accounting-cogs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"avg_cost\": 9.25,\n      \"qty_sold\": 450,\n      \"qty_returned\": 12,\n      \"qty_adjusted\": -5,\n      \"net_qty\": 433,\n      \"gross_cogs\": 4162.5,\n      \"returned_cogs\": 111,\n      \"adjusted_cogs\": -46.25,\n      \"net_cogs\": 4005.25\n    }\n  ]\n}"}]},{"name":"Get Accounting COGS Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/accounting-cogs/drilldown","host":["{{baseUrl}}"],"path":["api","reporting","accounting-cogs","drilldown"]},"description":"Underlying movements behind one COGS report row — the individual `accounting_cogs` view rows (sales fulfillments, customer returns, inventory adjustments, FBA movements) that compose the clicked group/SKU aggregate. Paginated, sortable, searchable, with a `totals` block that reconciles to the report row that opened it (same 9 metrics).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIdentify the clicked row with `dimensions[<group_by>]=<value>` for each active group-by dimension down to that row's level (e.g. sales_channel, then sku). Pass the same `filter[date_range_from]`/`filter[date_range_to]` the report was generated with. Each row includes a `product_link` to the product detail page and a `source_label`/`src_id` for the originating accounting record.\n\nAuthentication: Requires Bearer token. Scope: reports."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/accounting-cogs/drilldown","host":["{{baseUrl}}"],"path":["api","reporting","accounting-cogs","drilldown"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"transaction_date\": \"2026-05-20T14:03:00.000000Z\",\n      \"type\": \"sales_order_fulfillment\",\n      \"type_label\": \"Sale\",\n      \"category\": \"sold\",\n      \"sales_channel_name\": \"Shopify US\",\n      \"brand\": \"Acme\",\n      \"brand_id\": 3,\n      \"country\": \"US\",\n      \"sku\": \"ACM-001\",\n      \"product_id\": 42,\n      \"product_link\": \"/products/42\",\n      \"raw_qty\": 10,\n      \"sign\": -1,\n      \"unit_cost\": 9.25,\n      \"ext_cost\": 92.5,\n      \"cogs_impact\": 92.5,\n      \"src_id\": 1187,\n      \"src_type\": \"App\\\\Models\\\\BatchAccountingTransaction\",\n      \"source_label\": \"Batch Transaction\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"path\": \"...\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 42,\n  \"totals\": {\n    \"count\": 42,\n    \"qty_sold\": 450,\n    \"qty_returned\": 12,\n    \"qty_adjusted\": -5,\n    \"net_qty\": 433,\n    \"gross_cogs\": 4162.5,\n    \"returned_cogs\": 111,\n    \"adjusted_cogs\": -46.25,\n    \"net_cogs\": 4005.25,\n    \"avg_cost\": 9.25\n  }\n}"}]},{"name":"Export Accounting COGS","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/accounting-cogs/export?group_by[]=sales_channel","host":["{{baseUrl}}"],"path":["api","reporting","accounting-cogs","export"],"query":[{"key":"group_by[]","value":"sales_channel","description":"Grouping dimensions: sales_channel | country | brand | sku","disabled":true}]},"description":"Exports accounting COGS report as a CSV file. group_by[] determines which extra columns appear before the metric columns (Avg Cost, Qty Sold, Qty Returned, Qty Adjusted, Net Qty, Gross COGS, Returned COGS, Adjusted COGS, Net COGS).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download (accounting-cogs.csv)"}},{"name":"Get GINR Report (Prepaid Inventory)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr?start_date=2024-01-01&end_date=2024-06-30","host":["{{baseUrl}}"],"path":["api","reporting","ginr"],"query":[{"key":"start_date","value":"2024-01-01","description":"Optional. Report start date","disabled":true},{"key":"end_date","value":"2024-06-30","description":"Optional. Report end date","disabled":true}]},"description":"Returns the Goods In Not Received (GINR) / prepaid inventory report — purchase invoices paid but not yet received into inventory.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr?start_date=2024-01-01&end_date=2024-06-30","host":["{{baseUrl}}"],"path":["api","reporting","ginr"],"query":[{"key":"start_date","value":"2024-01-01","description":"Optional. Report start date","disabled":true},{"key":"end_date","value":"2024-06-30","description":"Optional. Report end date","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_number\": \"PO-350\",\n      \"supplier\": \"Widget Co\",\n      \"invoice_date\": \"2024-05-01\",\n      \"total_invoiced\": 5000,\n      \"total_received\": 2500,\n      \"outstanding\": 2500\n    }\n  ]\n}"}]},{"name":"Get GINR Balance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/balance","host":["{{baseUrl}}"],"path":["api","reporting","ginr","balance"]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the single cumulative GINR balance as of an arbitrary date, broken into its four components (invoiced, received, discrepancy, adjustments) plus the resulting `unreceived` balance. Figures are computed live from purchasing and receiving records at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/balance","host":["{{baseUrl}}"],"path":["api","reporting","ginr","balance"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-06-30\",\n    \"invoiced\": 148230.5,\n    \"received\": 121480.25,\n    \"discrepancy\": -350.75,\n    \"adjustments\": 1200,\n    \"unreceived\": 25199.5\n  }\n}"}]},{"name":"Get GINR Trend","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/trend","host":["{{baseUrl}}"],"path":["api","reporting","ginr","trend"]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the end-of-month unreceived (GINR) balance for the last N months — one point per month — suitable for rendering a sparkline or trend chart. The final point is the current in-flight month, measured as of today, and is flagged with `is_current: true`.\n\nData freshness: closed months are served from precomputed month-end snapshots that are refreshed nightly (the trailing three months are recomputed each night to absorb backdated entries). If a closed month has no snapshot yet, it is computed live as a fallback. The current month is always computed live.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/trend","host":["{{baseUrl}}"],"path":["api","reporting","ginr","trend"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"points\": [\n      {\n        \"period_end_date\": \"2026-02-28\",\n        \"unreceived\": 19875.1,\n        \"is_current\": false\n      },\n      {\n        \"period_end_date\": \"2026-03-31\",\n        \"unreceived\": 22140.85,\n        \"is_current\": false\n      },\n      {\n        \"period_end_date\": \"2026-04-30\",\n        \"unreceived\": 18320,\n        \"is_current\": false\n      },\n      {\n        \"period_end_date\": \"2026-05-31\",\n        \"unreceived\": 27410.6,\n        \"is_current\": false\n      },\n      {\n        \"period_end_date\": \"2026-06-30\",\n        \"unreceived\": 25199.5,\n        \"is_current\": false\n      },\n      {\n        \"period_end_date\": \"2026-07-31\",\n        \"unreceived\": 23847.25,\n        \"is_current\": true\n      }\n    ]\n  }\n}"}]},{"name":"Get GINR Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/breakdown","host":["{{baseUrl}}"],"path":["api","reporting","ginr","breakdown"]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the per-purchase-order breakdown of the GINR balance as of a given month's end (or an arbitrary date). Each row carries that PO's cumulative invoiced/received/discrepancy/adjustments values and resulting balance; the rows sum to the same balance reported by the balance endpoint for the same date. Rows are sorted by descending absolute balance. By default, settled and fully-received purchase orders are hidden to reduce noise. Figures are computed live at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/breakdown","host":["{{baseUrl}}"],"path":["api","reporting","ginr","breakdown"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-06-30\",\n    \"items\": [\n      {\n        \"purchase_order_id\": 412,\n        \"purchase_order_number\": \"PO-2041\",\n        \"purchase_order_date\": \"2026-04-12 00:00:00\",\n        \"supplier_name\": \"Shenzhen Lumina Electronics\",\n        \"invoiced\": 42800,\n        \"received\": 21400,\n        \"discrepancy\": 0,\n        \"adjustments\": 0,\n        \"balance\": 21400,\n        \"is_fully_received\": false\n      },\n      {\n        \"purchase_order_id\": 448,\n        \"purchase_order_number\": \"PO-2087\",\n        \"purchase_order_date\": \"2026-05-03 00:00:00\",\n        \"supplier_name\": \"Pacific Coast Distributors\",\n        \"invoiced\": 6120,\n        \"received\": 2295,\n        \"discrepancy\": -75.5,\n        \"adjustments\": 0,\n        \"balance\": 3749.5,\n        \"is_fully_received\": false\n      },\n      {\n        \"purchase_order_id\": 395,\n        \"purchase_order_number\": \"PO-1998\",\n        \"purchase_order_date\": \"2026-03-20 00:00:00\",\n        \"supplier_name\": \"Nordic Textiles AB\",\n        \"invoiced\": 980,\n        \"received\": 890,\n        \"discrepancy\": 0,\n        \"adjustments\": 40,\n        \"balance\": 50,\n        \"is_fully_received\": false\n      }\n    ],\n    \"totals\": {\n      \"invoiced\": 49900,\n      \"received\": 24585,\n      \"discrepancy\": -75.5,\n      \"adjustments\": 40,\n      \"balance\": 25199.5\n    }\n  }\n}"}]},{"name":"Get GINR Aging","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/aging","host":["{{baseUrl}}"],"path":["api","reporting","ginr","aging"]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the aging breakdown of purchase orders that still carry a non-zero GINR balance as of the given date. Each PO's age is measured in days from its earliest activity (first supplier invoice or first receipt) to the as-of date, and POs are grouped into fixed buckets: 0-30, 31-60, 61-90, 91-180, 181-365, and 365+ days. Each bucket reports the PO count, the net balance, and the sum of absolute balances (so offsetting positive/negative balances remain visible). Figures are computed live at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/aging","host":["{{baseUrl}}"],"path":["api","reporting","ginr","aging"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-06-30\",\n    \"buckets\": [\n      {\n        \"label\": \"0-30 days\",\n        \"min_days\": 0,\n        \"max_days\": 30,\n        \"po_count\": 4,\n        \"total_balance\": 8210.25,\n        \"absolute_balance\": 8210.25\n      },\n      {\n        \"label\": \"31-60 days\",\n        \"min_days\": 31,\n        \"max_days\": 60,\n        \"po_count\": 3,\n        \"total_balance\": 6485,\n        \"absolute_balance\": 6485\n      },\n      {\n        \"label\": \"61-90 days\",\n        \"min_days\": 61,\n        \"max_days\": 90,\n        \"po_count\": 2,\n        \"total_balance\": 5320.75,\n        \"absolute_balance\": 5320.75\n      },\n      {\n        \"label\": \"91-180 days\",\n        \"min_days\": 91,\n        \"max_days\": 180,\n        \"po_count\": 2,\n        \"total_balance\": 4890.5,\n        \"absolute_balance\": 4890.5\n      },\n      {\n        \"label\": \"181-365 days\",\n        \"min_days\": 181,\n        \"max_days\": 365,\n        \"po_count\": 1,\n        \"total_balance\": 293,\n        \"absolute_balance\": 293\n      },\n      {\n        \"label\": \"365+ days\",\n        \"min_days\": 366,\n        \"max_days\": null,\n        \"po_count\": 0,\n        \"total_balance\": 0,\n        \"absolute_balance\": 0\n      }\n    ],\n    \"totals\": {\n      \"po_count\": 12,\n      \"total_balance\": 25199.5,\n      \"absolute_balance\": 25199.5\n    }\n  }\n}"}]},{"name":"Get GINR Aging Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/aging/drilldown?min_days=91","host":["{{baseUrl}}"],"path":["api","reporting","ginr","aging","drilldown"],"query":[{"key":"min_days","value":"91","description":"Required. Minimum age in days (inclusive, integer ≥ 0) of the bucket to drill into.","disabled":true}]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nLists the purchase orders that fall into a specific aging bucket as of a given date — the drill-through for a bucket returned by the aging endpoint. Each row includes the PO's earliest activity date, its age in days, and the full per-metric breakdown (invoiced, received, discrepancy, adjustments, balance). Rows are sorted oldest first. Figures are computed live at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/aging/drilldown?min_days=91","host":["{{baseUrl}}"],"path":["api","reporting","ginr","aging","drilldown"],"query":[{"key":"min_days","value":"91","description":"Required. Minimum age in days (inclusive, integer ≥ 0) of the bucket to drill into.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-06-30\",\n    \"bucket\": {\n      \"label\": \"91-180 days\",\n      \"min_days\": 91,\n      \"max_days\": 180\n    },\n    \"items\": [\n      {\n        \"purchase_order_id\": 361,\n        \"purchase_order_number\": \"PO-1912\",\n        \"supplier_name\": \"Nordic Textiles AB\",\n        \"earliest_activity_date\": \"2026-02-18 08:15:42\",\n        \"age_days\": 132,\n        \"invoiced\": 3200,\n        \"received\": 0,\n        \"discrepancy\": 0,\n        \"adjustments\": 0,\n        \"balance\": 3200\n      },\n      {\n        \"purchase_order_id\": 372,\n        \"purchase_order_number\": \"PO-1935\",\n        \"supplier_name\": \"Guangzhou Homeware Co\",\n        \"earliest_activity_date\": \"2026-03-08 11:40:03\",\n        \"age_days\": 114,\n        \"invoiced\": 2140.5,\n        \"received\": 450,\n        \"discrepancy\": 0,\n        \"adjustments\": 0,\n        \"balance\": 1690.5\n      }\n    ],\n    \"totals\": {\n      \"po_count\": 2,\n      \"total_balance\": 4890.5,\n      \"absolute_balance\": 4890.5\n    }\n  }\n}"}]},{"name":"Get GINR Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/drilldown?metric=invoiced","host":["{{baseUrl}}"],"path":["api","reporting","ginr","drilldown"],"query":[{"key":"metric","value":"invoiced","description":"Required. Which GINR component to list the backing records for. One of: `invoiced`, `received`, `discrepancy`, `adjustments`.","disabled":true}]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the raw backing records for one GINR component (metric) through a given date, optionally scoped to a single purchase order. Records cover the cumulative window from the account's inventory start date through the as-of date, so the sum of each item's `value` equals the matching aggregate figure from the balance/breakdown endpoints.\n\nThe fields of each item vary by metric:\n- `invoiced` — supplier invoice lines (invoice reference, quantities, unit price, discount).\n- `received` — receipt lines from both warehouse receipts and Amazon FBA inbound ledger events (`receipt_source` is `warehouse_receipt` or `fba_ledger`), with the cost proration inputs used to value each receipt.\n- `discrepancy` — receiving-discrepancy journal postings (credit/debit lines).\n- `adjustments` — PO-linked inventory adjustment movements with the cost layer used to value them.\n\nFigures are computed live at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/drilldown?metric=invoiced","host":["{{baseUrl}}"],"path":["api","reporting","ginr","drilldown"],"query":[{"key":"metric","value":"invoiced","description":"Required. Which GINR component to list the backing records for. One of: `invoiced`, `received`, `discrepancy`, `adjustments`.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"metric\": \"invoiced\",\n    \"as_of_date\": \"2026-06-30\",\n    \"purchase_order_id\": null,\n    \"items\": [\n      {\n        \"invoice_line_id\": 5211,\n        \"purchase_invoice_id\": 1287,\n        \"invoice_reference\": \"INV-88213\",\n        \"date\": \"2026-04-15 00:00:00\",\n        \"purchase_order_id\": 412,\n        \"purchase_order_number\": \"PO-2041\",\n        \"supplier_name\": \"Shenzhen Lumina Electronics\",\n        \"purchase_order_line_id\": 3320,\n        \"product_sku\": \"LED-STRIP-5M-RGB\",\n        \"product_name\": \"5m LED Light Strip - RGB\",\n        \"quantity_invoiced\": 2000,\n        \"unit_price\": 21.4,\n        \"po_line_amount\": 21.4,\n        \"po_line_quantity\": 2000,\n        \"discount_rate\": 0,\n        \"value\": 42800\n      },\n      {\n        \"invoice_line_id\": 5304,\n        \"purchase_invoice_id\": 1301,\n        \"invoice_reference\": \"INV-88790\",\n        \"date\": \"2026-05-06 00:00:00\",\n        \"purchase_order_id\": 448,\n        \"purchase_order_number\": \"PO-2087\",\n        \"supplier_name\": \"Pacific Coast Distributors\",\n        \"purchase_order_line_id\": 3391,\n        \"product_sku\": \"GLOW-DESK-WAL\",\n        \"product_name\": \"Desk Glow Lamp - Walnut\",\n        \"quantity_invoiced\": 360,\n        \"unit_price\": 17,\n        \"po_line_amount\": 17,\n        \"po_line_quantity\": 360,\n        \"discount_rate\": 0,\n        \"value\": 6120\n      }\n    ],\n    \"total\": 48920\n  }\n}"}]},{"name":"Get GINR PO Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/ginr/po-receipts?purchase_order_id=412","host":["{{baseUrl}}"],"path":["api","reporting","ginr","po-receipts"],"query":[{"key":"purchase_order_id","value":"412","description":"Required. The purchase order to list receipts for (must be an existing purchase order ID).","disabled":true}]},"description":"GINR (Goods Invoiced, Not Received) — also called Accrued Purchases or GRNI — tracks the value of goods that suppliers have invoiced but that have not yet been received into inventory. The balance is calculated as: invoiced − received + discrepancies − adjustments, accumulated from the account's inventory start date (so it behaves like a balance-sheet figure, not a period movement).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the full lifetime receiving history for a single purchase order, grouped by receipt date. Unlike the other GINR endpoints this is not bounded by an as-of date — it shows every receipt so you can see when and how much of the PO arrived. Each row includes the quantity and value received that day plus its share of the PO's total value and quantity. Both warehouse receipts and Amazon FBA inbound receipts are included. Figures are computed live at request time.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/ginr/po-receipts?purchase_order_id=412","host":["{{baseUrl}}"],"path":["api","reporting","ginr","po-receipts"],"query":[{"key":"purchase_order_id","value":"412","description":"Required. The purchase order to list receipts for (must be an existing purchase order ID).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purchase_order_id\": 412,\n    \"purchase_order_number\": \"PO-2041\",\n    \"supplier_name\": \"Shenzhen Lumina Electronics\",\n    \"po_total_value\": 42800,\n    \"po_total_quantity\": 2000,\n    \"items\": [\n      {\n        \"date\": \"2026-05-14\",\n        \"received_at\": \"2026-05-14 09:32:11\",\n        \"quantity_received\": 500,\n        \"value\": 10700,\n        \"percent_of_po_value\": 25,\n        \"percent_of_po_quantity\": 25\n      },\n      {\n        \"date\": \"2026-06-02\",\n        \"received_at\": \"2026-06-02 00:00:00\",\n        \"quantity_received\": 500,\n        \"value\": 10700,\n        \"percent_of_po_value\": 25,\n        \"percent_of_po_quantity\": 25\n      }\n    ],\n    \"total_value\": 21400,\n    \"total_quantity\": 1000\n  }\n}"}]},{"name":"Get Accounting Income Statement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/accounting/income-statement?period=month","host":["{{baseUrl}}"],"path":["api","reporting","accounting","income-statement"],"query":[{"key":"period","value":"month","description":"Period grouping: month | year","disabled":true}]},"description":"Returns an income statement grouped by accounting nominal codes and period. Supports date filtering and period granularity.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/accounting/income-statement?period=month","host":["{{baseUrl}}"],"path":["api","reporting","accounting","income-statement"],"query":[{"key":"period","value":"month","description":"Period grouping: month | year","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"nominal_code_id\": 10,\n      \"nominal_code\": \"4000\",\n      \"nominal_code_name\": \"Sales Revenue\",\n      \"nominal_code_type\": \"income\",\n      \"period_date\": \"2024-06\",\n      \"total\": 45200\n    }\n  ]\n}"}]},{"name":"Get Accounting Balance Sheet","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/accounting/balance-sheet","host":["{{baseUrl}}"],"path":["api","reporting","accounting","balance-sheet"]},"description":"Returns a balance sheet snapshot as of a date, built from the same accounting_transaction_lines data source as the income statement so the two reconcile.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAccounts are grouped into assets (reported as net debit balance), liabilities and equity (reported as net credit balance). Cumulative net income is appended to equity as a computed \"Retained Earnings\" line so the statement balances (Assets = Liabilities + Equity).\n\nAlso scoped by scope by object:reports`.\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/accounting/balance-sheet","host":["{{baseUrl}}"],"path":["api","reporting","accounting","balance-sheet"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2024-06-30\",\n    \"assets\": [\n      {\n        \"nominal_code_id\": 1,\n        \"nominal_code\": \"1000\",\n        \"nominal_code_name\": \"Bank\",\n        \"nominal_code_type\": \"Bank\",\n        \"balance\": 1000,\n        \"is_computed\": false\n      },\n      {\n        \"nominal_code_id\": 2,\n        \"nominal_code\": \"1200\",\n        \"nominal_code_name\": \"Inventory\",\n        \"nominal_code_type\": \"Inventory\",\n        \"balance\": 200,\n        \"is_computed\": false\n      }\n    ],\n    \"liabilities\": [\n      {\n        \"nominal_code_id\": 3,\n        \"nominal_code\": \"2100\",\n        \"nominal_code_name\": \"Accounts Payable\",\n        \"nominal_code_type\": \"Currliab\",\n        \"balance\": 600,\n        \"is_computed\": false\n      }\n    ],\n    \"equity\": [\n      {\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"nominal_code_name\": \"Retained Earnings\",\n        \"nominal_code_type\": \"Equity\",\n        \"balance\": 600,\n        \"is_computed\": true\n      }\n    ],\n    \"totals\": {\n      \"assets\": 1200,\n      \"liabilities\": 600,\n      \"equity\": 600,\n      \"liabilities_and_equity\": 1200,\n      \"retained_earnings\": 600,\n      \"difference\": 0,\n      \"is_balanced\": true\n    }\n  }\n}"}]},{"name":"Get Sales Channel Coverage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage/paginated?page=1&per_page=25&by_integration=1&show_count=0","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage","paginated"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true},{"key":"by_integration","value":"1","description":"1 = group by integration, 0 = group by instance (default: 1)","disabled":true},{"key":"show_count","value":"0","description":"1 = show coverage count, 0 = show boolean (default: 0)","disabled":true}]},"description":"Returns paginated sales channel coverage data per product using Spatie QueryBuilder. Shows which products are listed on which sales channels.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nFilters: filter[search] (matches SKU OR supplier name), filter[product_types] (comma-separated: standard|blemished|kit), filter[integration_ids] (comma-separated), filter[instance_ids] (comma-separated)\n\nFlags:\n- by_integration (1/0) — group coverage by integration vs instance\n- show_count (1/0) — return numeric coverage counts vs boolean 0/1\n- in_stock_only (1/0) — restrict to products with on-hand stock at warehouse 0 (default 1)\n\nSort: sku, type, id"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage/paginated?page=1&per_page=25&by_integration=1&show_count=0","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage","paginated"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true},{"key":"by_integration","value":"1","description":"1 = group by integration, 0 = group by instance (default: 1)","disabled":true},{"key":"show_count","value":"0","description":"1 = show coverage count, 0 = show boolean (default: 0)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"supplier\": {\n        \"name\": \"Widget Co\"\n      },\n      \"type\": \"standard\",\n      \"stock\": 150,\n      \"valuation\": 1387.5,\n      \"coverage\": {\n        \"Shopify\": 1,\n        \"Amazon\": 0,\n        \"WooCommerce\": 1\n      }\n    }\n  ],\n  \"per_page\": 25,\n  \"total\": 342\n}"}]},{"name":"Get Full Sales Channel Coverage","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage"]},"description":"Returns listing coverage for every product across the selected sales channels in a single unpaginated response. For each product you get its stock on hand, inventory valuation, default supplier, and a coverage map keyed by channel name plus a Total.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest fields (all required):\n- `byIntegration` (boolean) — true groups coverage by integration (e.g. all Amazon instances combined); false groups by individual integration instance.\n- `showNumberOfCoverages` (boolean) — true returns the count of active listings per channel; false returns a binary indicator (1 = listed, 0 = not listed).\n- `ids` (array of integers) — the integration IDs (when `byIntegration` is true) or integration instance IDs (when false) to include in the coverage calculation.\n\nCoverage for kit/bundle products includes listings of their parent products. This endpoint computes coverage for the entire catalog in one request and can be slow on large catalogs — prefer `GET /api/reporting/sales-channel-coverage/paginated` for interactive use.\n\nAuthentication: Requires Bearer token. Scope: `reports` (read/write).","body":{"mode":"raw","raw":"{\n  \"byIntegration\": true,\n  \"showNumberOfCoverages\": false,\n  \"ids\": [\n    1,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"sku\": \"TSHIRT-BLK-M\",\n      \"type\": \"standard\",\n      \"stock\": 240,\n      \"valuation\": 1820.5,\n      \"supplier\": {\n        \"id\": 3,\n        \"name\": \"Acme Apparel Co\"\n      },\n      \"coverage\": {\n        \"Amazon\": 1,\n        \"Shopify\": 1,\n        \"Total\": 2\n      }\n    },\n    {\n      \"id\": 102,\n      \"sku\": \"TSHIRT-BLK-L\",\n      \"type\": \"standard\",\n      \"stock\": 0,\n      \"valuation\": 0,\n      \"supplier\": {\n        \"id\": 3,\n        \"name\": \"Acme Apparel Co\"\n      },\n      \"coverage\": {\n        \"Amazon\": 0,\n        \"Shopify\": 1,\n        \"Total\": 1\n      }\n    }\n  ]\n}"}]},{"name":"Export Sales Channel Coverage (Async)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage/export?by_integration=1&show_count=0&in_stock_only=1","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage","export"],"query":[{"key":"by_integration","value":"1","description":"1 = group by integration, 0 = group by instance (default: 1)","disabled":true},{"key":"show_count","value":"0","description":"1 = show coverage count, 0 = show boolean (default: 0)","disabled":true},{"key":"in_stock_only","value":"1","description":"1 = only include products with stock at warehouse 0 (default), 0 = include all products","disabled":true}]},"description":"Dispatches an async job (a background job) that builds the full unpaginated sales channel coverage CSV in the background. Returns immediately with a tracked_job_log_id that the frontend uses to poll progress via the tracked job log endpoints.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nFlow:\n1. Client calls this endpoint with the same filters/flags supported by the paginated endpoint.\n2. Server queues the job and returns { data: { tracked_job_log_id }, message }.\n3. Frontend subscribes via the tracked job log endpoints; when job completes, log.results.file contains the filename on the model-exports disk.\n4. Client downloads the file via GET /api/export/download?file={filename}.\n\nCSV columns: SKU, Product Name, Supplier, Type, Stock, Valuation, Total Coverage, plus one column per integration (or instance when by_integration=0) covering the union of channels across all returned rows. Channel columns are computed from the union of all rows in the result set."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-channel-coverage/export?by_integration=1&show_count=0&in_stock_only=1","host":["{{baseUrl}}"],"path":["api","reporting","sales-channel-coverage","export"],"query":[{"key":"by_integration","value":"1","description":"1 = group by integration, 0 = group by instance (default: 1)","disabled":true},{"key":"show_count","value":"0","description":"1 = show coverage count, 0 = show boolean (default: 0)","disabled":true},{"key":"in_stock_only","value":"1","description":"1 = only include products with stock at warehouse 0 (default), 0 = include all products","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Export started\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Release Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/reporting/release-schedule","host":["{{baseUrl}}"],"path":["api","v2","reporting","release-schedule"]},"description":"Forward-looking release schedule for held sales orders. Returns held orders (those with a future hold_until_date — a \"do not ship before\" release date, used for preorders and scheduled holds) grouped by the application-timezone date on which they become shippable.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOrders are excluded if they have no hold, the hold has already passed, are cancelled (canceled_at set), or are closed. Buckets are ordered by hold_until_date ascending.\n\nThis differs from Ship By Schedule: ship_by_date is a deadline (\"ship no later than\"), whereas hold_until_date is a floor (\"do not ship before\").\n\nAuthentication: Requires Bearer token. Scope: reports (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/reporting/release-schedule","host":["{{baseUrl}}"],"path":["api","v2","reporting","release-schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"hold_until_date\": \"2026-05-23\",\n      \"order_count\": 2,\n      \"orders\": [\n        {\n          \"id\": 10432,\n          \"order_number\": \"SO-10432\",\n          \"channel\": \"Acme Shopify Store\",\n          \"order_status\": \"reserved\",\n          \"hold_until_date\": \"2026-05-23T00:00:00+00:00\",\n          \"ship_by_date\": \"2026-05-25T00:00:00+00:00\",\n          \"item_count\": 3\n        },\n        {\n          \"id\": 10455,\n          \"order_number\": \"SO-10455\",\n          \"channel\": \"Acme Shopify Store\",\n          \"order_status\": \"reserved\",\n          \"hold_until_date\": \"2026-05-23T00:00:00+00:00\",\n          \"ship_by_date\": \"2026-05-26T00:00:00+00:00\",\n          \"item_count\": 1\n        }\n      ]\n    },\n    {\n      \"hold_until_date\": \"2026-06-01\",\n      \"order_count\": 1,\n      \"orders\": [\n        {\n          \"id\": 10501,\n          \"order_number\": \"SO-10501\",\n          \"channel\": \"Acme Shopify Store\",\n          \"order_status\": \"reserved\",\n          \"hold_until_date\": \"2026-06-01T00:00:00+00:00\",\n          \"ship_by_date\": \"2026-06-03T00:00:00+00:00\",\n          \"item_count\": 5\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Supplier Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Macro supplier dashboard for the resolved period: headline KPIs (purchase volume, sales volume, profit, active suppliers), the hottest/coldest movers, a 12-month growth heatmap, and the full leaderboard. KPIs and trends are read from monthly supplier metric snapshots.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required and date_to must be on or after date_from.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — the basis used to rank movers and the heatmap\n- min_volume: numeric — minimum purchase volume before a supplier qualifies as a mover (default: 1000)\n- include_archived: boolean — include archived suppliers (default: false)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"kpis\": {\n      \"purchase_volume\": {\n        \"current\": 1842500.5,\n        \"previous\": 1640200,\n        \"delta_pct\": 12.3\n      },\n      \"sales_volume\": {\n        \"current\": 3120900,\n        \"previous\": 2890400,\n        \"delta_pct\": 8\n      },\n      \"profit\": {\n        \"current\": 961000.25,\n        \"previous\": 905100,\n        \"delta_pct\": 6.2\n      },\n      \"active_suppliers\": {\n        \"current\": 48,\n        \"previous\": 45,\n        \"delta_pct\": 6.7\n      }\n    },\n    \"hottest\": [\n      {\n        \"supplier_id\": 42,\n        \"name\": \"Acme Components Ltd\",\n        \"value\": 184250.5,\n        \"delta_pct\": 31.5,\n        \"spark\": [\n          12000,\n          13400,\n          15600,\n          14200,\n          16800,\n          17100,\n          18900,\n          16400,\n          19200,\n          21000,\n          20400,\n          22300\n        ]\n      }\n    ],\n    \"coldest\": [\n      {\n        \"supplier_id\": 71,\n        \"name\": \"Borealis Supply Co\",\n        \"value\": 22400,\n        \"delta_pct\": -18.7,\n        \"spark\": [\n          9100,\n          8700,\n          8200,\n          7600,\n          6900,\n          6400,\n          5800,\n          5100,\n          4700,\n          4200,\n          3900,\n          3400\n        ]\n      }\n    ],\n    \"heatmap\": {\n      \"columns\": [\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\",\n        \"2026-05\"\n      ],\n      \"rows\": [\n        {\n          \"supplier_id\": 42,\n          \"name\": \"Acme Components Ltd\",\n          \"cells\": [\n            null,\n            8.2,\n            12.4,\n            -3.1,\n            6.7,\n            9,\n            14.2,\n            -2.4,\n            5.5,\n            11,\n            7.8,\n            12.4\n          ]\n        }\n      ]\n    },\n    \"leaderboard\": [\n      {\n        \"supplier_id\": 42,\n        \"name\": \"Acme Components Ltd\",\n        \"purchase_volume\": 184250.5,\n        \"sales_volume\": 312900,\n        \"units_purchased\": 8400,\n        \"units_sold\": 7950,\n        \"profit\": 96100.25,\n        \"margin_pct\": 30.7,\n        \"growth_pct\": 12.4,\n        \"active_po_count\": 23,\n        \"po_count\": 21,\n        \"is_low_volume\": false\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Supplier Leaderboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Leaderboard rows only — a lightweight endpoint for table page/sort changes on the macro supplier view, without recomputing KPIs, movers, or the heatmap. Rows are computed in-memory from snapshots, then filtered, sorted and sliced; low-volume suppliers are flagged via is_low_volume.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nServer-paginated (PRD edge case 15: 500+ suppliers) — returns the standard Laravel pagination envelope (data, current_page, last_page, per_page, total, etc.).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume: numeric — low-volume threshold (default: 1000)\n- include_archived: boolean (default: false)\n- sort: sort key, prefix - for DESC. Allowed: name, purchase_volume, sales_volume, units_purchased, units_sold, profit, margin_pct, growth_pct, active_po_count (default: -purchase_volume)\n- page: page number (default: 1)\n- per_page: rows per page (default: 10)\n- filter[search]: substring match on supplier name\n- filter[volume]: above | low — volume band filter"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier_id\": 42,\n      \"name\": \"Acme Components Ltd\",\n      \"purchase_volume\": 184250.5,\n      \"sales_volume\": 312900,\n      \"units_purchased\": 8400,\n      \"units_sold\": 7950,\n      \"profit\": 96100.25,\n      \"margin_pct\": 30.7,\n      \"growth_pct\": 12.4,\n      \"active_po_count\": 23,\n      \"po_count\": 21,\n      \"is_low_volume\": false\n    },\n    {\n      \"supplier_id\": 71,\n      \"name\": \"Borealis Supply Co\",\n      \"purchase_volume\": 22400,\n      \"sales_volume\": 41200,\n      \"units_purchased\": 980,\n      \"units_sold\": 910,\n      \"profit\": 9100.5,\n      \"margin_pct\": 22.1,\n      \"growth_pct\": -18.7,\n      \"active_po_count\": 4,\n      \"po_count\": 5,\n      \"is_low_volume\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/leaderboard?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/leaderboard?page=5\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/leaderboard?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/suppliers/leaderboard\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"Rebuild Supplier Metric Snapshots","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","rebuild-snapshots"]},"description":"Dispatches the supplier-metric snapshot rebuild as a tracked background job and returns its tracked job log ID for progress polling via the tracked job log endpoints. Rejects a second dispatch with 409 while a rebuild is already queued or running.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nThis endpoint takes no request body.\n\nNote: no request body is required.","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","rebuild-snapshots"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90871\n  },\n  \"message\": \"Supplier metric rebuild started.\"\n}"}]},{"name":"Get Supplier Scorecard Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","scorecard-settings"]},"description":"Returns the tenant-global supplier scorecard configuration: the six dimension weights (sum to 100), the ordered {min, score} threshold bands per dimension, and the minimum in-period PO count required before a supplier is scored. A default row is created on first access if none exists.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"weights\": {\n      \"on_time_delivery\": 25,\n      \"lead_time_reliability\": 15,\n      \"fill_rate\": 15,\n      \"defect_rate\": 15,\n      \"cost_competitiveness\": 25,\n      \"price_stability\": 5\n    },\n    \"thresholds\": {\n      \"on_time_delivery\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"lead_time_reliability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"fill_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"defect_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"cost_competitiveness\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"price_stability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_po_count\": 3,\n    \"created_at\": \"2026-01-04T09:00:00.000000Z\",\n    \"updated_at\": \"2026-05-10T14:22:31.000000Z\"\n  }\n}"}]},{"name":"Update Supplier Scorecard Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","scorecard-settings"]},"description":"Updates the tenant-global supplier scorecard configuration. The six weights must each be present and sum to exactly 100; every threshold band needs a numeric min and an integer 1-5 score.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequest body fields:\n- weights: object (required) — must contain all six metric keys; values numeric 0-100, summing to exactly 100\n- weights.on_time_delivery: numeric, 0-100 (required)\n- weights.lead_time_reliability: numeric, 0-100 (required)\n- weights.fill_rate: numeric, 0-100 (required)\n- weights.defect_rate: numeric, 0-100 (required)\n- weights.cost_competitiveness: numeric, 0-100 (required)\n- weights.price_stability: numeric, 0-100 (required)\n- thresholds: object (required) — must contain all six metric keys\n- thresholds.{metric}: array, min 1 item (required) — ordered {min, score} bands\n- thresholds.{metric}.*.min: numeric (required) — lower bound of the band\n- thresholds.{metric}.*.score: integer 1-5 (required) — score awarded for the band\n- min_po_count: integer, min 1 (required)","body":{"mode":"raw","raw":"{\n  \"weights\": {\n    \"on_time_delivery\": 25,\n    \"lead_time_reliability\": 15,\n    \"fill_rate\": 15,\n    \"defect_rate\": 15,\n    \"cost_competitiveness\": 25,\n    \"price_stability\": 5\n  },\n  \"thresholds\": {\n    \"on_time_delivery\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"lead_time_reliability\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"fill_rate\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"defect_rate\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"cost_competitiveness\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"price_stability\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ]\n  },\n  \"min_po_count\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","suppliers","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"weights\": {\n      \"on_time_delivery\": 25,\n      \"lead_time_reliability\": 15,\n      \"fill_rate\": 15,\n      \"defect_rate\": 15,\n      \"cost_competitiveness\": 25,\n      \"price_stability\": 5\n    },\n    \"thresholds\": {\n      \"on_time_delivery\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"lead_time_reliability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"fill_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"defect_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"cost_competitiveness\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"price_stability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_po_count\": 3,\n    \"created_at\": \"2026-01-04T09:00:00.000000Z\",\n    \"updated_at\": \"2026-05-10T14:22:31.000000Z\"\n  }\n}"}]},{"name":"Get Supplier Scorecard Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","scorecard-summary"],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]},"description":"Lightweight scorecard + volume sparklines for the supplier Profile chip. Returns the composite scorecard with its dimension breakdown, a directional composite trend hint (up | down | flat), and trailing-12-month purchase/sales volume sparklines. The period is fixed to YoY.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","scorecard-summary"],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"supplier\": {\n      \"id\": 42,\n      \"name\": \"Acme Components Ltd\"\n    },\n    \"scorecard\": {\n      \"composite\": 4.15,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"po_count\": 18,\n      \"dimensions\": [\n        {\n          \"key\": \"on_time_delivery\",\n          \"label\": \"On-Time Delivery\",\n          \"raw\": 92.3,\n          \"raw_display\": \"92.3%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"lead_time_reliability\",\n          \"label\": \"Lead-Time Reliability\",\n          \"raw\": 88,\n          \"raw_display\": \"88.0%\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"fill_rate\",\n          \"label\": \"Fill Rate\",\n          \"raw\": 98.6,\n          \"raw_display\": \"98.6%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"defect_rate\",\n          \"label\": \"Defect / RTV Rate\",\n          \"raw\": 1.2,\n          \"raw_display\": \"1.2%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"cost_competitiveness\",\n          \"label\": \"Cost Competitiveness\",\n          \"raw\": 74.5,\n          \"raw_display\": \"74.5 / 100\",\n          \"score\": 3,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"price_stability\",\n          \"label\": \"Price Stability\",\n          \"raw\": 0.18,\n          \"raw_display\": \"18% price increases\",\n          \"score\": 4,\n          \"weight\": 5\n        }\n      ]\n    },\n    \"composite_trend\": \"up\",\n    \"purchase_volume\": {\n      \"current\": 184250.5,\n      \"previous\": 158900,\n      \"delta_pct\": 16,\n      \"spark\": [\n        12000,\n        13400,\n        15600,\n        14200,\n        16800,\n        17100,\n        18900,\n        16400,\n        19200,\n        21000,\n        20400,\n        22300\n      ]\n    },\n    \"sales_volume\": {\n      \"current\": 312900,\n      \"previous\": 289400,\n      \"delta_pct\": 8.1,\n      \"spark\": [\n        22000,\n        23100,\n        24800,\n        25600,\n        26100,\n        27400,\n        26900,\n        28200,\n        29400,\n        30100,\n        31200,\n        32400\n      ]\n    },\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Supplier Analytics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]},"description":"Full per-supplier analytics for the Analytics tab: headline KPIs (purchase volume, sales volume, units purchased/sold, profit, margin %), the composite scorecard, a dual-line current-vs-previous trend chart, and the hottest/coolest products ranked by growth.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — drives the trend metric and product mover ranking\n- min_volume: numeric (default: 1000)\n- include_archived: boolean (default: false)\n\nThe response also includes `product_heatmap` (a period-aware per-product growth heatmap — the supplier's top products by volume, each cell a period-over-period change that follows the `period_mode` selector) and `calendar_year_volume` (per calendar year for the trailing 5 years: non-draft PO spend with units/PO counts plus non-draft sales revenue with units/order counts; the current year is year-to-date and is independent of `period_mode`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"supplier\": {\n      \"id\": 42,\n      \"name\": \"Acme Components Ltd\"\n    },\n    \"kpis\": {\n      \"purchase_volume\": {\n        \"current\": 184250.5,\n        \"previous\": 158900,\n        \"delta_pct\": 16\n      },\n      \"sales_volume\": {\n        \"current\": 312900,\n        \"previous\": 289400,\n        \"delta_pct\": 8.1\n      },\n      \"units_purchased\": {\n        \"current\": 8400,\n        \"previous\": 7600,\n        \"delta_pct\": 10.5\n      },\n      \"units_sold\": {\n        \"current\": 7950,\n        \"previous\": 7400,\n        \"delta_pct\": 7.4\n      },\n      \"profit\": {\n        \"current\": 96100.25,\n        \"previous\": 88200,\n        \"delta_pct\": 9\n      },\n      \"margin_pct\": {\n        \"current\": 30.7,\n        \"previous\": 30.5,\n        \"delta_pct\": 0.2\n      }\n    },\n    \"scorecard\": {\n      \"composite\": 4.15,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"po_count\": 18,\n      \"dimensions\": [\n        {\n          \"key\": \"on_time_delivery\",\n          \"label\": \"On-Time Delivery\",\n          \"raw\": 92.3,\n          \"raw_display\": \"92.3%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"lead_time_reliability\",\n          \"label\": \"Lead-Time Reliability\",\n          \"raw\": 88,\n          \"raw_display\": \"88.0%\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"fill_rate\",\n          \"label\": \"Fill Rate\",\n          \"raw\": 98.6,\n          \"raw_display\": \"98.6%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"defect_rate\",\n          \"label\": \"Defect / RTV Rate\",\n          \"raw\": 1.2,\n          \"raw_display\": \"1.2%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"cost_competitiveness\",\n          \"label\": \"Cost Competitiveness\",\n          \"raw\": 74.5,\n          \"raw_display\": \"74.5 / 100\",\n          \"score\": 3,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"price_stability\",\n          \"label\": \"Price Stability\",\n          \"raw\": 0.18,\n          \"raw_display\": \"18% price increases\",\n          \"score\": 4,\n          \"weight\": 5\n        }\n      ]\n    },\n    \"trend\": {\n      \"metric\": \"sales\",\n      \"buckets\": [\n        \"2025-05\",\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\"\n      ],\n      \"current\": [\n        14200,\n        15600,\n        16800,\n        17100,\n        18900,\n        16400,\n        19200,\n        21000,\n        20400,\n        22300,\n        21800,\n        23400\n      ],\n      \"previous\": [\n        12100,\n        13400,\n        14000,\n        14900,\n        15600,\n        14100,\n        16800,\n        18200,\n        17900,\n        19400,\n        18800,\n        20100\n      ]\n    },\n    \"hottest_products\": [\n      {\n        \"product_id\": 9001,\n        \"sku\": \"ACM-WIDGET-01\",\n        \"name\": \"Widget Assembly Type A\",\n        \"value\": 42100,\n        \"delta_pct\": 34.2\n      }\n    ],\n    \"coolest_products\": [\n      {\n        \"product_id\": 9044,\n        \"sku\": \"ACM-BRACKET-12\",\n        \"name\": \"Mounting Bracket XL\",\n        \"value\": 6200,\n        \"delta_pct\": -21.8\n      }\n    ],\n    \"product_heatmap\": {\n      \"columns\": [\n        \"2025-05\",\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\"\n      ],\n      \"rows\": [\n        {\n          \"product_id\": 9001,\n          \"sku\": \"ACM-WIDGET-01\",\n          \"name\": \"Widget Assembly Type A\",\n          \"cells\": [\n            {\n              \"delta\": null,\n              \"current_value\": 11800,\n              \"previous_value\": null,\n              \"compare_period\": \"2024-05\"\n            },\n            {\n              \"delta\": 12.4,\n              \"current_value\": 13300,\n              \"previous_value\": 11830,\n              \"compare_period\": \"2024-06\"\n            },\n            {\n              \"delta\": 8.1,\n              \"current_value\": 14380,\n              \"previous_value\": 13300,\n              \"compare_period\": \"2024-07\"\n            },\n            {\n              \"delta\": -3.2,\n              \"current_value\": 13920,\n              \"previous_value\": 14380,\n              \"compare_period\": \"2024-08\"\n            },\n            {\n              \"delta\": 19.5,\n              \"current_value\": 16640,\n              \"previous_value\": 13920,\n              \"compare_period\": \"2024-09\"\n            },\n            {\n              \"delta\": -6.7,\n              \"current_value\": 15520,\n              \"previous_value\": 16640,\n              \"compare_period\": \"2024-10\"\n            },\n            {\n              \"delta\": 22,\n              \"current_value\": 18940,\n              \"previous_value\": 15520,\n              \"compare_period\": \"2024-11\"\n            },\n            {\n              \"delta\": 9.3,\n              \"current_value\": 20700,\n              \"previous_value\": 18940,\n              \"compare_period\": \"2024-12\"\n            },\n            {\n              \"delta\": -2.4,\n              \"current_value\": 20200,\n              \"previous_value\": 20700,\n              \"compare_period\": \"2025-01\"\n            },\n            {\n              \"delta\": 10.4,\n              \"current_value\": 22300,\n              \"previous_value\": 20200,\n              \"compare_period\": \"2025-02\"\n            },\n            {\n              \"delta\": -2.2,\n              \"current_value\": 21800,\n              \"previous_value\": 22300,\n              \"compare_period\": \"2025-03\"\n            },\n            {\n              \"delta\": 7.3,\n              \"current_value\": 23400,\n              \"previous_value\": 21800,\n              \"compare_period\": \"2025-04\"\n            }\n          ]\n        }\n      ]\n    },\n    \"calendar_year_volume\": [\n      {\n        \"year\": 2022,\n        \"purchase_volume\": 142300,\n        \"units_purchased\": 6100,\n        \"po_count\": 12,\n        \"sales_volume\": 238700,\n        \"units_sold\": 5840,\n        \"so_count\": 214\n      },\n      {\n        \"year\": 2023,\n        \"purchase_volume\": 168900,\n        \"units_purchased\": 7050,\n        \"po_count\": 14,\n        \"sales_volume\": 281400,\n        \"units_sold\": 6720,\n        \"so_count\": 248\n      },\n      {\n        \"year\": 2024,\n        \"purchase_volume\": 191450,\n        \"units_purchased\": 7780,\n        \"po_count\": 16,\n        \"sales_volume\": 309600,\n        \"units_sold\": 7410,\n        \"so_count\": 271\n      },\n      {\n        \"year\": 2025,\n        \"purchase_volume\": 224800,\n        \"units_purchased\": 8640,\n        \"po_count\": 19,\n        \"sales_volume\": 352100,\n        \"units_sold\": 8190,\n        \"so_count\": 305\n      },\n      {\n        \"year\": 2026,\n        \"purchase_volume\": 86200,\n        \"units_purchased\": 3320,\n        \"po_count\": 7,\n        \"sales_volume\": 131900,\n        \"units_sold\": 3040,\n        \"so_count\": 118\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Supplier Product Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/products?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","products"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]},"description":"Paginated, sortable per-product breakdown for one supplier (Analytics-tab product table). Each row carries units, purchase/sales volume, profit, margin %, sell-through %, landed unit cost, the landed-cost trend direction (cost_trend), and period-over-period growth %.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nFilters (Spatie QueryBuilder):\n- filter[search]: partial match on product SKU or name\n- filter[cost_trend]: landed-unit-cost trend direction — up | down | flat\n- filter[margin]: margin sign — positive (margin > 0) | negative (margin < 0)\n\nSort (sort param, prefix - for DESC). Allowed: units_purchased, units_sold, purchase_volume, sales_volume, profit, margin_pct, sell_through_pct, growth_pct. Default: -purchase_volume\n\nPagination: page (default 1), per_page (default 10).\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — drives the growth_pct column\n- min_volume, include_archived\n\nResponse field cost_trend: up | down | flat — direction of the landed unit cost vs the prior period (always present, defaults to flat)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/products?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","products"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"units_purchased\": 3200,\n      \"units_sold\": 3050,\n      \"purchase_volume\": 42100,\n      \"sales_volume\": 78900,\n      \"profit\": 24600,\n      \"margin_pct\": 31.2,\n      \"sell_through_pct\": 95.3,\n      \"landed_unit_cost\": 13.16,\n      \"cost_trend\": \"up\",\n      \"growth_pct\": 34.2\n    },\n    {\n      \"product_id\": 9044,\n      \"sku\": \"ACM-BRACKET-12\",\n      \"name\": \"Mounting Bracket XL\",\n      \"units_purchased\": 540,\n      \"units_sold\": 410,\n      \"purchase_volume\": 6200,\n      \"sales_volume\": 9800,\n      \"profit\": 2100,\n      \"margin_pct\": 21.4,\n      \"sell_through_pct\": 75.9,\n      \"landed_unit_cost\": 11.48,\n      \"cost_trend\": \"down\",\n      \"growth_pct\": -21.8\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/42/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/42/products?page=5\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/reporting/suppliers/42/products?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/suppliers/42/products\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 47\n}"}]},{"name":"Get Supplier Product Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/products/{product}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","products",":product"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Single-product drill-down for one supplier: current vs previous purchase/sales totals, a landed-cost-per-receipt trend, and the list of alternate suppliers carrying the same SKU with their cost, lead time and reliability.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID\n- product: the Product ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume, include_archived"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/products/{product}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","products",":product"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"current\": {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"purchase_volume\": 42100,\n      \"units_purchased\": 3200,\n      \"sales_volume\": 78900,\n      \"units_sold\": 3050,\n      \"profit\": 24600,\n      \"margin\": 0\n    },\n    \"previous\": {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"purchase_volume\": 31400,\n      \"units_purchased\": 2400,\n      \"sales_volume\": 58200,\n      \"units_sold\": 2280,\n      \"profit\": 17900,\n      \"margin\": 0\n    },\n    \"landed_cost_trend\": [\n      {\n        \"date\": \"2025-07-12\",\n        \"po_number\": \"PO-100482\",\n        \"unit_cost\": 13.4\n      },\n      {\n        \"date\": \"2025-11-03\",\n        \"po_number\": \"PO-101655\",\n        \"unit_cost\": 13.16\n      },\n      {\n        \"date\": \"2026-02-21\",\n        \"po_number\": \"PO-103120\",\n        \"unit_cost\": 12.95\n      }\n    ],\n    \"alternate_suppliers\": [\n      {\n        \"supplier_id\": 58,\n        \"name\": \"Globex Manufacturing\",\n        \"landed_unit_cost\": 12.1,\n        \"leadtime\": 21,\n        \"lead_time_reliability_pct\": 91.5,\n        \"is_default\": false\n      },\n      {\n        \"supplier_id\": 73,\n        \"name\": \"Initech Hardware\",\n        \"landed_unit_cost\": 14.05,\n        \"leadtime\": 35,\n        \"lead_time_reliability_pct\": null,\n        \"is_default\": false\n      }\n    ],\n    \"supplier\": {\n      \"id\": 42,\n      \"name\": \"Acme Components Ltd\"\n    },\n    \"product\": {\n      \"id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\"\n    },\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Supplier PO History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/po-history","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","po-history"],"variable":[{"key":"supplier","value":"42","description":"The Supplier ID"}]},"description":"Recent purchase orders for one supplier — backs the \"Recent Purchase Orders\" mini-table on the supplier Analytics tab. Returns up to the 10 most recent non-draft purchase orders ordered by purchase order date (DESC), each with its receipt status and an on-time flag.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID\n\nThis endpoint is period-independent — it always returns the most recent purchase orders and takes no query parameters. Draft purchase orders are excluded.\n\nResponse fields per row:\n- id: purchase order ID\n- po_number: human-readable purchase order number\n- purchase_order_date: order date (Y-m-d)\n- total_cost: total purchase order cost\n- receipt_status: receipt status of the PO (e.g. unreceived, partially_received, fully_received)\n- on_time: true if fully received on or before the estimated delivery date, false if late, null if not yet fully received"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/po-history","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","po-history"],"variable":[{"key":"supplier","value":"42","description":"The Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8821,\n      \"po_number\": \"PO-2025-0142\",\n      \"purchase_order_date\": \"2025-05-08\",\n      \"total_cost\": 42100,\n      \"receipt_status\": \"fully_received\",\n      \"on_time\": true\n    },\n    {\n      \"id\": 8790,\n      \"po_number\": \"PO-2025-0118\",\n      \"purchase_order_date\": \"2025-04-22\",\n      \"total_cost\": 6200.5,\n      \"receipt_status\": \"partially_received\",\n      \"on_time\": null\n    },\n    {\n      \"id\": 8755,\n      \"po_number\": \"PO-2025-0091\",\n      \"purchase_order_date\": \"2025-03-30\",\n      \"total_cost\": 18750,\n      \"receipt_status\": \"fully_received\",\n      \"on_time\": false\n    }\n  ]\n}"}]},{"name":"Get Supplier Scorecard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]},"description":"Standalone composite scorecard for a supplier over the resolved period — the composite, its band, and the per-dimension breakdown.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe band is one of: excellent, good, needs_attention, poor. When the supplier has fewer received POs than the configured minimum (is_sufficient=false), the band is not_rated and composite is 0.\n\nLive preview: when the optional preview_weights, preview_thresholds and preview_min_po_count parameters are supplied (all three together), the score is computed against a transient, non-persisted settings instance built from those values. Nothing is written to the scorecard settings table. preview_weights must contain all six metric keys and sum to exactly 100.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- supplier: the Supplier ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional period params:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume, include_archived\n\nOptional live-preview params (all three required together when previewing):\n- preview_weights[{metric}]: numeric 0-100 — one per metric, summing to 100\n- preview_thresholds[{metric}][{i}][min]: numeric; preview_thresholds[{metric}][{i}][score]: integer 1-5\n- preview_min_po_count: integer, min 1\n\npreview_weights and preview_thresholds may be passed either as bracketed array params (shown above) or as a single URL-encoded JSON string — the live-preview UI sends them as JSON strings."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/suppliers/{supplier}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","suppliers",":supplier","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"supplier","value":"","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"composite\": 4.15,\n    \"band\": \"good\",\n    \"is_sufficient\": true,\n    \"po_count\": 18,\n    \"dimensions\": [\n      {\n        \"key\": \"on_time_delivery\",\n        \"label\": \"On-Time Delivery\",\n        \"raw\": 92.3,\n        \"raw_display\": \"92.3%\",\n        \"score\": 4,\n        \"weight\": 25\n      },\n      {\n        \"key\": \"lead_time_reliability\",\n        \"label\": \"Lead-Time Reliability\",\n        \"raw\": 88,\n        \"raw_display\": \"88.0%\",\n        \"score\": 3,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"fill_rate\",\n        \"label\": \"Fill Rate\",\n        \"raw\": 98.6,\n        \"raw_display\": \"98.6%\",\n        \"score\": 5,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"defect_rate\",\n        \"label\": \"Defect / RTV Rate\",\n        \"raw\": 1.2,\n        \"raw_display\": \"1.2%\",\n        \"score\": 5,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"cost_competitiveness\",\n        \"label\": \"Cost Competitiveness\",\n        \"raw\": 74.5,\n        \"raw_display\": \"74.5 / 100\",\n        \"score\": 3,\n        \"weight\": 25\n      },\n      {\n        \"key\": \"price_stability\",\n        \"label\": \"Price Stability\",\n        \"raw\": 0.18,\n        \"raw_display\": \"18% price increases\",\n        \"score\": 4,\n        \"weight\": 5\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Macro product dashboard for the resolved period: headline KPIs (sales volume, units sold, profit, active products), the hottest/coldest movers, a 12-month growth heatmap, and the full leaderboard. KPIs and trends are read from monthly product metric snapshots.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required and date_to must be on or after date_from.\n\nOptional:\n- growth_basis: sales | units | profit | margin (default: sales) — the basis used to rank movers and the heatmap\n- min_volume: numeric — minimum sales volume before a product qualifies as a mover\n- sales_channel_id: integer — restrict the dashboard to a single sales channel\n- include_archived: boolean — include archived products (default: false)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"kpis\": {\n      \"sales_volume\": {\n        \"current\": 3120900,\n        \"previous\": 2890400,\n        \"delta_pct\": 8\n      },\n      \"units_sold\": {\n        \"current\": 41200,\n        \"previous\": 39800,\n        \"delta_pct\": 3.5\n      },\n      \"profit\": {\n        \"current\": 961000.25,\n        \"previous\": 905100,\n        \"delta_pct\": 6.2\n      },\n      \"active_products\": {\n        \"current\": 612,\n        \"previous\": 588,\n        \"delta_pct\": 4.1\n      }\n    },\n    \"hottest\": [\n      {\n        \"product_id\": 1042,\n        \"sku\": \"WIDGET-RED-L\",\n        \"name\": \"Red Widget Large\",\n        \"value\": 184250.5,\n        \"delta_pct\": 31.5,\n        \"spark\": [\n          12000,\n          13400,\n          15600,\n          14200,\n          16800,\n          17100,\n          18900,\n          16400,\n          19200,\n          21000,\n          20400,\n          22300\n        ]\n      }\n    ],\n    \"coldest\": [\n      {\n        \"product_id\": 871,\n        \"sku\": \"GADGET-BLU-S\",\n        \"name\": \"Blue Gadget Small\",\n        \"value\": 22400,\n        \"delta_pct\": -18.7,\n        \"spark\": [\n          9100,\n          8700,\n          8200,\n          7600,\n          6900,\n          6400,\n          5800,\n          5100,\n          4700,\n          4200,\n          3900,\n          3400\n        ]\n      }\n    ],\n    \"heatmap\": {\n      \"columns\": [\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\",\n        \"2026-05\"\n      ],\n      \"rows\": [\n        {\n          \"product_id\": 1042,\n          \"sku\": \"WIDGET-RED-L\",\n          \"name\": \"Red Widget Large\",\n          \"cells\": [\n            null,\n            8.2,\n            12.4,\n            -3.1,\n            6.7,\n            9,\n            14.2,\n            -2.4,\n            5.5,\n            11,\n            7.8,\n            12.4\n          ]\n        }\n      ]\n    },\n    \"leaderboard\": [\n      {\n        \"product_id\": 1042,\n        \"sku\": \"WIDGET-RED-L\",\n        \"name\": \"Red Widget Large\",\n        \"sales_volume\": 312900,\n        \"units_sold\": 7950,\n        \"cogs\": 216800,\n        \"profit\": 96100.25,\n        \"margin_pct\": 30.7,\n        \"return_rate_pct\": 2.1,\n        \"growth_pct\": 12.4,\n        \"so_count\": 421,\n        \"is_low_volume\": false\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Product Leaderboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Server-paginated, sortable product leaderboard for the resolved period — used when the macro dashboard's leaderboard table changes page or sort. Returns the standard Laravel pagination envelope.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nAccepts the same period parameters as Get Product Overview, plus:\n- sort: column to sort by, prefix with - for descending\n- page / per_page: standard pagination controls (per_page default 25)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 1042,\n      \"sku\": \"WIDGET-RED-L\",\n      \"name\": \"Red Widget Large\",\n      \"sales_volume\": 312900,\n      \"units_sold\": 7950,\n      \"cogs\": 216800,\n      \"profit\": 96100.25,\n      \"margin_pct\": 30.7,\n      \"return_rate_pct\": 2.1,\n      \"growth_pct\": 12.4,\n      \"so_count\": 421,\n      \"is_low_volume\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 25,\n  \"per_page\": 25,\n  \"total\": 612,\n  \"from\": 1,\n  \"to\": 25,\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/products/leaderboard\"\n}"}]},{"name":"Rebuild Product Metric Snapshots","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/products/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","products","rebuild-snapshots"]},"description":"Dispatches the product-metric snapshot rebuild as a tracked background job and returns its tracked job log ID for progress polling via the tracked job log endpoints. The rebuild recomputes per-channel sales snapshots first, then derives the per-product snapshots by summation. Rejects a second dispatch with 409 while a rebuild is already queued or running.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nThis endpoint takes no request body.","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/products/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","products","rebuild-snapshots"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90871\n  },\n  \"message\": \"Product metric rebuild started.\"\n}"}]},{"name":"Get Product Scorecard Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","products","scorecard-settings"]},"description":"Returns the tenant's product scorecard configuration: the six dimension weights (must sum to 100), the threshold bands that map a raw metric value to a 1–5 score, and min_so_count — the minimum sales-order count before a product is scored.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","products","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"weights\": {\n      \"gross_margin\": 25,\n      \"gmroi\": 15,\n      \"sales_growth\": 20,\n      \"sell_through\": 15,\n      \"stock_cover\": 15,\n      \"return_rate\": 10\n    },\n    \"thresholds\": {\n      \"gross_margin\": [\n        {\n          \"min\": 40,\n          \"score\": 5\n        },\n        {\n          \"min\": 30,\n          \"score\": 4\n        },\n        {\n          \"min\": 20,\n          \"score\": 3\n        },\n        {\n          \"min\": 10,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"gmroi\": [\n        {\n          \"min\": 4,\n          \"score\": 5\n        },\n        {\n          \"min\": 3,\n          \"score\": 4\n        },\n        {\n          \"min\": 2,\n          \"score\": 3\n        },\n        {\n          \"min\": 1,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"sales_growth\": [\n        {\n          \"min\": 25,\n          \"score\": 5\n        },\n        {\n          \"min\": 10,\n          \"score\": 4\n        },\n        {\n          \"min\": 0,\n          \"score\": 3\n        },\n        {\n          \"min\": -15,\n          \"score\": 2\n        },\n        {\n          \"min\": -100,\n          \"score\": 1\n        }\n      ],\n      \"sell_through\": [\n        {\n          \"min\": 90,\n          \"score\": 5\n        },\n        {\n          \"min\": 75,\n          \"score\": 4\n        },\n        {\n          \"min\": 60,\n          \"score\": 3\n        },\n        {\n          \"min\": 40,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"stock_cover\": [\n        {\n          \"min\": 30,\n          \"score\": 5\n        },\n        {\n          \"min\": 21,\n          \"score\": 4\n        },\n        {\n          \"min\": 14,\n          \"score\": 3\n        },\n        {\n          \"min\": 7,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"return_rate\": [\n        {\n          \"min\": 98,\n          \"score\": 5\n        },\n        {\n          \"min\": 95,\n          \"score\": 4\n        },\n        {\n          \"min\": 90,\n          \"score\": 3\n        },\n        {\n          \"min\": 85,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_so_count\": 3\n  }\n}"}]},{"name":"Update Product Scorecard Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/products/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","products","scorecard-settings"]},"description":"Updates the tenant's product scorecard configuration.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequest body (all fields required):\n- weights: object — a numeric weight (0–100) for each of the six dimensions (gross_margin, gmroi, sales_growth, sell_through, stock_cover, return_rate). The six weights must sum to exactly 100.\n- thresholds: object — for each dimension, an array of at least one band; each band has a numeric `min` and an integer `score` between 1 and 5.\n- min_so_count: integer — minimum sales-order count before a product is scored (at least 1).","body":{"mode":"raw","raw":"{\n  \"weights\": {\n    \"gross_margin\": 25,\n    \"gmroi\": 15,\n    \"sales_growth\": 20,\n    \"sell_through\": 15,\n    \"stock_cover\": 15,\n    \"return_rate\": 10\n  },\n  \"thresholds\": {\n    \"gross_margin\": [\n      {\n        \"min\": 40,\n        \"score\": 5\n      },\n      {\n        \"min\": 30,\n        \"score\": 4\n      },\n      {\n        \"min\": 20,\n        \"score\": 3\n      },\n      {\n        \"min\": 10,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"gmroi\": [\n      {\n        \"min\": 4,\n        \"score\": 5\n      },\n      {\n        \"min\": 3,\n        \"score\": 4\n      },\n      {\n        \"min\": 2,\n        \"score\": 3\n      },\n      {\n        \"min\": 1,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"sales_growth\": [\n      {\n        \"min\": 25,\n        \"score\": 5\n      },\n      {\n        \"min\": 10,\n        \"score\": 4\n      },\n      {\n        \"min\": 0,\n        \"score\": 3\n      },\n      {\n        \"min\": -15,\n        \"score\": 2\n      },\n      {\n        \"min\": -100,\n        \"score\": 1\n      }\n    ],\n    \"sell_through\": [\n      {\n        \"min\": 90,\n        \"score\": 5\n      },\n      {\n        \"min\": 75,\n        \"score\": 4\n      },\n      {\n        \"min\": 60,\n        \"score\": 3\n      },\n      {\n        \"min\": 40,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"stock_cover\": [\n      {\n        \"min\": 30,\n        \"score\": 5\n      },\n      {\n        \"min\": 21,\n        \"score\": 4\n      },\n      {\n        \"min\": 14,\n        \"score\": 3\n      },\n      {\n        \"min\": 7,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"return_rate\": [\n      {\n        \"min\": 98,\n        \"score\": 5\n      },\n      {\n        \"min\": 95,\n        \"score\": 4\n      },\n      {\n        \"min\": 90,\n        \"score\": 3\n      },\n      {\n        \"min\": 85,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ]\n  },\n  \"min_so_count\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/products/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","products","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"weights\": {\n      \"gross_margin\": 25,\n      \"gmroi\": 15,\n      \"sales_growth\": 20,\n      \"sell_through\": 15,\n      \"stock_cover\": 15,\n      \"return_rate\": 10\n    },\n    \"thresholds\": {\n      \"gross_margin\": [\n        {\n          \"min\": 40,\n          \"score\": 5\n        },\n        {\n          \"min\": 30,\n          \"score\": 4\n        },\n        {\n          \"min\": 20,\n          \"score\": 3\n        },\n        {\n          \"min\": 10,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"gmroi\": [\n        {\n          \"min\": 4,\n          \"score\": 5\n        },\n        {\n          \"min\": 3,\n          \"score\": 4\n        },\n        {\n          \"min\": 2,\n          \"score\": 3\n        },\n        {\n          \"min\": 1,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"sales_growth\": [\n        {\n          \"min\": 25,\n          \"score\": 5\n        },\n        {\n          \"min\": 10,\n          \"score\": 4\n        },\n        {\n          \"min\": 0,\n          \"score\": 3\n        },\n        {\n          \"min\": -15,\n          \"score\": 2\n        },\n        {\n          \"min\": -100,\n          \"score\": 1\n        }\n      ],\n      \"sell_through\": [\n        {\n          \"min\": 90,\n          \"score\": 5\n        },\n        {\n          \"min\": 75,\n          \"score\": 4\n        },\n        {\n          \"min\": 60,\n          \"score\": 3\n        },\n        {\n          \"min\": 40,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"stock_cover\": [\n        {\n          \"min\": 30,\n          \"score\": 5\n        },\n        {\n          \"min\": 21,\n          \"score\": 4\n        },\n        {\n          \"min\": 14,\n          \"score\": 3\n        },\n        {\n          \"min\": 7,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"return_rate\": [\n        {\n          \"min\": 98,\n          \"score\": 5\n        },\n        {\n          \"min\": 95,\n          \"score\": 4\n        },\n        {\n          \"min\": 90,\n          \"score\": 3\n        },\n        {\n          \"min\": 85,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_so_count\": 3\n  }\n}"}]},{"name":"Get Product Scorecard Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","scorecard-summary"],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Lightweight scorecard payload for the product Profile-tab performance chip: the composite scorecard, a directional trend hint (up | flat | down) and two short volume sparklines (sales volume and units sold).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","scorecard-summary"],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 1042,\n      \"sku\": \"WIDGET-RED-L\",\n      \"name\": \"Red Widget Large\"\n    },\n    \"scorecard\": {\n      \"composite\": 3.85,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"so_count\": 421,\n      \"dimensions\": [\n        {\n          \"key\": \"gross_margin\",\n          \"label\": \"Gross Margin\",\n          \"raw\": 30.7,\n          \"raw_display\": \"30.7%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"gmroi\",\n          \"label\": \"GMROI\",\n          \"raw\": 3.2,\n          \"raw_display\": \"3.2\",\n          \"score\": 4,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"sales_growth\",\n          \"label\": \"Sales Growth\",\n          \"raw\": 12.4,\n          \"raw_display\": \"+12.4%\",\n          \"score\": 4,\n          \"weight\": 20\n        },\n        {\n          \"key\": \"sell_through\",\n          \"label\": \"Sell-Through\",\n          \"raw\": 78,\n          \"raw_display\": \"78%\",\n          \"score\": 4,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"stock_cover\",\n          \"label\": \"Stock Cover\",\n          \"raw\": 18.5,\n          \"raw_display\": \"18.5 days\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"return_rate\",\n          \"label\": \"Return Rate\",\n          \"raw\": 2.1,\n          \"raw_display\": \"2.1%\",\n          \"score\": 5,\n          \"weight\": 10\n        }\n      ]\n    },\n    \"composite_trend\": \"up\",\n    \"sales_volume\": [\n      22100,\n      24300,\n      23800,\n      26100,\n      27400,\n      28900\n    ],\n    \"units_sold\": [\n      560,\n      612,\n      598,\n      651,\n      683,\n      720\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"Trailing 6 months\"\n    }\n  }\n}"}]},{"name":"Get Product Stock Coverage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/stock-coverage","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","stock-coverage"],"variable":[{"key":"product","value":"1042","description":"The product ID"}]},"description":"Daily Average Consumption (DAC) and Days of Stock reconstructed as a 12-month monthly time series for a product. No history is stored for either metric, so both are rebuilt from source ledgers: DAC at each month is gross units sold over the trailing sales-history window divided by that window length; on-hand at each month is the running balance of stock movements up to that month; Days of Stock is on-hand divided by DAC (null when DAC is 0, i.e. coverage is effectively infinite).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID\n\nQuery parameter:\n- months: span of the series - an integer count of trailing months (e.g. 12, 24) or 'all' for the product's full ledger history (capped at 60 months). Default: 12.\n\nResponse fields:\n- buckets: 12 month labels (YYYY-MM), oldest first\n- window_days: the trailing DAC window length in days\n- dac / units_sold / on_hand / days_of_stock: parallel arrays aligned to buckets (units_sold is the raw units sold that calendar month; dac is the trailing-window daily average) (days_of_stock entries are null where DAC is 0)\n- current: the latest bucket's dac, on_hand and days_of_stock"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/stock-coverage","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","stock-coverage"],"variable":[{"key":"product","value":"1042","description":"The product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"buckets\": [\n      \"2025-08\",\n      \"2025-09\",\n      \"2025-10\",\n      \"2025-11\",\n      \"2025-12\",\n      \"2026-01\",\n      \"2026-02\",\n      \"2026-03\",\n      \"2026-04\",\n      \"2026-05\",\n      \"2026-06\",\n      \"2026-07\"\n    ],\n    \"window_days\": 90,\n    \"dac\": [\n      0,\n      0,\n      0.12,\n      0.18,\n      0.2,\n      0.26,\n      0.3,\n      0.34,\n      0.4,\n      0.46,\n      0.52,\n      0.6\n    ],\n    \"units_sold\": [\n      0,\n      0,\n      14,\n      18,\n      20,\n      26,\n      30,\n      34,\n      40,\n      46,\n      52,\n      60\n    ],\n    \"on_hand\": [\n      0,\n      0,\n      120,\n      118,\n      150,\n      210,\n      190,\n      175,\n      160,\n      140,\n      120,\n      100\n    ],\n    \"days_of_stock\": [\n      null,\n      null,\n      1000,\n      655.6,\n      750,\n      807.7,\n      633.3,\n      514.7,\n      400,\n      304.3,\n      230.8,\n      166.7\n    ],\n    \"current\": {\n      \"dac\": 0.6,\n      \"units_sold\": 60,\n      \"on_hand\": 100,\n      \"days_of_stock\": 166.7\n    }\n  }\n}"}]},{"name":"Export Product Stock Coverage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/stock-coverage/export","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","stock-coverage","export"],"variable":[{"key":"product","value":"1042","description":"The product ID"}]},"description":"Download the month-by-month Stock Coverage series as a spreadsheet. Columns: Month, Units Sold (that calendar month), DAC (units/day, trailing-window daily average), On Hand (month-end), Days of Stock (on-hand / DAC). Honors the same 'months' span as the JSON endpoint.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID\n\nQuery parameters:\n- months: trailing-month count or 'all' (default 12)\n- format: 'xlsx' or 'csv' (default xlsx)\n\nReturns a file download (Content-Type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for xlsx, text/csv for csv), not JSON. Filename: stock-coverage-{sku}-{timestamp}.{format}."}},{"name":"Get Product Analytics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Full per-product analytics for the Analytics tab: period KPIs (sales volume, units sold, profit, margin), the computed scorecard, a monthly trend series, the hottest/coolest sales channels, a per-channel growth heatmap and recent orders.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID\n\nAccepts the same period parameters as Get Product Overview."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 1042,\n      \"sku\": \"WIDGET-RED-L\",\n      \"name\": \"Red Widget Large\"\n    },\n    \"kpis\": {\n      \"sales_volume\": {\n        \"current\": 312900,\n        \"previous\": 278400,\n        \"delta_pct\": 12.4\n      },\n      \"units_sold\": {\n        \"current\": 7950,\n        \"previous\": 7420,\n        \"delta_pct\": 7.1\n      },\n      \"profit\": {\n        \"current\": 96100.25,\n        \"previous\": 88200,\n        \"delta_pct\": 9\n      },\n      \"margin_pct\": {\n        \"current\": 30.7,\n        \"previous\": 31.7,\n        \"delta_pct\": -3.2\n      }\n    },\n    \"scorecard\": {\n      \"composite\": 3.85,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"so_count\": 421,\n      \"dimensions\": [\n        {\n          \"key\": \"gross_margin\",\n          \"label\": \"Gross Margin\",\n          \"raw\": 30.7,\n          \"raw_display\": \"30.7%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"gmroi\",\n          \"label\": \"GMROI\",\n          \"raw\": 3.2,\n          \"raw_display\": \"3.2\",\n          \"score\": 4,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"sales_growth\",\n          \"label\": \"Sales Growth\",\n          \"raw\": 12.4,\n          \"raw_display\": \"+12.4%\",\n          \"score\": 4,\n          \"weight\": 20\n        },\n        {\n          \"key\": \"sell_through\",\n          \"label\": \"Sell-Through\",\n          \"raw\": 78,\n          \"raw_display\": \"78%\",\n          \"score\": 4,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"stock_cover\",\n          \"label\": \"Stock Cover\",\n          \"raw\": 18.5,\n          \"raw_display\": \"18.5 days\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"return_rate\",\n          \"label\": \"Return Rate\",\n          \"raw\": 2.1,\n          \"raw_display\": \"2.1%\",\n          \"score\": 5,\n          \"weight\": 10\n        }\n      ]\n    },\n    \"trend\": {\n      \"columns\": [\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\",\n        \"2026-05\"\n      ],\n      \"sales_volume\": [\n        48200,\n        51100,\n        49800,\n        53400,\n        55900,\n        54500\n      ],\n      \"units_sold\": [\n        1210,\n        1280,\n        1250,\n        1340,\n        1410,\n        1460\n      ]\n    },\n    \"hottest_channels\": [\n      {\n        \"sales_channel_id\": 3,\n        \"name\": \"Amazon US\",\n        \"value\": 142800,\n        \"delta_pct\": 24.1\n      }\n    ],\n    \"coolest_channels\": [\n      {\n        \"sales_channel_id\": 7,\n        \"name\": \"eBay\",\n        \"value\": 18400,\n        \"delta_pct\": -12.6\n      }\n    ],\n    \"hottest_customers\": [\n      {\n        \"customer_id\": 5521,\n        \"name\": \"Acme Distributors\",\n        \"value\": 48200,\n        \"delta_pct\": 31.7\n      }\n    ],\n    \"coolest_customers\": [\n      {\n        \"customer_id\": 4310,\n        \"name\": \"Bright Retail Co\",\n        \"value\": 9100,\n        \"delta_pct\": -18.4\n      }\n    ],\n    \"channel_heatmap\": {\n      \"columns\": [\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\",\n        \"2026-05\"\n      ],\n      \"rows\": [\n        {\n          \"sales_channel_id\": 3,\n          \"name\": \"Amazon US\",\n          \"cells\": [\n            6.2,\n            -1.4,\n            8.1,\n            11,\n            4.5,\n            9.3\n          ]\n        }\n      ]\n    },\n    \"recent_orders\": [\n      {\n        \"sales_order_id\": 88213,\n        \"order_number\": \"SO-88213\",\n        \"sales_channel\": \"Amazon US\",\n        \"ordered_at\": \"2026-05-12\",\n        \"units\": 24,\n        \"sales_volume\": 940\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Product Channel Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/channels?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","channels"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Server-paginated, sortable per-sales-channel breakdown for one product — the Channels tab table. Each row carries the channel's units, sales volume, profit, order count, average order value, margin, return rate, share of the product's sales and period-over-period growth. Channel-grain data is sales-side only (purchasing is not channel-attributable).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID\n\nAccepts the same period parameters as Get Product Overview, plus sort / page / per_page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/channels?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","channels"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_channel_id\": 3,\n      \"name\": \"Amazon US\",\n      \"units_sold\": 4820,\n      \"sales_volume\": 142800,\n      \"profit\": 44100,\n      \"order_count\": 412,\n      \"avg_order_value\": 346.6,\n      \"margin_pct\": 30.9,\n      \"return_rate_pct\": 1.8,\n      \"sales_share_pct\": 45.6,\n      \"growth_pct\": 24.1\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 6,\n  \"from\": 1,\n  \"to\": 6,\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/products/1042/channels\"\n}"}]},{"name":"Get Product Channel Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/channels/{salesChannel}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","channels",":salesChannel"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."},{"key":"salesChannel","value":"","description":"The sales channel ID."}]},"description":"Single-channel drill-down for one product: the channel's current and previous-period totals, the product's whole-period totals for a share comparison, and recent orders placed on that channel.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- product: the product ID\n- salesChannel: the sales channel ID\n\nAccepts the same period parameters as Get Product Overview."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/channels/{salesChannel}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","channels",":salesChannel"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."},{"key":"salesChannel","value":"","description":"The sales channel ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 1042,\n      \"sku\": \"WIDGET-RED-L\",\n      \"name\": \"Red Widget Large\"\n    },\n    \"sales_channel_id\": 3,\n    \"current\": {\n      \"units_sold\": 4820,\n      \"sales_volume\": 142800,\n      \"cogs\": 98700,\n      \"profit\": 44100,\n      \"margin_pct\": 30.9,\n      \"returned_units\": 87,\n      \"so_count\": 198\n    },\n    \"previous\": {\n      \"units_sold\": 3910,\n      \"sales_volume\": 115100,\n      \"cogs\": 80200,\n      \"profit\": 34900,\n      \"margin_pct\": 30.3,\n      \"returned_units\": 71,\n      \"so_count\": 162\n    },\n    \"product_current\": {\n      \"units_sold\": 7950,\n      \"sales_volume\": 312900,\n      \"profit\": 96100.25\n    },\n    \"recent_orders\": [\n      {\n        \"sales_order_id\": 88213,\n        \"order_number\": \"SO-88213\",\n        \"ordered_at\": \"2026-05-12\",\n        \"units\": 24,\n        \"sales_volume\": 940\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Product Scorecard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Standalone computed scorecard for one product — the composite, its band and the per-dimension breakdown. Used by the Scorecard Settings live preview.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameter:\n- product: the product ID\n\nAccepts the same period parameters as Get Product Overview. When the optional preview_weights, preview_thresholds and preview_min_so_count parameters are supplied together, the score is computed against a transient, non-persisted settings configuration built from those values — nothing is written to the scorecard settings table. Supplying any one of the three without the others returns a 422."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/products/{product}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","products",":product","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"composite\": 3.85,\n    \"band\": \"good\",\n    \"is_sufficient\": true,\n    \"so_count\": 421,\n    \"dimensions\": [\n      {\n        \"key\": \"gross_margin\",\n        \"label\": \"Gross Margin\",\n        \"raw\": 30.7,\n        \"raw_display\": \"30.7%\",\n        \"score\": 4,\n        \"weight\": 25\n      },\n      {\n        \"key\": \"gmroi\",\n        \"label\": \"GMROI\",\n        \"raw\": 3.2,\n        \"raw_display\": \"3.2\",\n        \"score\": 4,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"sales_growth\",\n        \"label\": \"Sales Growth\",\n        \"raw\": 12.4,\n        \"raw_display\": \"+12.4%\",\n        \"score\": 4,\n        \"weight\": 20\n      },\n      {\n        \"key\": \"sell_through\",\n        \"label\": \"Sell-Through\",\n        \"raw\": 78,\n        \"raw_display\": \"78%\",\n        \"score\": 4,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"stock_cover\",\n        \"label\": \"Stock Cover\",\n        \"raw\": 18.5,\n        \"raw_display\": \"18.5 days\",\n        \"score\": 3,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"return_rate\",\n        \"label\": \"Return Rate\",\n        \"raw\": 2.1,\n        \"raw_display\": \"2.1%\",\n        \"score\": 5,\n        \"weight\": 10\n      }\n    ]\n  }\n}"}]},{"name":"Get Brand Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Macro brand dashboard for the resolved period: headline KPIs (purchase volume, sales volume, profit, active brands), the hottest/coldest movers, a 12-month growth heatmap, and the full leaderboard. KPIs and trends are read from monthly brand metric snapshots.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required and date_to must be on or after date_from.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — the basis used to rank movers and the heatmap\n- min_volume: numeric — minimum purchase volume before a brand qualifies as a mover (default: 1000)\n- include_archived: boolean — include archived brands (default: false)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/overview?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands","overview"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"kpis\": {\n      \"purchase_volume\": {\n        \"current\": 1842500.5,\n        \"previous\": 1640200,\n        \"delta_pct\": 12.3\n      },\n      \"sales_volume\": {\n        \"current\": 3120900,\n        \"previous\": 2890400,\n        \"delta_pct\": 8\n      },\n      \"profit\": {\n        \"current\": 961000.25,\n        \"previous\": 905100,\n        \"delta_pct\": 6.2\n      },\n      \"active_brands\": {\n        \"current\": 48,\n        \"previous\": 45,\n        \"delta_pct\": 6.7\n      }\n    },\n    \"hottest\": [\n      {\n        \"brand_id\": 42,\n        \"name\": \"Acme Housewares\",\n        \"value\": 184250.5,\n        \"delta_pct\": 31.5,\n        \"spark\": [\n          12000,\n          13400,\n          15600,\n          14200,\n          16800,\n          17100,\n          18900,\n          16400,\n          19200,\n          21000,\n          20400,\n          22300\n        ]\n      }\n    ],\n    \"coldest\": [\n      {\n        \"brand_id\": 71,\n        \"name\": \"Borealis Home\",\n        \"value\": 22400,\n        \"delta_pct\": -18.7,\n        \"spark\": [\n          9100,\n          8700,\n          8200,\n          7600,\n          6900,\n          6400,\n          5800,\n          5100,\n          4700,\n          4200,\n          3900,\n          3400\n        ]\n      }\n    ],\n    \"heatmap\": {\n      \"columns\": [\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\",\n        \"2026-05\"\n      ],\n      \"rows\": [\n        {\n          \"brand_id\": 42,\n          \"name\": \"Acme Housewares\",\n          \"cells\": [\n            null,\n            8.2,\n            12.4,\n            -3.1,\n            6.7,\n            9,\n            14.2,\n            -2.4,\n            5.5,\n            11,\n            7.8,\n            12.4\n          ]\n        }\n      ]\n    },\n    \"leaderboard\": [\n      {\n        \"brand_id\": 42,\n        \"name\": \"Acme Housewares\",\n        \"purchase_volume\": 184250.5,\n        \"sales_volume\": 312900,\n        \"units_purchased\": 8400,\n        \"units_sold\": 7950,\n        \"profit\": 96100.25,\n        \"margin_pct\": 30.7,\n        \"growth_pct\": 12.4,\n        \"active_po_count\": 23,\n        \"po_count\": 21,\n        \"is_low_volume\": false\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Brand Leaderboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]},"description":"Leaderboard rows only — a lightweight endpoint for table page/sort changes on the macro brand view, without recomputing KPIs, movers, or the heatmap. Rows are computed in-memory from snapshots, then filtered, sorted and sliced; low-volume brands are flagged via is_low_volume.\n\nServer-paginated (PRD edge case 15: 500+ brands) — returns the standard Laravel pagination envelope (data, current_page, last_page, per_page, total, etc.).\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume: numeric — low-volume threshold (default: 1000)\n- include_archived: boolean (default: false)\n- sort: sort key, prefix - for DESC. Allowed: name, purchase_volume, sales_volume, units_purchased, units_sold, profit, margin_pct, growth_pct, active_po_count (default: -purchase_volume)\n- page: page number (default: 1)\n- per_page: rows per page (default: 10)\n- filter[search]: substring match on brand name\n- filter[volume]: above | low — volume band filter"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/leaderboard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands","leaderboard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"brand_id\": 42,\n      \"name\": \"Acme Housewares\",\n      \"purchase_volume\": 184250.5,\n      \"sales_volume\": 312900,\n      \"units_purchased\": 8400,\n      \"units_sold\": 7950,\n      \"profit\": 96100.25,\n      \"margin_pct\": 30.7,\n      \"growth_pct\": 12.4,\n      \"active_po_count\": 23,\n      \"po_count\": 21,\n      \"is_low_volume\": false\n    },\n    {\n      \"brand_id\": 71,\n      \"name\": \"Borealis Home\",\n      \"purchase_volume\": 22400,\n      \"sales_volume\": 41200,\n      \"units_purchased\": 980,\n      \"units_sold\": 910,\n      \"profit\": 9100.5,\n      \"margin_pct\": 22.1,\n      \"growth_pct\": -18.7,\n      \"active_po_count\": 4,\n      \"po_count\": 5,\n      \"is_low_volume\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/leaderboard?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/leaderboard?page=5\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/leaderboard?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/brands/leaderboard\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"Rebuild Brand Metric Snapshots","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/brands/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","brands","rebuild-snapshots"]},"description":"Dispatches the brand-metric snapshot rebuild as a tracked background job and returns its tracked job log ID for progress polling via the tracked job log endpoints. Rejects a second dispatch with 409 while a rebuild is already queued or running.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nThis endpoint takes no request body.\n\nNote: no request body is required.","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/brands/rebuild-snapshots","host":["{{baseUrl}}"],"path":["api","reporting","brands","rebuild-snapshots"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90871\n  },\n  \"message\": \"Brand metric rebuild started.\"\n}"}]},{"name":"Get Brand Scorecard Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","brands","scorecard-settings"]},"description":"Returns the tenant-global brand scorecard configuration: the six dimension weights (sum to 100), the ordered {min, score} threshold bands per dimension, and the minimum in-period PO count required before a brand is scored. A default row is created on first access if none exists.\n\nAuthentication: Requires Bearer token (scope: reports)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","brands","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"weights\": {\n      \"on_time_delivery\": 25,\n      \"lead_time_reliability\": 15,\n      \"fill_rate\": 15,\n      \"defect_rate\": 15,\n      \"cost_competitiveness\": 25,\n      \"price_stability\": 5\n    },\n    \"thresholds\": {\n      \"on_time_delivery\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"lead_time_reliability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"fill_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"defect_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"cost_competitiveness\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"price_stability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_po_count\": 3,\n    \"created_at\": \"2026-01-04T09:00:00.000000Z\",\n    \"updated_at\": \"2026-05-10T14:22:31.000000Z\"\n  }\n}"}]},{"name":"Update Brand Scorecard Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/brands/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","brands","scorecard-settings"]},"description":"Updates the tenant-global brand scorecard configuration. The six weights must each be present and sum to exactly 100; every threshold band needs a numeric min and an integer 1-5 score.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nRequest body fields:\n- weights: object (required) — must contain all six metric keys; values numeric 0-100, summing to exactly 100\n- weights.on_time_delivery: numeric, 0-100 (required)\n- weights.lead_time_reliability: numeric, 0-100 (required)\n- weights.fill_rate: numeric, 0-100 (required)\n- weights.defect_rate: numeric, 0-100 (required)\n- weights.cost_competitiveness: numeric, 0-100 (required)\n- weights.price_stability: numeric, 0-100 (required)\n- thresholds: object (required) — must contain all six metric keys\n- thresholds.{metric}: array, min 1 item (required) — ordered {min, score} bands\n- thresholds.{metric}.*.min: numeric (required) — lower bound of the band\n- thresholds.{metric}.*.score: integer 1-5 (required) — score awarded for the band\n- min_po_count: integer, min 1 (required)","body":{"mode":"raw","raw":"{\n  \"weights\": {\n    \"on_time_delivery\": 25,\n    \"lead_time_reliability\": 15,\n    \"fill_rate\": 15,\n    \"defect_rate\": 15,\n    \"cost_competitiveness\": 25,\n    \"price_stability\": 5\n  },\n  \"thresholds\": {\n    \"on_time_delivery\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"lead_time_reliability\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"fill_rate\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"defect_rate\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"cost_competitiveness\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ],\n    \"price_stability\": [\n      {\n        \"min\": 97,\n        \"score\": 5\n      },\n      {\n        \"min\": 90,\n        \"score\": 4\n      },\n      {\n        \"min\": 80,\n        \"score\": 3\n      },\n      {\n        \"min\": 60,\n        \"score\": 2\n      },\n      {\n        \"min\": 0,\n        \"score\": 1\n      }\n    ]\n  },\n  \"min_po_count\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/reporting/brands/scorecard-settings","host":["{{baseUrl}}"],"path":["api","reporting","brands","scorecard-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"weights\": {\n      \"on_time_delivery\": 25,\n      \"lead_time_reliability\": 15,\n      \"fill_rate\": 15,\n      \"defect_rate\": 15,\n      \"cost_competitiveness\": 25,\n      \"price_stability\": 5\n    },\n    \"thresholds\": {\n      \"on_time_delivery\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"lead_time_reliability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"fill_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"defect_rate\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"cost_competitiveness\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ],\n      \"price_stability\": [\n        {\n          \"min\": 97,\n          \"score\": 5\n        },\n        {\n          \"min\": 90,\n          \"score\": 4\n        },\n        {\n          \"min\": 80,\n          \"score\": 3\n        },\n        {\n          \"min\": 60,\n          \"score\": 2\n        },\n        {\n          \"min\": 0,\n          \"score\": 1\n        }\n      ]\n    },\n    \"min_po_count\": 3,\n    \"created_at\": \"2026-01-04T09:00:00.000000Z\",\n    \"updated_at\": \"2026-05-10T14:22:31.000000Z\"\n  }\n}"}]},{"name":"Get Brand Scorecard Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","scorecard-summary"],"variable":[{"key":"brand","value":"","description":"The brand ID."}]},"description":"Lightweight scorecard + volume sparklines for the brand Profile chip. Returns the composite scorecard with its dimension breakdown, a directional composite trend hint (up | down | flat), and trailing-12-month purchase/sales volume sparklines. The period is fixed to YoY.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/scorecard-summary","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","scorecard-summary"],"variable":[{"key":"brand","value":"","description":"The brand ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"brand\": {\n      \"id\": 42,\n      \"name\": \"Acme Housewares\"\n    },\n    \"scorecard\": {\n      \"composite\": 4.15,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"po_count\": 18,\n      \"dimensions\": [\n        {\n          \"key\": \"on_time_delivery\",\n          \"label\": \"On-Time Delivery\",\n          \"raw\": 92.3,\n          \"raw_display\": \"92.3%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"lead_time_reliability\",\n          \"label\": \"Lead-Time Reliability\",\n          \"raw\": 88,\n          \"raw_display\": \"88.0%\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"fill_rate\",\n          \"label\": \"Fill Rate\",\n          \"raw\": 98.6,\n          \"raw_display\": \"98.6%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"defect_rate\",\n          \"label\": \"Defect / RTV Rate\",\n          \"raw\": 1.2,\n          \"raw_display\": \"1.2%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"cost_competitiveness\",\n          \"label\": \"Cost Competitiveness\",\n          \"raw\": 74.5,\n          \"raw_display\": \"74.5 / 100\",\n          \"score\": 3,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"price_stability\",\n          \"label\": \"Price Stability\",\n          \"raw\": 0.18,\n          \"raw_display\": \"18% price increases\",\n          \"score\": 4,\n          \"weight\": 5\n        }\n      ]\n    },\n    \"composite_trend\": \"up\",\n    \"purchase_volume\": {\n      \"current\": 184250.5,\n      \"previous\": 158900,\n      \"delta_pct\": 16,\n      \"spark\": [\n        12000,\n        13400,\n        15600,\n        14200,\n        16800,\n        17100,\n        18900,\n        16400,\n        19200,\n        21000,\n        20400,\n        22300\n      ]\n    },\n    \"sales_volume\": {\n      \"current\": 312900,\n      \"previous\": 289400,\n      \"delta_pct\": 8.1,\n      \"spark\": [\n        22000,\n        23100,\n        24800,\n        25600,\n        26100,\n        27400,\n        26900,\n        28200,\n        29400,\n        30100,\n        31200,\n        32400\n      ]\n    },\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Brand Analytics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]},"description":"Full per-brand analytics for the Analytics tab: headline KPIs (purchase volume, sales volume, units purchased/sold, profit, margin %), the composite scorecard, a dual-line current-vs-previous trend chart, and the hottest/coolest products ranked by growth.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — drives the trend metric and product mover ranking\n- min_volume: numeric (default: 1000)\n- include_archived: boolean (default: false)\n\nThe response also includes `product_heatmap` (a period-aware per-product growth heatmap — the brand's top products by volume, each cell a period-over-period change that follows the `period_mode` selector) and `calendar_year_volume` (per calendar year for the trailing 5 years: non-draft PO spend with units/PO counts plus non-draft sales revenue with units/order counts; the current year is year-to-date and is independent of `period_mode`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/analytics?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","analytics"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"brand\": {\n      \"id\": 42,\n      \"name\": \"Acme Housewares\"\n    },\n    \"kpis\": {\n      \"purchase_volume\": {\n        \"current\": 184250.5,\n        \"previous\": 158900,\n        \"delta_pct\": 16\n      },\n      \"sales_volume\": {\n        \"current\": 312900,\n        \"previous\": 289400,\n        \"delta_pct\": 8.1\n      },\n      \"units_purchased\": {\n        \"current\": 8400,\n        \"previous\": 7600,\n        \"delta_pct\": 10.5\n      },\n      \"units_sold\": {\n        \"current\": 7950,\n        \"previous\": 7400,\n        \"delta_pct\": 7.4\n      },\n      \"profit\": {\n        \"current\": 96100.25,\n        \"previous\": 88200,\n        \"delta_pct\": 9\n      },\n      \"margin_pct\": {\n        \"current\": 30.7,\n        \"previous\": 30.5,\n        \"delta_pct\": 0.2\n      }\n    },\n    \"scorecard\": {\n      \"composite\": 4.15,\n      \"band\": \"good\",\n      \"is_sufficient\": true,\n      \"po_count\": 18,\n      \"dimensions\": [\n        {\n          \"key\": \"on_time_delivery\",\n          \"label\": \"On-Time Delivery\",\n          \"raw\": 92.3,\n          \"raw_display\": \"92.3%\",\n          \"score\": 4,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"lead_time_reliability\",\n          \"label\": \"Lead-Time Reliability\",\n          \"raw\": 88,\n          \"raw_display\": \"88.0%\",\n          \"score\": 3,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"fill_rate\",\n          \"label\": \"Fill Rate\",\n          \"raw\": 98.6,\n          \"raw_display\": \"98.6%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"defect_rate\",\n          \"label\": \"Defect / RTV Rate\",\n          \"raw\": 1.2,\n          \"raw_display\": \"1.2%\",\n          \"score\": 5,\n          \"weight\": 15\n        },\n        {\n          \"key\": \"cost_competitiveness\",\n          \"label\": \"Cost Competitiveness\",\n          \"raw\": 74.5,\n          \"raw_display\": \"74.5 / 100\",\n          \"score\": 3,\n          \"weight\": 25\n        },\n        {\n          \"key\": \"price_stability\",\n          \"label\": \"Price Stability\",\n          \"raw\": 0.18,\n          \"raw_display\": \"18% price increases\",\n          \"score\": 4,\n          \"weight\": 5\n        }\n      ]\n    },\n    \"trend\": {\n      \"metric\": \"sales\",\n      \"buckets\": [\n        \"2025-05\",\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\"\n      ],\n      \"current\": [\n        14200,\n        15600,\n        16800,\n        17100,\n        18900,\n        16400,\n        19200,\n        21000,\n        20400,\n        22300,\n        21800,\n        23400\n      ],\n      \"previous\": [\n        12100,\n        13400,\n        14000,\n        14900,\n        15600,\n        14100,\n        16800,\n        18200,\n        17900,\n        19400,\n        18800,\n        20100\n      ]\n    },\n    \"hottest_products\": [\n      {\n        \"product_id\": 9001,\n        \"sku\": \"ACM-WIDGET-01\",\n        \"name\": \"Widget Assembly Type A\",\n        \"value\": 42100,\n        \"delta_pct\": 34.2\n      }\n    ],\n    \"coolest_products\": [\n      {\n        \"product_id\": 9044,\n        \"sku\": \"ACM-BRACKET-12\",\n        \"name\": \"Mounting Bracket XL\",\n        \"value\": 6200,\n        \"delta_pct\": -21.8\n      }\n    ],\n    \"product_heatmap\": {\n      \"columns\": [\n        \"2025-05\",\n        \"2025-06\",\n        \"2025-07\",\n        \"2025-08\",\n        \"2025-09\",\n        \"2025-10\",\n        \"2025-11\",\n        \"2025-12\",\n        \"2026-01\",\n        \"2026-02\",\n        \"2026-03\",\n        \"2026-04\"\n      ],\n      \"rows\": [\n        {\n          \"product_id\": 9001,\n          \"sku\": \"ACM-WIDGET-01\",\n          \"name\": \"Widget Assembly Type A\",\n          \"cells\": [\n            {\n              \"delta\": null,\n              \"current_value\": 11800,\n              \"previous_value\": null,\n              \"compare_period\": \"2024-05\"\n            },\n            {\n              \"delta\": 12.4,\n              \"current_value\": 13300,\n              \"previous_value\": 11830,\n              \"compare_period\": \"2024-06\"\n            },\n            {\n              \"delta\": 8.1,\n              \"current_value\": 14380,\n              \"previous_value\": 13300,\n              \"compare_period\": \"2024-07\"\n            },\n            {\n              \"delta\": -3.2,\n              \"current_value\": 13920,\n              \"previous_value\": 14380,\n              \"compare_period\": \"2024-08\"\n            },\n            {\n              \"delta\": 19.5,\n              \"current_value\": 16640,\n              \"previous_value\": 13920,\n              \"compare_period\": \"2024-09\"\n            },\n            {\n              \"delta\": -6.7,\n              \"current_value\": 15520,\n              \"previous_value\": 16640,\n              \"compare_period\": \"2024-10\"\n            },\n            {\n              \"delta\": 22,\n              \"current_value\": 18940,\n              \"previous_value\": 15520,\n              \"compare_period\": \"2024-11\"\n            },\n            {\n              \"delta\": 9.3,\n              \"current_value\": 20700,\n              \"previous_value\": 18940,\n              \"compare_period\": \"2024-12\"\n            },\n            {\n              \"delta\": -2.4,\n              \"current_value\": 20200,\n              \"previous_value\": 20700,\n              \"compare_period\": \"2025-01\"\n            },\n            {\n              \"delta\": 10.4,\n              \"current_value\": 22300,\n              \"previous_value\": 20200,\n              \"compare_period\": \"2025-02\"\n            },\n            {\n              \"delta\": -2.2,\n              \"current_value\": 21800,\n              \"previous_value\": 22300,\n              \"compare_period\": \"2025-03\"\n            },\n            {\n              \"delta\": 7.3,\n              \"current_value\": 23400,\n              \"previous_value\": 21800,\n              \"compare_period\": \"2025-04\"\n            }\n          ]\n        }\n      ]\n    },\n    \"calendar_year_volume\": [\n      {\n        \"year\": 2022,\n        \"purchase_volume\": 142300,\n        \"units_purchased\": 6100,\n        \"po_count\": 12,\n        \"sales_volume\": 238700,\n        \"units_sold\": 5840,\n        \"so_count\": 214\n      },\n      {\n        \"year\": 2023,\n        \"purchase_volume\": 168900,\n        \"units_purchased\": 7050,\n        \"po_count\": 14,\n        \"sales_volume\": 281400,\n        \"units_sold\": 6720,\n        \"so_count\": 248\n      },\n      {\n        \"year\": 2024,\n        \"purchase_volume\": 191450,\n        \"units_purchased\": 7780,\n        \"po_count\": 16,\n        \"sales_volume\": 309600,\n        \"units_sold\": 7410,\n        \"so_count\": 271\n      },\n      {\n        \"year\": 2025,\n        \"purchase_volume\": 224800,\n        \"units_purchased\": 8640,\n        \"po_count\": 19,\n        \"sales_volume\": 352100,\n        \"units_sold\": 8190,\n        \"so_count\": 305\n      },\n      {\n        \"year\": 2026,\n        \"purchase_volume\": 86200,\n        \"units_purchased\": 3320,\n        \"po_count\": 7,\n        \"sales_volume\": 131900,\n        \"units_sold\": 3040,\n        \"so_count\": 118\n      }\n    ],\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Brand Product Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/products?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","products"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]},"description":"Paginated, sortable per-product breakdown for one brand (Analytics-tab product table). Each row carries units, purchase/sales volume, profit, margin %, sell-through %, landed unit cost, the landed-cost trend direction (cost_trend), and period-over-period growth %.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nFilters (Spatie QueryBuilder):\n- filter[search]: partial match on product SKU or name\n- filter[cost_trend]: landed-unit-cost trend direction — up | down | flat\n- filter[margin]: margin sign — positive (margin > 0) | negative (margin < 0)\n\nSort (sort param, prefix - for DESC). Allowed: units_purchased, units_sold, purchase_volume, sales_volume, profit, margin_pct, sell_through_pct, growth_pct. Default: -purchase_volume\n\nPagination: page (default 1), per_page (default 10).\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales) — drives the growth_pct column\n- min_volume, include_archived\n\nResponse field cost_trend: up | down | flat — direction of the landed unit cost vs the prior period (always present, defaults to flat)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/products?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","products"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"units_purchased\": 3200,\n      \"units_sold\": 3050,\n      \"purchase_volume\": 42100,\n      \"sales_volume\": 78900,\n      \"profit\": 24600,\n      \"margin_pct\": 31.2,\n      \"sell_through_pct\": 95.3,\n      \"landed_unit_cost\": 13.16,\n      \"cost_trend\": \"up\",\n      \"growth_pct\": 34.2\n    },\n    {\n      \"product_id\": 9044,\n      \"sku\": \"ACM-BRACKET-12\",\n      \"name\": \"Mounting Bracket XL\",\n      \"units_purchased\": 540,\n      \"units_sold\": 410,\n      \"purchase_volume\": 6200,\n      \"sales_volume\": 9800,\n      \"profit\": 2100,\n      \"margin_pct\": 21.4,\n      \"sell_through_pct\": 75.9,\n      \"landed_unit_cost\": 11.48,\n      \"cost_trend\": \"down\",\n      \"growth_pct\": -21.8\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/42/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/42/products?page=5\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/reporting/brands/42/products?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/reporting/brands/42/products\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 47\n}"}]},{"name":"Get Brand Product Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/products/{product}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","products",":product"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Single-product drill-down for one brand: current vs previous purchase/sales totals, a landed-cost-per-receipt trend, and the list of suppliers carrying the same SKU with their cost, lead time and reliability.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID\n- product: the Product ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume, include_archived"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/products/{product}?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","products",":product"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"current\": {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"purchase_volume\": 42100,\n      \"units_purchased\": 3200,\n      \"sales_volume\": 78900,\n      \"units_sold\": 3050,\n      \"profit\": 24600,\n      \"margin\": 0\n    },\n    \"previous\": {\n      \"product_id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\",\n      \"name\": \"Widget Assembly Type A\",\n      \"purchase_volume\": 31400,\n      \"units_purchased\": 2400,\n      \"sales_volume\": 58200,\n      \"units_sold\": 2280,\n      \"profit\": 17900,\n      \"margin\": 0\n    },\n    \"landed_cost_trend\": [\n      {\n        \"date\": \"2025-07-12\",\n        \"po_number\": \"PO-100482\",\n        \"unit_cost\": 13.4\n      },\n      {\n        \"date\": \"2025-11-03\",\n        \"po_number\": \"PO-101655\",\n        \"unit_cost\": 13.16\n      },\n      {\n        \"date\": \"2026-02-21\",\n        \"po_number\": \"PO-103120\",\n        \"unit_cost\": 12.95\n      }\n    ],\n    \"suppliers\": [\n      {\n        \"supplier_id\": 58,\n        \"name\": \"Globex Manufacturing\",\n        \"landed_unit_cost\": 12.1,\n        \"leadtime\": 21,\n        \"lead_time_reliability_pct\": 91.5,\n        \"is_default\": false\n      },\n      {\n        \"supplier_id\": 73,\n        \"name\": \"Initech Hardware\",\n        \"landed_unit_cost\": 14.05,\n        \"leadtime\": 35,\n        \"lead_time_reliability_pct\": null,\n        \"is_default\": false\n      }\n    ],\n    \"brand\": {\n      \"id\": 42,\n      \"name\": \"Acme Housewares\"\n    },\n    \"product\": {\n      \"id\": 9001,\n      \"sku\": \"ACM-WIDGET-01\"\n    },\n    \"meta\": {\n      \"data_as_of\": \"2026-05-14T03:12:08+00:00\",\n      \"period_label\": \"YoY — May 2025 – May 2026 vs May 2024 – May 2025\",\n      \"current_range\": [\n        \"2025-05-16\",\n        \"2026-05-15\"\n      ],\n      \"previous_range\": [\n        \"2024-05-16\",\n        \"2025-05-15\"\n      ],\n      \"is_partial\": false,\n      \"is_live_query\": false\n    }\n  }\n}"}]},{"name":"Get Brand PO History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/po-history","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","po-history"],"variable":[{"key":"brand","value":"42","description":"The Brand ID"}]},"description":"Recent purchase orders containing one brand's products — backs the \"Recent Purchase Orders\" mini-table on the brand Analytics tab. Returns up to the 10 most recent non-draft purchase orders ordered by purchase order date (DESC), each with its receipt status and an on-time flag.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID\n\nThis endpoint is period-independent — it always returns the most recent purchase orders and takes no query parameters. Draft purchase orders are excluded.\n\nResponse fields per row:\n- id: purchase order ID\n- po_number: human-readable purchase order number\n- purchase_order_date: order date (Y-m-d)\n- total_cost: total purchase order cost\n- receipt_status: receipt status of the PO (e.g. unreceived, partially_received, fully_received)\n- on_time: true if fully received on or before the estimated delivery date, false if late, null if not yet fully received"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/po-history","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","po-history"],"variable":[{"key":"brand","value":"42","description":"The Brand ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8821,\n      \"po_number\": \"PO-2025-0142\",\n      \"purchase_order_date\": \"2025-05-08\",\n      \"total_cost\": 42100,\n      \"receipt_status\": \"fully_received\",\n      \"on_time\": true\n    },\n    {\n      \"id\": 8790,\n      \"po_number\": \"PO-2025-0118\",\n      \"purchase_order_date\": \"2025-04-22\",\n      \"total_cost\": 6200.5,\n      \"receipt_status\": \"partially_received\",\n      \"on_time\": null\n    },\n    {\n      \"id\": 8755,\n      \"po_number\": \"PO-2025-0091\",\n      \"purchase_order_date\": \"2025-03-30\",\n      \"total_cost\": 18750,\n      \"receipt_status\": \"fully_received\",\n      \"on_time\": false\n    }\n  ]\n}"}]},{"name":"Get Brand Scorecard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]},"description":"Standalone composite scorecard for a brand over the resolved period — the composite, its band, and the per-dimension breakdown.\n\nThe band is one of: excellent, good, needs_attention, poor. When the brand has fewer received POs than the configured minimum (is_sufficient=false), the band is not_rated and composite is 0.\n\nLive preview: when the optional preview_weights, preview_thresholds and preview_min_po_count parameters are supplied (all three together), the score is computed against a transient, non-persisted settings instance built from those values. Nothing is written to the scorecard settings table. preview_weights must contain all six metric keys and sum to exactly 100.\n\nAuthentication: Requires Bearer token (scope: reports)\n\nPath parameters:\n- brand: the Brand ID\n\nRequired parameters:\n- period_mode: yoy | qoq | mom | custom\n\nWhen period_mode=custom, date_from and date_to (YYYY-MM-DD or m/d/Y) are both required.\n\nOptional period params:\n- growth_basis: spend | sales | profit | margin (default: sales)\n- min_volume, include_archived\n\nOptional live-preview params (all three required together when previewing):\n- preview_weights[{metric}]: numeric 0-100 — one per metric, summing to 100\n- preview_thresholds[{metric}][{i}][min]: numeric; preview_thresholds[{metric}][{i}][score]: integer 1-5\n- preview_min_po_count: integer, min 1\n\npreview_weights and preview_thresholds may be passed either as bracketed array params (shown above) or as a single URL-encoded JSON string — the live-preview UI sends them as JSON strings."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/brands/{brand}/scorecard?period_mode=yoy","host":["{{baseUrl}}"],"path":["api","reporting","brands",":brand","scorecard"],"query":[{"key":"period_mode","value":"yoy","description":"Required. Period comparison model: yoy | qoq | mom | custom","disabled":true}],"variable":[{"key":"brand","value":"","description":"The brand ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"composite\": 4.15,\n    \"band\": \"good\",\n    \"is_sufficient\": true,\n    \"po_count\": 18,\n    \"dimensions\": [\n      {\n        \"key\": \"on_time_delivery\",\n        \"label\": \"On-Time Delivery\",\n        \"raw\": 92.3,\n        \"raw_display\": \"92.3%\",\n        \"score\": 4,\n        \"weight\": 25\n      },\n      {\n        \"key\": \"lead_time_reliability\",\n        \"label\": \"Lead-Time Reliability\",\n        \"raw\": 88,\n        \"raw_display\": \"88.0%\",\n        \"score\": 3,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"fill_rate\",\n        \"label\": \"Fill Rate\",\n        \"raw\": 98.6,\n        \"raw_display\": \"98.6%\",\n        \"score\": 5,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"defect_rate\",\n        \"label\": \"Defect / RTV Rate\",\n        \"raw\": 1.2,\n        \"raw_display\": \"1.2%\",\n        \"score\": 5,\n        \"weight\": 15\n      },\n      {\n        \"key\": \"cost_competitiveness\",\n        \"label\": \"Cost Competitiveness\",\n        \"raw\": 74.5,\n        \"raw_display\": \"74.5 / 100\",\n        \"score\": 3,\n        \"weight\": 25\n      },\n      {\n        \"key\": \"price_stability\",\n        \"label\": \"Price Stability\",\n        \"raw\": 0.18,\n        \"raw_display\": \"18% price increases\",\n        \"score\": 4,\n        \"weight\": 5\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Data Health Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-data-health/metrics","host":["{{baseUrl}}"],"path":["api","product-data-health","metrics"]},"description":"Aggregated product data-health metrics for the Product Data Health dashboard: product-type distribution, active/archived breakdown, unit-cost health (>0 / =0 / null), brand and supplier coverage, supplier-price health, kit/bundle component gaps, pricing coverage, image health, and sales-channel mapping coverage.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nImage health: `products_with_image` / `products_without_image` reflect image presence (a primary or any product image). `products_with_broken_image` counts products whose primary image was checked and found unresolvable by the on-demand image-health check (see POST /api/product-data-health/check-image-health). `image_health_last_checked_at` is the most recent time any product image was validated (UTC, ISO-8601), or null if no check has ever run.\n\nAuthentication: Requires Bearer token (scope: products read-write).\n\nOptional filters (all narrow every metric):\n- archived_status: active | archived — restrict to active or archived products\n- brand_id: integer — restrict to a single brand\n- default_supplier_id: integer — restrict to products whose default supplier matches"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-data-health/metrics","host":["{{baseUrl}}"],"path":["api","product-data-health","metrics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"product_counts_by_type\": {\n    \"standard\": 1240,\n    \"kit\": 85,\n    \"bundle\": 42,\n    \"variation\": 30,\n    \"variation_child\": 180\n  },\n  \"total_products\": 1577,\n  \"active_products\": 1402,\n  \"archived_products\": 175,\n  \"active_products_by_type\": {\n    \"standard\": 1100,\n    \"kit\": 78,\n    \"bundle\": 38,\n    \"variation\": 28,\n    \"variation_child\": 158\n  },\n  \"archived_products_by_type\": {\n    \"standard\": 140,\n    \"kit\": 7,\n    \"bundle\": 4,\n    \"variation\": 2,\n    \"variation_child\": 22\n  },\n  \"products_with_unit_cost\": 1180,\n  \"products_with_zero_unit_cost\": 95,\n  \"products_with_null_unit_cost\": 302,\n  \"products_with_unit_cost_by_type\": {\n    \"standard\": 980,\n    \"kit\": 60,\n    \"bundle\": 30,\n    \"variation_child\": 110\n  },\n  \"products_with_zero_unit_cost_by_type\": {\n    \"standard\": 80,\n    \"kit\": 5,\n    \"bundle\": 4,\n    \"variation_child\": 6\n  },\n  \"products_with_null_unit_cost_by_type\": {\n    \"standard\": 180,\n    \"kit\": 20,\n    \"bundle\": 8,\n    \"variation_child\": 64\n  },\n  \"products_with_brand\": 1320,\n  \"products_without_brand\": 257,\n  \"brand_distribution\": [\n    {\n      \"name\": \"Acme\",\n      \"count\": 540\n    },\n    {\n      \"name\": \"Globex\",\n      \"count\": 320\n    },\n    {\n      \"name\": \"Unbranded\",\n      \"count\": 257\n    }\n  ],\n  \"products_with_supplier\": 1190,\n  \"products_without_supplier\": 387,\n  \"products_with_supplier_by_type\": {\n    \"standard\": 1000,\n    \"variation_child\": 190\n  },\n  \"products_without_supplier_by_type\": {\n    \"standard\": 240,\n    \"variation_child\": 147\n  },\n  \"supplier_count_distribution\": [\n    {\n      \"supplier_count\": 1,\n      \"products\": 900\n    },\n    {\n      \"supplier_count\": 2,\n      \"products\": 220\n    },\n    {\n      \"supplier_count\": 3,\n      \"products\": 70\n    }\n  ],\n  \"products_with_zero_supplier_price\": 64,\n  \"products_with_non_zero_supplier_price\": 1126,\n  \"default_supplier_pricing_tier_name\": \"Default Cost\",\n  \"kits_without_components\": 3,\n  \"bundles_without_components\": 1,\n  \"total_kits\": 85,\n  \"total_bundles\": 42,\n  \"products_with_pricing\": 1450,\n  \"products_without_pricing\": 127,\n  \"products_without_pricing_by_type\": {\n    \"standard\": 90,\n    \"kit\": 12,\n    \"bundle\": 5,\n    \"variation_child\": 20\n  },\n  \"default_pricing_tier_name\": \"Retail\",\n  \"products_with_image\": 1390,\n  \"products_without_image\": 187,\n  \"products_without_image_by_type\": {\n    \"standard\": 150,\n    \"kit\": 18,\n    \"bundle\": 9,\n    \"variation_child\": 10\n  },\n  \"products_with_broken_image\": 12,\n  \"image_health_last_checked_at\": \"2026-06-09T14:32:00.000000Z\",\n  \"mapped_product_listings\": 2104,\n  \"unmapped_sales_channel_products\": 96,\n  \"sales_channel_mapping_by_channel\": [\n    {\n      \"name\": \"Amazon US\",\n      \"mapped\": 980,\n      \"unmapped\": 40,\n      \"integration_instance_id\": 12,\n      \"channel_type\": \"amazon\"\n    },\n    {\n      \"name\": \"Shopify Storefront\",\n      \"mapped\": 1124,\n      \"unmapped\": 56,\n      \"integration_instance_id\": 7,\n      \"channel_type\": \"shopify\"\n    }\n  ]\n}"}]},{"name":"Check Image Health","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/product-data-health/check-image-health","host":["{{baseUrl}}"],"path":["api","product-data-health","check-image-health"]},"description":"Dispatch the on-demand image-health check job. The job re-validates every product image — local (disk) images are checked for existence on their storage disk, remote (URL) images via an HTTP request — records the result on each product image (resolvable + checked-at), and surfaces progress through the tracked job log endpoints.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the tracked job log id so the frontend can follow progress via the tracked job log endpoints. There is no request body.\n\nAuthentication: Requires Bearer token (scope: products read-write)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-data-health/check-image-health","host":["{{baseUrl}}"],"path":["api","product-data-health","check-image-health"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84213\n  },\n  \"message\": \"Image health check started\"\n}"}]},{"name":"Sales by Source Type (POS vs Online)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/sales-by-source-type","host":["{{baseUrl}}"],"path":["api","reporting","sales-by-source-type"]},"description":"Omnichannel sales segmented by sub-sales-channel source type (in-store / Point of Sale vs online vs marketplace). Integration-agnostic — aggregates Shopify POS, Square, and any classified source. Returns per-segment order_count, units, line revenue, plus point_of_sale_total and online_total. Optional date_from/date_to (Y-m-d). Authenticate with a Personal Access Token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/sales-by-source-type","host":["{{baseUrl}}"],"path":["api","reporting","sales-by-source-type"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"source_type\": \"point_of_sale\",\n      \"label\": \"Point of Sale\",\n      \"order_count\": 42,\n      \"units\": 118,\n      \"revenue\": 3840.5\n    },\n    {\n      \"source_type\": \"online\",\n      \"label\": \"Online\",\n      \"order_count\": 97,\n      \"units\": 210,\n      \"revenue\": 8120\n    }\n  ],\n  \"point_of_sale_total\": 3840.5,\n  \"online_total\": 8120\n}"}]},{"name":"List Supplier IRR Ranking","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers"]},"description":"Rank every supplier by the pooled internal rate of return on the cash deployed with them.\n\nEach row's `xirr` is the annualized money-weighted return (0.549 = 54.9%), pooled across all the entity's non-draft purchase orders — deposit and balance payments out, then net sales proceeds in as the received units sell through, plus remaining stock valued at cost as of today. Also returns the cash multiple (`moic`), profit, capital deployed, days deployed, and units sold. Rows are ranked by IRR (unsolvable rows sort last with `is_rankable=false`). Amounts are in the account's base currency. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currency_code\": \"USD\",\n    \"last_refreshed_at\": \"2026-07-18T04:30:11+00:00\",\n    \"eligible_po_count\": 47,\n    \"covered_po_count\": 47,\n    \"pending_po_count\": 0,\n    \"summary\": {\n      \"entity_count\": 3,\n      \"ranked_count\": 3,\n      \"total_capital_deployed\": 26750,\n      \"total_profit\": 8125.8,\n      \"blended_moic\": 1.3038,\n      \"best\": {\n        \"id\": 12,\n        \"name\": \"Rainier Roasters\",\n        \"sku\": null,\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      \"worst\": {\n        \"id\": 21,\n        \"name\": \"Umbrella Goods\",\n        \"sku\": null,\n        \"xirr\": -0.0312,\n        \"period_return\": 0.05,\n        \"moic\": 0.98,\n        \"profit\": -197.6,\n        \"capital_deployed\": 9750,\n        \"total_cash_in\": 9552.4,\n        \"npv_at_hurdle\": -410,\n        \"days_capital_deployed\": 280,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 38,\n        \"pct_realized\": 0.25,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    },\n    \"rows\": [\n      {\n        \"id\": 12,\n        \"name\": \"Rainier Roasters\",\n        \"sku\": null,\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      {\n        \"id\": 7,\n        \"name\": \"Acme Supplies\",\n        \"sku\": null,\n        \"xirr\": 1.6112,\n        \"period_return\": 0.05,\n        \"moic\": 1.46,\n        \"profit\": 3670.4,\n        \"capital_deployed\": 8000,\n        \"total_cash_in\": 11670.4,\n        \"npv_at_hurdle\": 3120.1,\n        \"days_capital_deployed\": 240,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 74,\n        \"pct_realized\": 0.74,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      {\n        \"id\": 21,\n        \"name\": \"Umbrella Goods\",\n        \"sku\": null,\n        \"xirr\": -0.0312,\n        \"period_return\": 0.05,\n        \"moic\": 0.98,\n        \"profit\": -197.6,\n        \"capital_deployed\": 9750,\n        \"total_cash_in\": 9552.4,\n        \"npv_at_hurdle\": -410,\n        \"days_capital_deployed\": 280,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 38,\n        \"pct_realized\": 0.25,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    ]\n  }\n}"}]},{"name":"List Product IRR Ranking","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/products","host":["{{baseUrl}}"],"path":["api","reporting","irr","products"]},"description":"Rank every product by the internal rate of return on its purchasing cash flows (each order's flows prorated to the product by its cost share of the order).\n\nEach row's `xirr` is the annualized money-weighted return (0.549 = 54.9%), pooled across all the entity's non-draft purchase orders — deposit and balance payments out, then net sales proceeds in as the received units sell through, plus remaining stock valued at cost as of today. Also returns the cash multiple (`moic`), profit, capital deployed, days deployed, and units sold. Rows are ranked by IRR (unsolvable rows sort last with `is_rankable=false`). Amounts are in the account's base currency. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/products","host":["{{baseUrl}}"],"path":["api","reporting","irr","products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currency_code\": \"USD\",\n    \"last_refreshed_at\": \"2026-07-18T04:30:11+00:00\",\n    \"eligible_po_count\": 47,\n    \"covered_po_count\": 47,\n    \"pending_po_count\": 0,\n    \"summary\": {\n      \"entity_count\": 2,\n      \"ranked_count\": 2,\n      \"total_capital_deployed\": 16200,\n      \"total_profit\": 8109,\n      \"blended_moic\": 1.5006,\n      \"best\": {\n        \"id\": 31,\n        \"name\": \"Cold Brew Concentrate 32oz\",\n        \"sku\": \"CB-32\",\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      \"worst\": {\n        \"id\": 44,\n        \"name\": \"Gooseneck Kettle 1.2L\",\n        \"sku\": \"KET-GN-12\",\n        \"xirr\": 1.5701,\n        \"period_return\": 0.05,\n        \"moic\": 1.48,\n        \"profit\": 3456,\n        \"capital_deployed\": 7200,\n        \"total_cash_in\": 10656,\n        \"npv_at_hurdle\": 2980.2,\n        \"days_capital_deployed\": 320,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 90,\n        \"pct_realized\": 1,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    },\n    \"rows\": [\n      {\n        \"id\": 31,\n        \"name\": \"Cold Brew Concentrate 32oz\",\n        \"sku\": \"CB-32\",\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      {\n        \"id\": 44,\n        \"name\": \"Gooseneck Kettle 1.2L\",\n        \"sku\": \"KET-GN-12\",\n        \"xirr\": 1.5701,\n        \"period_return\": 0.05,\n        \"moic\": 1.48,\n        \"profit\": 3456,\n        \"capital_deployed\": 7200,\n        \"total_cash_in\": 10656,\n        \"npv_at_hurdle\": 2980.2,\n        \"days_capital_deployed\": 320,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 90,\n        \"pct_realized\": 1,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    ]\n  }\n}"}]},{"name":"List Supplier Product IRR Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/products","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","products"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"For one supplier, return its own pooled IRR (in `supplier`) plus every product purchased from it, ranked by IRR.\n\nEach row's `xirr` is the annualized money-weighted return (0.549 = 54.9%), pooled across all the entity's non-draft purchase orders — deposit and balance payments out, then net sales proceeds in as the received units sell through, plus remaining stock valued at cost as of today. Also returns the cash multiple (`moic`), profit, capital deployed, days deployed, and units sold. Rows are ranked by IRR (unsolvable rows sort last with `is_rankable=false`). Amounts are in the account's base currency. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/products","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","products"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currency_code\": \"USD\",\n    \"last_refreshed_at\": \"2026-07-18T04:30:11+00:00\",\n    \"eligible_po_count\": 47,\n    \"covered_po_count\": 47,\n    \"pending_po_count\": 0,\n    \"summary\": {\n      \"entity_count\": 1,\n      \"ranked_count\": 1,\n      \"total_capital_deployed\": 9000,\n      \"total_profit\": 4653,\n      \"blended_moic\": 1.517,\n      \"best\": {\n        \"id\": 31,\n        \"name\": \"Cold Brew Concentrate 32oz\",\n        \"sku\": \"CB-32\",\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      },\n      \"worst\": {\n        \"id\": 31,\n        \"name\": \"Cold Brew Concentrate 32oz\",\n        \"sku\": \"CB-32\",\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    },\n    \"supplier\": {\n      \"id\": 12,\n      \"name\": \"Rainier Roasters\",\n      \"sku\": null,\n      \"xirr\": 5.4903,\n      \"period_return\": 0.05,\n      \"moic\": 1.52,\n      \"profit\": 4653,\n      \"capital_deployed\": 9000,\n      \"total_cash_in\": 13653,\n      \"npv_at_hurdle\": 4091.55,\n      \"days_capital_deployed\": 150,\n      \"po_count\": 1,\n      \"units_bought\": 1000,\n      \"units_sold\": 188,\n      \"pct_realized\": 0.94,\n      \"selling_since\": \"2025-02-14\",\n      \"is_short_hold\": false,\n      \"is_provisional\": false,\n      \"is_rankable\": true\n    },\n    \"rows\": [\n      {\n        \"id\": 31,\n        \"name\": \"Cold Brew Concentrate 32oz\",\n        \"sku\": \"CB-32\",\n        \"xirr\": 5.4903,\n        \"period_return\": 0.05,\n        \"moic\": 1.52,\n        \"profit\": 4653,\n        \"capital_deployed\": 9000,\n        \"total_cash_in\": 13653,\n        \"npv_at_hurdle\": 4091.55,\n        \"days_capital_deployed\": 150,\n        \"po_count\": 1,\n        \"units_bought\": 1000,\n        \"units_sold\": 188,\n        \"pct_realized\": 0.94,\n        \"selling_since\": \"2025-02-14\",\n        \"is_short_hold\": false,\n        \"is_provisional\": false,\n        \"is_rankable\": true\n      }\n    ]\n  }\n}"}]},{"name":"List Supplier Reconciliation Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/reconciliation-events","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","reconciliation-events"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"The bulk stock-take write-off events behind a supplier's reconciliation figure, grouped by stock-take (largest first) with per-product lines. Each event carries the stock-take date, warehouse, status, mode (full_count or adjustment), variance direction, units, and cost value, plus a link to the stock-take record. Use to see exactly which physical counts wrote off inventory.\n\nAuthentication: requires a Bearer token.\n\nQuery params: `since` (optional) restricts to purchase orders placed on/after the date."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/reconciliation-events","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","reconciliation-events"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entity\": {\n      \"type\": \"supplier\",\n      \"id\": 17,\n      \"name\": \"Example Supplier\",\n      \"sku\": null\n    },\n    \"currency_code\": \"USD\",\n    \"total_value\": 28416.43,\n    \"total_units\": 234,\n    \"event_count\": 2,\n    \"events\": [\n      {\n        \"stock_take_id\": 147,\n        \"reference\": \"Stock Take #147\",\n        \"link_route\": \"/inventory/stock-takes/147?tab=movements\",\n        \"date\": \"2026-06-11\",\n        \"warehouse\": \"Main Warehouse\",\n        \"status\": \"closed\",\n        \"mode\": \"full_count\",\n        \"variance_direction\": \"mixed\",\n        \"notes\": \"Stock take created from inventory discrepancies found during the fulfillment-provider sync.\",\n        \"value_change\": -45028.88,\n        \"units\": 233,\n        \"value\": 28305.58,\n        \"lines\": [\n          {\n            \"product_id\": 517,\n            \"product_name\": \"Diagnostic Scanner Pro\",\n            \"sku\": \"SCAN-PRO\",\n            \"product_route\": \"/products/517\",\n            \"units\": 28,\n            \"value\": 7154.7,\n            \"unit_cost\": 255.53,\n            \"variance_reason\": \"damage\",\n            \"variance_reason_label\": \"Damage\",\n            \"counted_before\": 75,\n            \"counted_after\": 47,\n            \"purchase_orders\": [\n              {\n                \"id\": 373,\n                \"number\": \"PO-0318\",\n                \"route\": \"/orders/purchase-orders/373\"\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"List Product Reconciliation Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/products/{product}/reconciliation-events","host":["{{baseUrl}}"],"path":["api","reporting","irr","products",":product","reconciliation-events"],"variable":[{"key":"product","value":"34","description":"Product ID"}]},"description":"The bulk stock-take write-off events behind a product's reconciliation figure, grouped by stock-take (largest first). Each event carries the stock-take date, warehouse, status, mode, variance direction, units, and cost value, plus a link to the stock-take record.\n\nAuthentication: requires a Bearer token.\n\nQuery params: `since` (optional) restricts to purchase orders placed on/after the date."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/products/{product}/reconciliation-events","host":["{{baseUrl}}"],"path":["api","reporting","irr","products",":product","reconciliation-events"],"variable":[{"key":"product","value":"34","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entity\": {\n      \"type\": \"supplier\",\n      \"id\": 17,\n      \"name\": \"Example Supplier\",\n      \"sku\": null\n    },\n    \"currency_code\": \"USD\",\n    \"total_value\": 28416.43,\n    \"total_units\": 234,\n    \"event_count\": 2,\n    \"events\": [\n      {\n        \"stock_take_id\": 147,\n        \"reference\": \"Stock Take #147\",\n        \"link_route\": \"/inventory/stock-takes/147?tab=movements\",\n        \"date\": \"2026-06-11\",\n        \"warehouse\": \"Main Warehouse\",\n        \"status\": \"closed\",\n        \"mode\": \"full_count\",\n        \"variance_direction\": \"mixed\",\n        \"notes\": \"Stock take created from inventory discrepancies found during the fulfillment-provider sync.\",\n        \"value_change\": -45028.88,\n        \"units\": 233,\n        \"value\": 28305.58,\n        \"lines\": [\n          {\n            \"product_id\": 517,\n            \"product_name\": \"Diagnostic Scanner Pro\",\n            \"sku\": \"SCAN-PRO\",\n            \"product_route\": \"/products/517\",\n            \"units\": 28,\n            \"value\": 7154.7,\n            \"unit_cost\": 255.53,\n            \"variance_reason\": \"damage\",\n            \"variance_reason_label\": \"Damage\",\n            \"counted_before\": 75,\n            \"counted_after\": 47,\n            \"purchase_orders\": [\n              {\n                \"id\": 373,\n                \"number\": \"PO-0318\",\n                \"route\": \"/orders/purchase-orders/373\"\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Get Supplier Cash-Flow Proof","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/cash-flows","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","cash-flows"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"The full proof behind a supplier's pooled return: the pooled metrics, a monthly cash-flow shape (money-in/out + running cumulative for charts), the dated cash-flow ledger (every flow the MIRR is solved on, each linked to its source document), and a per-purchase-order contribution breakdown.\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/suppliers/{supplier}/cash-flows","host":["{{baseUrl}}"],"path":["api","reporting","irr","suppliers",":supplier","cash-flows"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entity\": {\n      \"type\": \"supplier\",\n      \"id\": 4,\n      \"name\": \"Example Supplier\",\n      \"sku\": null\n    },\n    \"currency_code\": \"USD\",\n    \"metrics\": {\n      \"id\": 4,\n      \"name\": \"Example Supplier\",\n      \"xirr\": 0.93,\n      \"xirr_exact\": null,\n      \"moic\": 1.89,\n      \"profit\": 67425,\n      \"capital_deployed\": 75480,\n      \"total_cash_in\": 142905,\n      \"days_capital_deployed\": 472,\n      \"po_count\": 2,\n      \"units_sold\": 1641,\n      \"pct_realized\": 0.66,\n      \"is_rankable\": true\n    },\n    \"monthly\": [\n      {\n        \"month\": \"2025-01\",\n        \"inflow\": 212.5,\n        \"outflow\": 0,\n        \"net\": 212.5,\n        \"cumulative\": 212.5\n      },\n      {\n        \"month\": \"2025-02\",\n        \"inflow\": 1078.31,\n        \"outflow\": -65480,\n        \"net\": -64401.69,\n        \"cumulative\": -64189.19\n      }\n    ],\n    \"flows\": [\n      {\n        \"date\": \"2025-02-19\",\n        \"amount\": -65480,\n        \"type\": \"deposit\",\n        \"label\": \"Vendor deposit\",\n        \"source_type\": \"App\\\\Models\\\\VendorDeposit\",\n        \"source_type_label\": \"Vendor Deposit\",\n        \"source_id\": 812,\n        \"source_route\": null\n      },\n      {\n        \"date\": \"2025-04-18\",\n        \"amount\": 9180,\n        \"type\": \"sale\",\n        \"label\": \"Sale of 42 unit(s)\",\n        \"source_type\": \"App\\\\Models\\\\SalesOrderLine\",\n        \"source_type_label\": \"Sales Order Line\",\n        \"source_id\": 10233,\n        \"source_route\": null\n      }\n    ],\n    \"flows_total\": 510,\n    \"purchase_orders\": [\n      {\n        \"id\": 312,\n        \"number\": \"PO-0269\",\n        \"route\": \"/orders/purchase-orders/312\",\n        \"date\": \"2025-02-19\",\n        \"capital\": 65480,\n        \"cash_in\": 142904.65,\n        \"profit\": 77424.65,\n        \"moic\": 2.1824,\n        \"xirr\": 1.12,\n        \"days_held\": 544,\n        \"pct_realized\": 0.66\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Cash-Flow Proof","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/products/{product}/cash-flows","host":["{{baseUrl}}"],"path":["api","reporting","irr","products",":product","cash-flows"],"variable":[{"key":"product","value":"34","description":"Product ID"}]},"description":"The full proof behind a product's pooled return (cash flows prorated to the product's cost share of each order): pooled metrics, monthly cash-flow shape, the dated ledger, and per-purchase-order breakdown.\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/irr/products/{product}/cash-flows","host":["{{baseUrl}}"],"path":["api","reporting","irr","products",":product","cash-flows"],"variable":[{"key":"product","value":"34","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"entity\": {\n      \"type\": \"product\",\n      \"id\": 4,\n      \"name\": \"Example Product\",\n      \"sku\": null\n    },\n    \"currency_code\": \"USD\",\n    \"metrics\": {\n      \"id\": 4,\n      \"name\": \"Example Supplier\",\n      \"xirr\": 0.93,\n      \"xirr_exact\": null,\n      \"moic\": 1.89,\n      \"profit\": 67425,\n      \"capital_deployed\": 75480,\n      \"total_cash_in\": 142905,\n      \"days_capital_deployed\": 472,\n      \"po_count\": 2,\n      \"units_sold\": 1641,\n      \"pct_realized\": 0.66,\n      \"is_rankable\": true\n    },\n    \"monthly\": [\n      {\n        \"month\": \"2025-01\",\n        \"inflow\": 212.5,\n        \"outflow\": 0,\n        \"net\": 212.5,\n        \"cumulative\": 212.5\n      },\n      {\n        \"month\": \"2025-02\",\n        \"inflow\": 1078.31,\n        \"outflow\": -65480,\n        \"net\": -64401.69,\n        \"cumulative\": -64189.19\n      }\n    ],\n    \"flows\": [\n      {\n        \"date\": \"2025-02-19\",\n        \"amount\": -65480,\n        \"type\": \"deposit\",\n        \"label\": \"Vendor deposit\",\n        \"source_type\": \"App\\\\Models\\\\VendorDeposit\",\n        \"source_type_label\": \"Vendor Deposit\",\n        \"source_id\": 812,\n        \"source_route\": null\n      },\n      {\n        \"date\": \"2025-04-18\",\n        \"amount\": 9180,\n        \"type\": \"sale\",\n        \"label\": \"Sale of 42 unit(s)\",\n        \"source_type\": \"App\\\\Models\\\\SalesOrderLine\",\n        \"source_type_label\": \"Sales Order Line\",\n        \"source_id\": 10233,\n        \"source_route\": null\n      }\n    ],\n    \"flows_total\": 510,\n    \"purchase_orders\": [\n      {\n        \"id\": 312,\n        \"number\": \"PO-0269\",\n        \"route\": \"/orders/purchase-orders/312\",\n        \"date\": \"2025-02-19\",\n        \"capital\": 65480,\n        \"cash_in\": 142904.65,\n        \"profit\": 77424.65,\n        \"moic\": 2.1824,\n        \"xirr\": 1.12,\n        \"days_held\": 544,\n        \"pct_realized\": 0.66\n      }\n    ]\n  }\n}"}]},{"name":"Refresh IRR Metrics","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/irr/refresh","host":["{{baseUrl}}"],"path":["api","reporting","irr","refresh"]},"description":"Recompute every eligible purchase order's return metric in the background so the supplier and product IRR leaderboards reflect fresh figures. The leaderboards read these persisted metrics, so a refresh is what updates `last_refreshed_at` and clears any pending (not-yet-computed) purchase orders.\n\nRuns as a background job and returns immediately. Idempotent: if a refresh is already running, `started` is `false` and no second run is queued. Requires a Bearer token with reports write access."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/reporting/irr/refresh","host":["{{baseUrl}}"],"path":["api","reporting","irr","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"started\": true,\n    \"tracked_job_log_id\": 4821\n  }\n}"}]},{"name":"List Supplier Pickup Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reports/supplier-pickup-orders","host":["{{baseUrl}}"],"path":["api","reports","supplier-pickup-orders"]},"description":"Paginated Supplier Pickup Orders report — one row per drop-ship purchase-order line whose requested shipping method is a supplier pickup (vendor will-call), so a customer collects the goods directly from the merchant's supplier. Each row carries COGS (from the purchase-order line), revenue (from the matching sales-order line), margin, the customer, the supplier, the pickup location, and the derived pickup status.\n\nFilters (Spatie `filter[...]`): search (SKU, product name, PO number, SO number, customer name, supplier name, or row id), status (picked_up | awaiting_pickup | all), customer_id (comma-separated customer ids), supplier_id (comma-separated), warehouse_id (comma-separated pickup-location / supplier-warehouse ids), customer_tag (comma-separated tag names on the customer).\n\nAdvanced grouped filters are also accepted via a `filter_groups` tree over the columns expected_pickup_at, order_date, quantity, customer, supplier, product, sku.\n\nSorting (`sort`, prefix `-` for descending): id, order_date, expected_pickup_at, days_open, customer, supplier. Default order is newest order date first.\n\nPagination: page, per_page (default 10).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reports/supplier-pickup-orders","host":["{{baseUrl}}"],"path":["api","reports","supplier-pickup-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 98,\n      \"sales_order\": {\n        \"id\": 512,\n        \"number\": \"SO-9236\",\n        \"route\": \"/orders/sales-orders/512\"\n      },\n      \"purchase_order\": {\n        \"id\": 28,\n        \"number\": \"PO-0028\",\n        \"route\": \"/orders/purchase-orders/28\"\n      },\n      \"customer\": {\n        \"id\": 44,\n        \"name\": \"Harbor Freight Traders\",\n        \"route\": \"/crm/customers/44\"\n      },\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Shenzhen Helmet Co.\",\n        \"route\": \"/crm/suppliers/7\"\n      },\n      \"pickup_location\": \"Shenzhen Supplier DC\",\n      \"product\": {\n        \"id\": 61,\n        \"sku\": \"5884265723882\",\n        \"name\": \"Carbon Track Helmet\",\n        \"route\": \"/products/61/overview\"\n      },\n      \"quantity\": 180,\n      \"order_date\": \"2026-06-27T00:00:00+00:00\",\n      \"expected_pickup_at\": \"2026-09-07T00:00:00+00:00\",\n      \"days_open\": 27,\n      \"status\": \"awaiting_pickup\",\n      \"unit_cost\": 14,\n      \"cogs\": 2520,\n      \"revenue\": 5670,\n      \"margin\": 3150,\n      \"margin_pct\": 0.5556,\n      \"currency\": \"USD\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/reports/supplier-pickup-orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/reports/supplier-pickup-orders?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/reports/supplier-pickup-orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 3\n}"}]},{"name":"Get Supplier Pickup Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reports/supplier-pickup-orders/summary","host":["{{baseUrl}}"],"path":["api","reports","supplier-pickup-orders","summary"]},"description":"KPI summary totals for the Supplier Pickup Orders report header cards. Honours the same filters as the list endpoint (search, customer_id, supplier_id, warehouse_id, customer_tag, and the advanced filter_groups) EXCEPT status, which is ignored so both the awaiting and picked-up buckets are always represented.\n\nReturns: open_count (distinct orders awaiting pickup), units_awaiting, value_awaiting (COGS of awaiting lines), picked_up_count (distinct picked-up orders), revenue_period and margin_period (revenue / margin of picked-up lines).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reports/supplier-pickup-orders/summary","host":["{{baseUrl}}"],"path":["api","reports","supplier-pickup-orders","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"open_count\": 1,\n    \"units_awaiting\": 180,\n    \"value_awaiting\": 2520,\n    \"picked_up_count\": 2,\n    \"revenue_period\": 13230,\n    \"margin_period\": 7350\n  }\n}"}]}]},{"name":"Product Listings (V2)","item":[{"name":"End Listing on Channel","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}/end","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing","end"],"variable":[{"key":"productListing","value":"1","description":"The ProductListing ID to end on its sales channel"}]},"description":"End a live listing on its sales channel (listing publishing).\n\nPer-channel semantics:\n- Amazon: deletes the SKU's listings item (SP-API deleteListingsItem)\n- BigCommerce: hides the product (is_visible=false, reversible)\n- eBay: ends the item (Trading EndFixedPriceItem, EndingReason=NotAvailable)\n- Walmart: retires the item (DELETE /v3/items/{sku}, async up to 48h)\n- Shopify: archives the product (productUpdate status ARCHIVED, reversible)\n- WooCommerce: trashes the product (DELETE without force, reversible)\n\nOn success the local ProductListing's remote_status is stamped with the channel-side state the listing was left in — `missing` for hard deletes/retires (Amazon, eBay, Walmart) or `archived` for native unpublish (Shopify, BigCommerce, WooCommerce) — so the catalog coverage matrix demotes the cell and offers a republish.\n\nAuthentication: Requires Bearer token. Gated by the per-tenant listing-publishing feature flag (403 when disabled).\n\nIdempotent: ending a listing that was already removed on the channel still succeeds (remote_status becomes `missing`)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/product-listings/{productListing}/end","host":["{{baseUrl}}"],"path":["api","v2","product-listings",":productListing","end"],"variable":[{"key":"productListing","value":"1","description":"The ProductListing ID to end on its sales channel"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"remote_status\": \"archived\",\n    \"remote_status_checked_at\": \"2026-07-03T08:15:42.000000Z\"\n  },\n  \"message\": \"Listing ended on the channel.\"\n}"}]}]},{"name":"PDF Templates","item":[{"name":"List PDF Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates","host":["{{baseUrl}}"],"path":["api","pdf-templates"]},"description":"Returns every global (non store-specific) PDF template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nEach template includes its raw `content`, resolved `variables`, a grouped `variables_tree`/`schema`, and `type`. Template types: purchase_order, sales_order, packing, quote, pick_list, vendor_credit, sales_credit. There is no server-side type filter — request the full list and filter by `type` on the client."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates","host":["{{baseUrl}}"],"path":["api","pdf-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Purchase Order\",\n      \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n      \"type\": \"purchase_order\",\n      \"description\": \"Default purchase order layout.\",\n      \"variables\": [\n        {\n          \"name\": \"Order Number\",\n          \"variable\": \"order_number\",\n          \"mockValue\": \"PO-2044\"\n        },\n        {\n          \"name\": \"Vendor Name\",\n          \"variable\": \"vendor_name\",\n          \"mockValue\": \"Acme Supply Co.\"\n        }\n      ],\n      \"variables_tree\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"PO-2044\"\n            }\n          }\n        }\n      },\n      \"schema\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"PO-2044\"\n            }\n          }\n        }\n      },\n      \"store_id\": null,\n      \"store_name\": null,\n      \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Sales Order\",\n      \"content\": \"<html><body><h1>Sales Order {{order_number}}</h1></body></html>\",\n      \"type\": \"sales_order\",\n      \"description\": \"Default sales order layout.\",\n      \"variables\": [\n        {\n          \"name\": \"Order Number\",\n          \"variable\": \"order_number\",\n          \"mockValue\": \"SO-1001\"\n        },\n        {\n          \"name\": \"Customer Name\",\n          \"variable\": \"customer_name\",\n          \"mockValue\": \"Jane Doe\"\n        }\n      ],\n      \"variables_tree\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        }\n      },\n      \"schema\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        }\n      },\n      \"store_id\": null,\n      \"store_name\": null,\n      \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Packing Slip\",\n      \"content\": \"<html><body><h1>Packing Slip {{order_number}}</h1>{{#items}}<p>{{sku}} x {{quantity}}</p>{{/items}}</body></html>\",\n      \"type\": \"packing\",\n      \"description\": \"Default packing slip layout.\",\n      \"variables\": [\n        {\n          \"name\": \"Order Number\",\n          \"variable\": \"order_number\",\n          \"mockValue\": \"SO-1001\"\n        },\n        {\n          \"name\": \"Warehouse\",\n          \"variable\": \"warehouse\",\n          \"mockValue\": \"Main Warehouse\"\n        },\n        {\n          \"name\": \"Items\",\n          \"variable\": \"items\",\n          \"mockValue\": \"\"\n        }\n      ],\n      \"variables_tree\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        },\n        \"items\": {\n          \"label\": \"Items\",\n          \"type\": \"section\",\n          \"mock\": \"\"\n        },\n        \"asset\": {\n          \"label\": \"Custom Assets\",\n          \"children\": {\n            \"company_logo\": {\n              \"label\": \"Company Logo\",\n              \"type\": \"html\",\n              \"mock\": \"\"\n            }\n          }\n        }\n      },\n      \"schema\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        },\n        \"items\": {\n          \"label\": \"Items\",\n          \"type\": \"section\",\n          \"mock\": \"\"\n        },\n        \"asset\": {\n          \"label\": \"Custom Assets\",\n          \"children\": {\n            \"company_logo\": {\n              \"label\": \"Company Logo\",\n              \"type\": \"html\",\n              \"mock\": \"\"\n            }\n          }\n        }\n      },\n      \"store_id\": null,\n      \"store_name\": null,\n      \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n    }\n  ]\n}"}]},{"name":"Get PDF Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Returns a single PDF template by ID, including its raw `content`, resolved `variables`, and `variables_tree`/`schema`.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Purchase Order\",\n    \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n    \"type\": \"purchase_order\",\n    \"description\": \"Default purchase order layout.\",\n    \"variables\": [\n      {\n        \"name\": \"Order Number\",\n        \"variable\": \"order_number\",\n        \"mockValue\": \"PO-2044\"\n      },\n      {\n        \"name\": \"Vendor Name\",\n        \"variable\": \"vendor_name\",\n        \"mockValue\": \"Acme Supply Co.\"\n      }\n    ],\n    \"variables_tree\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"store_id\": null,\n    \"store_name\": null,\n    \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n  }\n}"}]},{"name":"Update PDF Template","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Updates the `content` of a PDF template and snapshots the previous content as a new version.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access).\n\nFields:\n- content (required): the template markup string.\n- updated_at (optional): the template's last-known `updated_at` timestamp. When supplied it enables optimistic-lock checking so a concurrent edit is rejected instead of silently overwritten.","body":{"mode":"raw","raw":"{\n  \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1><p>Updated layout</p></body></html>\",\n  \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Purchase Order\",\n    \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1><p>Updated layout</p></body></html>\",\n    \"type\": \"purchase_order\",\n    \"description\": \"Default purchase order layout.\",\n    \"variables\": [\n      {\n        \"name\": \"Order Number\",\n        \"variable\": \"order_number\",\n        \"mockValue\": \"PO-2044\"\n      },\n      {\n        \"name\": \"Vendor Name\",\n        \"variable\": \"vendor_name\",\n        \"mockValue\": \"Acme Supply Co.\"\n      }\n    ],\n    \"variables_tree\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"store_id\": null,\n    \"store_name\": null,\n    \"updated_at\": \"2026-07-21T09:15:00+00:00\"\n  }\n}"}]},{"name":"Reset PDF Template to Default","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/reset","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","reset"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Resets a PDF template back to its built-in default content and records the reset as a new version so the prior content can still be restored.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/reset","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","reset"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Purchase Order\",\n    \"content\": \"<html><body><!-- default purchase order layout --></body></html>\",\n    \"type\": \"purchase_order\",\n    \"description\": \"Default purchase order layout.\",\n    \"variables\": [\n      {\n        \"name\": \"Order Number\",\n        \"variable\": \"order_number\",\n        \"mockValue\": \"PO-2044\"\n      },\n      {\n        \"name\": \"Vendor Name\",\n        \"variable\": \"vendor_name\",\n        \"mockValue\": \"Acme Supply Co.\"\n      }\n    ],\n    \"variables_tree\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"store_id\": null,\n    \"store_name\": null,\n    \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n  }\n}"}]},{"name":"Preview PDF Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/preview","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","preview"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Renders a preview of draft template content without saving it, using sample data.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nFields:\n- content (required): the draft markup to render.\n- format (optional): `pdf` (default) returns a base64-encoded PDF in `data.pdf`; `html` returns rendered markup in `data.html`.\n- sales_order_id (optional): render against a real sales order's data instead of sample data. Only applied for packing-slip templates; ignored for other types.\n\nInvalid template markup returns a 422 with the offending line rather than a server error.","body":{"mode":"raw","raw":"{\n  \"content\": \"<html><body><h1>Packing Slip {{order_number}}</h1></body></html>\",\n  \"format\": \"pdf\",\n  \"sales_order_id\": 4821\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/preview","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","preview"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pdf\": \"JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDEgMCBSL1Jlc291cmNlcyAyIDAgUj4+CmVuZG9iagolJUVPRg==\",\n    \"type\": \"application/pdf\",\n    \"rendered_with\": \"wkhtmltopdf\"\n  }\n}"}]},{"name":"Preview Packing Slip for a Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pdf-templates/preview-sales-order","host":["{{baseUrl}}"],"path":["api","pdf-templates","preview-sales-order"]},"description":"Renders the saved packing-slip template against a real sales order and returns a base64-encoded PDF in `data.pdf`.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nFields:\n- sales_order_id (required): the sales order to render.","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 4821\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/preview-sales-order","host":["{{baseUrl}}"],"path":["api","pdf-templates","preview-sales-order"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pdf\": \"JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDEgMCBSL1Jlc291cmNlcyAyIDAgUj4+CmVuZG9iagolJUVPRg==\",\n    \"type\": \"application/pdf\"\n  }\n}"}]},{"name":"List Sales Orders for Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/search-sales-orders","host":["{{baseUrl}}"],"path":["api","pdf-templates","search-sales-orders"]},"description":"Returns up to 20 recent sales orders (newest first) for use when picking a sample order to preview a packing slip against.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nQuery params:\n- search (optional): match against the sales order number.\n- store_id (optional): restrict results to a single store."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates/search-sales-orders","host":["{{baseUrl}}"],"path":["api","pdf-templates","search-sales-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"sales_order_number\": \"SO-1001\",\n      \"store_id\": 3,\n      \"store_name\": \"Acme Store\",\n      \"order_date\": \"2026-07-18T00:00:00+00:00\"\n    },\n    {\n      \"id\": 4805,\n      \"sales_order_number\": \"SO-0998\",\n      \"store_id\": 3,\n      \"store_name\": \"Acme Store\",\n      \"order_date\": \"2026-07-17T00:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Validate PDF Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/validate","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","validate"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Validates draft template content against the template type's schema without rendering it. Use this to surface unknown variables, unbalanced sections, and non-blocking warnings before saving.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nFields:\n- content (required): the draft markup to validate.\n\nThe response `data` contains `ok` (true when there are no errors), an `errors` array, and a `warnings` array.","body":{"mode":"raw","raw":"{\n  \"content\": \"<html><body><h1>{{order_number}}</h1>{{#items}}<p>{{sku}}</p>{{/items}}</body></html>\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/validate","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","validate"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ok\": true,\n    \"errors\": [],\n    \"warnings\": [\n      \"Template has no line-items block ({{items}} or {{#items}}…{{/items}}). The PDF will render without itemized rows.\"\n    ]\n  }\n}"}]},{"name":"List PDF Template Versions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Returns the change history for a template, newest first, as a paginated list. Each version captures the content at that point plus who changed it and why.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nThis endpoint returns a standard paginator envelope (`data`, `current_page`, `last_page`, `per_page`, `total`, …) rather than the `{ data: ... }` wrapper used by the other endpoints.\n\nQuery params:\n- page (optional): page number (default 1).\n- per_page (optional): items per page (default 10).\n\nVersion `source` is one of: manual, ai, reset, migration, import."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 58,\n      \"pdf_template_id\": 1,\n      \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n      \"source\": \"manual\",\n      \"source_label\": \"Manual\",\n      \"summary\": \"Updated footer address block.\",\n      \"ai_message_id\": null,\n      \"created_by\": 7,\n      \"created_by_name\": \"Jane Smith\",\n      \"created_at\": \"2026-07-20T14:32:10+00:00\"\n    },\n    {\n      \"id\": 57,\n      \"pdf_template_id\": 1,\n      \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n      \"source\": \"ai\",\n      \"source_label\": \"AI\",\n      \"summary\": \"Applied AI suggestion to restyle the header.\",\n      \"ai_message_id\": null,\n      \"created_by\": 7,\n      \"created_by_name\": \"Jane Smith\",\n      \"created_at\": \"2026-07-20T14:32:10+00:00\"\n    },\n    {\n      \"id\": 56,\n      \"pdf_template_id\": 1,\n      \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n      \"source\": \"reset\",\n      \"source_label\": \"Reset\",\n      \"summary\": \"Reset to default layout.\",\n      \"ai_message_id\": null,\n      \"created_by\": 7,\n      \"created_by_name\": \"Ops Admin\",\n      \"created_at\": \"2026-07-20T14:32:10+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/pdf-templates/1/versions?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/pdf-templates/1/versions?page=4\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/pdf-templates/1/versions?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/pdf-templates/1/versions\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 34\n}"}]},{"name":"Get PDF Template Version","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions/{versionId}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions",":versionId"],"variable":[{"key":"id","value":"","description":"The record ID."},{"key":"versionId","value":"","description":"The version ID."}]},"description":"Returns a single template version by ID, including its full content snapshot.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions/{versionId}","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions",":versionId"],"variable":[{"key":"id","value":"","description":"The record ID."},{"key":"versionId","value":"","description":"The version ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 58,\n    \"pdf_template_id\": 1,\n    \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n    \"source\": \"manual\",\n    \"source_label\": \"Manual\",\n    \"summary\": \"Updated footer address block.\",\n    \"ai_message_id\": null,\n    \"created_by\": 7,\n    \"created_by_name\": \"Jane Smith\",\n    \"created_at\": \"2026-07-20T14:32:10+00:00\"\n  }\n}"}]},{"name":"Restore PDF Template Version","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions/{versionId}/restore","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions",":versionId","restore"],"variable":[{"key":"id","value":"","description":"The record ID."},{"key":"versionId","value":"","description":"The version ID."}]},"description":"Restores a prior template version, replacing the template's current content with that version's snapshot and recording the previous content as a new version.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/versions/{versionId}/restore","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","versions",":versionId","restore"],"variable":[{"key":"id","value":"","description":"The record ID."},{"key":"versionId","value":"","description":"The version ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Purchase Order\",\n    \"content\": \"<html><body><h1>Purchase Order {{order_number}}</h1></body></html>\",\n    \"type\": \"purchase_order\",\n    \"description\": \"Default purchase order layout.\",\n    \"variables\": [\n      {\n        \"name\": \"Order Number\",\n        \"variable\": \"order_number\",\n        \"mockValue\": \"PO-2044\"\n      },\n      {\n        \"name\": \"Vendor Name\",\n        \"variable\": \"vendor_name\",\n        \"mockValue\": \"Acme Supply Co.\"\n      }\n    ],\n    \"variables_tree\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"PO-2044\"\n          }\n        }\n      }\n    },\n    \"store_id\": null,\n    \"store_name\": null,\n    \"updated_at\": \"2026-07-21T09:20:00+00:00\"\n  }\n}"}]},{"name":"List Store Overrides","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{type}/store-overrides","host":["{{baseUrl}}"],"path":["api","pdf-templates",":type","store-overrides"],"variable":[{"key":"type","value":"","description":"The type ID."}]},"description":"Returns every store-specific override for a given template type. A store override is a copy of the global template that a single store can customize independently.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access).\n\nPath params:\n- type: template type — one of purchase_order, sales_order, packing, quote, pick_list, vendor_credit, sales_credit."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-templates/{type}/store-overrides","host":["{{baseUrl}}"],"path":["api","pdf-templates",":type","store-overrides"],"variable":[{"key":"type","value":"","description":"The type ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"name\": \"Packing Slip\",\n      \"content\": \"<html><body><h1>Packing Slip {{order_number}}</h1>{{#items}}<p>{{sku}} x {{quantity}}</p>{{/items}}</body></html>\",\n      \"type\": \"packing\",\n      \"description\": \"Default packing slip layout.\",\n      \"variables\": [\n        {\n          \"name\": \"Order Number\",\n          \"variable\": \"order_number\",\n          \"mockValue\": \"SO-1001\"\n        },\n        {\n          \"name\": \"Warehouse\",\n          \"variable\": \"warehouse\",\n          \"mockValue\": \"Main Warehouse\"\n        },\n        {\n          \"name\": \"Items\",\n          \"variable\": \"items\",\n          \"mockValue\": \"\"\n        }\n      ],\n      \"variables_tree\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        },\n        \"items\": {\n          \"label\": \"Items\",\n          \"type\": \"section\",\n          \"mock\": \"\"\n        },\n        \"asset\": {\n          \"label\": \"Custom Assets\",\n          \"children\": {\n            \"company_logo\": {\n              \"label\": \"Company Logo\",\n              \"type\": \"html\",\n              \"mock\": \"\"\n            }\n          }\n        }\n      },\n      \"schema\": {\n        \"order\": {\n          \"label\": \"Order\",\n          \"children\": {\n            \"number\": {\n              \"label\": \"Order Number\",\n              \"type\": \"string\",\n              \"mock\": \"SO-1001\"\n            }\n          }\n        },\n        \"items\": {\n          \"label\": \"Items\",\n          \"type\": \"section\",\n          \"mock\": \"\"\n        },\n        \"asset\": {\n          \"label\": \"Custom Assets\",\n          \"children\": {\n            \"company_logo\": {\n              \"label\": \"Company Logo\",\n              \"type\": \"html\",\n              \"mock\": \"\"\n            }\n          }\n        }\n      },\n      \"store_id\": 3,\n      \"store_name\": \"Acme Store\",\n      \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Store Override","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/store-override","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","store-override"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Creates a store-specific override from a global template. The override starts with the global template's content and can then be edited independently for that store.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access).\n\nFields:\n- store_id (required): the store the override is created for.","body":{"mode":"raw","raw":"{\n  \"store_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/store-override","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","store-override"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Packing Slip\",\n    \"content\": \"<html><body><h1>Packing Slip {{order_number}}</h1>{{#items}}<p>{{sku}} x {{quantity}}</p>{{/items}}</body></html>\",\n    \"type\": \"packing\",\n    \"description\": \"Default packing slip layout.\",\n    \"variables\": [\n      {\n        \"name\": \"Order Number\",\n        \"variable\": \"order_number\",\n        \"mockValue\": \"SO-1001\"\n      },\n      {\n        \"name\": \"Warehouse\",\n        \"variable\": \"warehouse\",\n        \"mockValue\": \"Main Warehouse\"\n      },\n      {\n        \"name\": \"Items\",\n        \"variable\": \"items\",\n        \"mockValue\": \"\"\n      }\n    ],\n    \"variables_tree\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"SO-1001\"\n          }\n        }\n      },\n      \"items\": {\n        \"label\": \"Items\",\n        \"type\": \"section\",\n        \"mock\": \"\"\n      },\n      \"asset\": {\n        \"label\": \"Custom Assets\",\n        \"children\": {\n          \"company_logo\": {\n            \"label\": \"Company Logo\",\n            \"type\": \"html\",\n            \"mock\": \"\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"order\": {\n        \"label\": \"Order\",\n        \"children\": {\n          \"number\": {\n            \"label\": \"Order Number\",\n            \"type\": \"string\",\n            \"mock\": \"SO-1001\"\n          }\n        }\n      },\n      \"items\": {\n        \"label\": \"Items\",\n        \"type\": \"section\",\n        \"mock\": \"\"\n      },\n      \"asset\": {\n        \"label\": \"Custom Assets\",\n        \"children\": {\n          \"company_logo\": {\n            \"label\": \"Company Logo\",\n            \"type\": \"html\",\n            \"mock\": \"\"\n          }\n        }\n      }\n    },\n    \"store_id\": 3,\n    \"store_name\": \"Acme Store\",\n    \"updated_at\": \"2026-07-20T14:32:10+00:00\"\n  }\n}"}]},{"name":"Delete Store Override","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/store-override","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","store-override"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Deletes a store-specific override. That store reverts to the global template of the same type.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access).\n\nPath params:\n- id: the ID of the store override template to delete."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/pdf-templates/{id}/store-override","host":["{{baseUrl}}"],"path":["api","pdf-templates",":id","store-override"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Store override deleted successfully.\"\n  }\n}"}]},{"name":"List Template Assets","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-template-assets","host":["{{baseUrl}}"],"path":["api","pdf-template-assets"]},"description":"Returns every uploaded image asset available to templates. Reference an asset inside template content with its `token` (for example `{{{asset.company_logo}}}`), which renders as an inline image in the PDF.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (read access)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pdf-template-assets","host":["{{baseUrl}}"],"path":["api","pdf-template-assets"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 11,\n      \"slug\": \"company_logo\",\n      \"name\": \"Company Logo\",\n      \"mime_type\": \"image/png\",\n      \"size_bytes\": 20481,\n      \"width\": 320,\n      \"height\": 120,\n      \"url\": \"https://assets.sku.io/pdf-template-assets/company_logo.png\",\n      \"token\": \"{{{asset.company_logo}}}\",\n      \"created_at\": \"2026-07-19T11:05:00+00:00\"\n    },\n    {\n      \"id\": 12,\n      \"slug\": \"signature\",\n      \"name\": \"Signature\",\n      \"mime_type\": \"image/png\",\n      \"size_bytes\": 20481,\n      \"width\": 320,\n      \"height\": 120,\n      \"url\": \"https://assets.sku.io/pdf-template-assets/signature.png\",\n      \"token\": \"{{{asset.signature}}}\",\n      \"created_at\": \"2026-07-19T11:05:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Upload Template Asset","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-template-assets","host":["{{baseUrl}}"],"path":["api","pdf-template-assets"]},"description":"Uploads a new image asset for use in templates. Send the request as multipart/form-data.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access).\n\nFields:\n- image (required): the image file (JPG, PNG, GIF, or WEBP, max 5 MB).\n- name (optional): a display name; the reference slug is derived from it.\n\nThe response includes the generated `slug` and the `token` you place in template content.","body":{"mode":"formdata","formdata":[{"key":"image","type":"file","src":[]},{"key":"name","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pdf-template-assets","host":["{{baseUrl}}"],"path":["api","pdf-template-assets"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 13,\n    \"slug\": \"company_logo\",\n    \"name\": \"Company Logo\",\n    \"mime_type\": \"image/png\",\n    \"size_bytes\": 20481,\n    \"width\": 320,\n    \"height\": 120,\n    \"url\": \"https://assets.sku.io/pdf-template-assets/company_logo.png\",\n    \"token\": \"{{{asset.company_logo}}}\",\n    \"created_at\": \"2026-07-19T11:05:00+00:00\"\n  }\n}"}]},{"name":"Delete Template Asset","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/pdf-template-assets/{id}","host":["{{baseUrl}}"],"path":["api","pdf-template-assets",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Deletes an uploaded image asset. Templates that reference the asset's token will no longer render its image.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Bearer Personal Access Token with the `settings` scope (write access).\n\nPath params:\n- id: the ID of the asset to delete."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/pdf-template-assets/{id}","host":["{{baseUrl}}"],"path":["api","pdf-template-assets",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Asset deleted.\"\n  }\n}"}]}]},{"name":"Card on File","item":[{"name":"List Cards On File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."}]},"description":"List a customer's saved (tokenized) cards on file. Returns only safe display metadata — brand, last four, expiry, cardholder name, the default flag, and the consent timestamp. The processor-vaulted reusable token is NEVER serialized and does not appear in the response.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\n\nReturns 200 with `{ data: [ ... ] }` — an array of card-on-file records (no token field)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"processor\": \"square\",\n      \"brand\": \"Visa\",\n      \"last_four\": \"4242\",\n      \"exp_month\": 12,\n      \"exp_year\": 2028,\n      \"cardholder_name\": \"Alex Rivera\",\n      \"is_default\": true,\n      \"label\": \"Visa ••••4242\",\n      \"consent_given_at\": \"2026-07-06T14:30:00+00:00\",\n      \"created_at\": \"2026-07-06T14:30:00+00:00\"\n    },\n    {\n      \"id\": 43,\n      \"processor\": \"stripe\",\n      \"brand\": \"Mastercard\",\n      \"last_four\": \"4444\",\n      \"exp_month\": 3,\n      \"exp_year\": 2027,\n      \"cardholder_name\": \"Alex Rivera\",\n      \"is_default\": false,\n      \"label\": \"Mastercard ••••4444\",\n      \"consent_given_at\": \"2026-06-01T09:15:00+00:00\",\n      \"created_at\": \"2026-06-01T09:15:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Save Card On File","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."}]},"description":"Save a tokenized card on file for a customer. The client tokenizes the card with the processor SDK (Square / Stripe) and sends ONLY the resulting reusable token — a raw card number (PAN) or CVV is never accepted. Requires explicit, affirmative customer consent.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nRequest body fields:\n- `processor` (string, required) — the tokenizing processor. One of: `square`, `stripe`.\n- `processor_token` (string, required, max 255) — the processor's reusable card token from client-side SDK vaulting (e.g. a Square card nonce or Stripe PaymentMethod id). NEVER a raw PAN or CVV.\n- `processor_customer_id` (string, nullable, max 255) — the processor's customer/vault id the token is attached to.\n- `consent_given` (required, must be accepted — `true`, `1`, `\"yes\"`, or `\"on\"`) — explicit customer consent to store the card. Error when missing/false: \"Explicit customer consent is required to store a card on file.\"\n- `brand` (string, nullable, max 50) — safe display card brand (e.g. Visa, Mastercard).\n- `last_four` (nullable, exactly 4 digits) — safe display last four of the card.\n- `exp_month` (integer, nullable, 1–12) — card expiry month.\n- `exp_year` (integer, nullable, 2020–2100) — card expiry year.\n- `cardholder_name` (string, nullable, max 255) — name on the card.\n- `is_default` (boolean, nullable) — make this the customer's default card. Defaults to false.\n\nReturns 201 with `{ data: <card on file>, message: \"Card saved on file.\" }` (no token field).","body":{"mode":"raw","raw":"{\n  \"processor\": \"square\",\n  \"processor_token\": \"cnon:card-nonce-vaulted\",\n  \"processor_customer_id\": \"sq_cust_9f3a2b\",\n  \"consent_given\": true,\n  \"brand\": \"Visa\",\n  \"last_four\": \"4242\",\n  \"exp_month\": 12,\n  \"exp_year\": 2028,\n  \"cardholder_name\": \"Alex Rivera\",\n  \"is_default\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"processor\": \"square\",\n    \"brand\": \"Visa\",\n    \"last_four\": \"4242\",\n    \"exp_month\": 12,\n    \"exp_year\": 2028,\n    \"cardholder_name\": \"Alex Rivera\",\n    \"is_default\": true,\n    \"label\": \"Visa ••••4242\",\n    \"consent_given_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"message\": \"Card saved on file.\"\n}"}]},{"name":"Set Default Card","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods/{paymentMethod}/default","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods",":paymentMethod","default"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."},{"key":"paymentMethod","value":"{{paymentMethod}}","description":"The saved card (payment method) id."}]},"description":"Make a saved card the customer's default. Clears the default flag on the customer's other cards and sets it on this one.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nNo request body. The card must belong to the customer in the path, otherwise a 422 is returned.\n\nReturns 200 with `{ data: <card on file>, message: \"Default card updated.\" }` (no token field)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods/{paymentMethod}/default","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods",":paymentMethod","default"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."},{"key":"paymentMethod","value":"{{paymentMethod}}","description":"The saved card (payment method) id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"processor\": \"square\",\n    \"brand\": \"Visa\",\n    \"last_four\": \"4242\",\n    \"exp_month\": 12,\n    \"exp_year\": 2028,\n    \"cardholder_name\": \"Alex Rivera\",\n    \"is_default\": true,\n    \"label\": \"Visa ••••4242\",\n    \"consent_given_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"message\": \"Default card updated.\"\n}"}]},{"name":"Remove Card On File","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods/{paymentMethod}","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods",":paymentMethod"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."},{"key":"paymentMethod","value":"{{paymentMethod}}","description":"The saved card (payment method) id."}]},"description":"Remove a saved card from the customer's file. Deletes the stored token reference and its display metadata.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nNo request body. The card must belong to the customer in the path, otherwise a 422 is returned.\n\nReturns 200 with `{ message: \"Card removed.\" }`."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/customers/{customer}/payment-methods/{paymentMethod}","host":["{{baseUrl}}"],"path":["api","customers",":customer","payment-methods",":paymentMethod"],"variable":[{"key":"customer","value":"{{customer}}","description":"The customer id."},{"key":"paymentMethod","value":"{{paymentMethod}}","description":"The saved card (payment method) id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Card removed.\"\n}"}]}]},{"name":"Channel Partners","item":[{"name":"Delete All Inbound Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events/delete-all","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events","delete-all"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete ALL inbound events for a channel partner instance. Use with caution.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events/delete-all","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events","delete-all"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"97 event(s) deleted.\"\n}"}]},{"name":"List Channel Partners","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners","host":["{{baseUrl}}"],"path":["api","channel-partners"]},"description":"Returns all API Sales Channel integration instances (channel partners).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (Sanctum user session)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners","host":["{{baseUrl}}"],"path":["api","channel-partners"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My Storefront API\",\n      \"integration_id\": 5,\n      \"connection_settings\": {},\n      \"integration_settings\": {},\n      \"sync_status\": null,\n      \"is_automatic_sync_enabled\": false,\n      \"sales_channel\": {\n        \"id\": 3,\n        \"name\": \"My Storefront\",\n        \"store_id\": 1\n      },\n      \"orders_count\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Channel Partner","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel-partners","host":["{{baseUrl}}"],"path":["api","channel-partners"]},"description":"Create a new API Sales Channel integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (required, string, max:255)\n- `store_id` (optional, integer)","body":{"mode":"raw","raw":"{\n  \"name\": \"B2B Portal Integration\",\n  \"store_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-partners","host":["{{baseUrl}}"],"path":["api","channel-partners"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"B2B Portal Integration\"\n  }\n}"}]},{"name":"Get Channel Partner","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single channel partner integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Storefront API\",\n    \"integration_id\": 5,\n    \"connection_settings\": {},\n    \"integration_settings\": {},\n    \"sync_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"sales_channel\": {\n      \"id\": 3,\n      \"name\": \"My Storefront\",\n      \"store_id\": 1\n    },\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Channel Partner","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a channel partner integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields (all optional):\n- name: Updated name (max 255 chars)\n- store_id: Updated store ID (nullable)","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Storefront API\",\n  \"store_id\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Storefront API\",\n    \"integration_id\": 5\n  }\n}"}]},{"name":"Delete Channel Partner","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a channel partner integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 204 No Content."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Channel Partner Dashboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/dashboard","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","dashboard"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns dashboard stats and recent orders for a channel partner.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/dashboard","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","dashboard"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"instance\": {\n      \"id\": 1,\n      \"name\": \"My Storefront API\"\n    },\n    \"stats\": {\n      \"total_orders\": 142,\n      \"pending_orders\": 12,\n      \"fulfilled_orders\": 130,\n      \"last_order_at\": \"2024-06-01T09:00:00.000000Z\"\n    },\n    \"recent_orders\": [\n      {\n        \"id\": 500,\n        \"sales_order_number\": \"SO-2024-500\",\n        \"order_status\": \"open\",\n        \"fulfillment_status\": \"unfulfilled\",\n        \"order_date\": \"2024-06-01T08:00:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"List Channel Partner Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns paginated sales orders for a channel partner's sales channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 500,\n      \"sales_order_number\": \"SO-2024-500\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"customer_name\": \"John Doe\",\n      \"order_date\": \"2024-06-01T08:00:00.000000Z\",\n      \"created_at\": \"2024-06-01T08:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 142\n}"}]},{"name":"List API Tokens","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Lists all active API tokens for a channel partner.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Production Token\",\n      \"abilities\": [\n        \"channel:read\",\n        \"channel:write\"\n      ],\n      \"created_at\": \"2024-06-01T12:00:00.000000Z\",\n      \"last_used_at\": \"2024-06-01T14:30:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Generate API Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Generates a new API token for a channel partner. The plain text token is only shown once.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Token name/label (max 255 chars)","body":{"mode":"raw","raw":"{\n  \"name\": \"Production Token\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"token\": \"3|abc123def456ghi789jkl012mno345pqr678|channel:read|channel:write\",\n    \"name\": \"Production Token\"\n  },\n  \"message\": \"Token generated. Please copy it now — it won't be shown again.\"\n}"}]},{"name":"Revoke API Token","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens/{id2}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Revokes a specific API token for a channel partner.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/tokens/{id2}","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","tokens",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Token revoked successfully.\"\n}"}]},{"name":"Create Channel API Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel/tokens","host":["{{baseUrl}}"],"path":["api","channel","tokens"]},"description":"Creates a new Sanctum token with channel:read and channel:write abilities for a sales channel integration instance. If a token with these abilities already exists, it will be replaced.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Token name (max 255 chars)\n- integration_instance_id (required): ID of the integration instance","body":{"mode":"raw","raw":"{\n  \"name\": \"channel-token-production\",\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel/tokens","host":["{{baseUrl}}"],"path":["api","channel","tokens"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"token\": \"4|channeltoken123abc456def789ghi012jkl\",\n    \"integration_instance_id\": 1,\n    \"name\": \"channel-token-production\",\n    \"abilities\": [\n      \"channel:read\",\n      \"channel:write\"\n    ],\n    \"created_at\": \"2024-06-01T12:00:00.000000Z\",\n    \"replaced_existing\": false\n  }\n}"}]}]},{"name":"Sales Channel Listing Profiles","item":[{"name":"List Listing Profiles","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-channel-listing-profiles","host":["{{baseUrl}}"],"path":["api","v2","sales-channel-listing-profiles"]},"description":"Cross-channel paginated list of listing profiles, with the owning sales channel and \"used by\" template/draft counts. Requires the listing-publishing feature to be enabled (403 otherwise).\n\nAuthentication: Requires Bearer token.\n\nAvailable filters:\n- filter[sales_channel_id]: exact match on channel\n- filter[is_default]: exact match on the default flag (1/0)\n- filter[name]: partial match on name\n- filter[search]: search by name or exact id\n- filter[created_at] / filter[updated_at]: date filters\n\nAllowed sorts: id, name, sales_channel_id, is_default, created_at, updated_at (default: name).\n\nPagination: page (default 1), per_page (default 20, max 100)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-channel-listing-profiles","host":["{{baseUrl}}"],"path":["api","v2","sales-channel-listing-profiles"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"sales_channel_id\": 5,\n      \"name\": \"Standard\",\n      \"is_default\": true,\n      \"settings\": {\n        \"condition\": \"NEW\",\n        \"handling_time\": \"1\"\n      },\n      \"created_at\": \"2026-07-18T09:00:00+00:00\",\n      \"updated_at\": \"2026-07-20T14:30:00+00:00\",\n      \"templates_count\": 2,\n      \"drafts_count\": 5,\n      \"sales_channel\": {\n        \"id\": 5,\n        \"name\": \"eBay US\",\n        \"integration_id\": 3,\n        \"integration_name\": \"Ebay\",\n        \"integration_image_url\": \"https://cdn.sku.io/integrations/ebay.png\",\n        \"integration_instance_id\": 9\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 20,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Bulk Delete Listing Profiles","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/sales-channel-listing-profiles/bulk-destroy","host":["{{baseUrl}}"],"path":["api","v2","sales-channel-listing-profiles","bulk-destroy"]},"description":"Bulk delete listing profiles. Provide either an explicit `ids` array, or set `apply_to_all` to true with a `filters` object to delete every profile matching the current filter set. Requires the listing-publishing feature to be enabled (403 otherwise).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of):\n- ids: array of profile IDs to delete (required unless apply_to_all is true)\n- apply_to_all: when true, delete all profiles matching filters\n- filters: filter object (e.g. { \"sales_channel_id\": 5 }) applied when apply_to_all is true","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-channel-listing-profiles/bulk-destroy","host":["{{baseUrl}}"],"path":["api","v2","sales-channel-listing-profiles","bulk-destroy"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": 3\n  },\n  \"message\": \"Deleted 3 profiles.\"\n}"}]}]},{"name":"Sub Sales Channels","item":[{"name":"List Sub Sales Channels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels"]},"description":"Returns a paginated list of sub sales channels. Each row carries its classified `source_type` (online, point_of_sale, marketplace, draft, other), a human `source_type_label`, an `is_point_of_sale` convenience flag, and `source_type_locked` (true once an operator has manually reclassified it). Authenticate with a Personal Access Token.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAllowed sorts: id, name, created_at, updated_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"sales_channel_id\": 3,\n      \"name\": \"POS\",\n      \"external_identifier\": \"pos\",\n      \"source_type\": \"point_of_sale\",\n      \"source_type_label\": \"Point of Sale\",\n      \"source_type_locked\": false,\n      \"is_point_of_sale\": true,\n      \"sales_nominal_code_id\": null,\n      \"cogs_nominal_code_id\": null,\n      \"shipping_revenue_nominal_code_id\": null,\n      \"shipping_refund_nominal_code_id\": null,\n      \"sales_returns_allowances_nominal_code_id\": null,\n      \"created_at\": \"2026-06-17T09:15:00.000000Z\",\n      \"updated_at\": \"2026-06-17T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"path\": \"{{protocol}}{{domain}}/api/sub-sales-channels\"\n}"}]},{"name":"Create Sub Sales Channel","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels"]},"description":"Creates a new sub sales channel.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required.\n\nFields:\n- sales_channel_id (required): ID of the parent sales channel\n- name (required): Name of the sub sales channel (max 255 chars)\n- sales_nominal_code_id (optional): Nominal code ID for sales revenue\n- cogs_nominal_code_id (optional): Nominal code ID for cost of goods sold","body":{"mode":"raw","raw":"{\n  \"sales_channel_id\": 5,\n  \"name\": \"Amazon US\",\n  \"sales_nominal_code_id\": 10,\n  \"cogs_nominal_code_id\": 11,\n  \"shipping_revenue_nominal_code_id\": 12,\n  \"shipping_refund_nominal_code_id\": 13,\n  \"sales_returns_allowances_nominal_code_id\": 14\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sub-sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sub Sales Channel created successfully.\",\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Amazon US\"\n  }\n}"}]},{"name":"Reclassify Source Type","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{subSalesChannel}/source-type","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":subSalesChannel","source-type"],"variable":[{"key":"subSalesChannel","value":"12","description":"Sub sales channel ID"}]},"description":"Manually reclassify a sub sales channel's source type (e.g. mark an in-store source as Point of Sale). Sets `source_type_locked = true` so future integration syncs never revert the operator's choice.\n\nRequest body:\n- `source_type` (required) — one of: online, point_of_sale, marketplace, draft, other.\n\nReturns the updated sub sales channel.","body":{"mode":"raw","raw":"{\n  \"source_type\": \"point_of_sale\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{subSalesChannel}/source-type","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":subSalesChannel","source-type"],"variable":[{"key":"subSalesChannel","value":"12","description":"Sub sales channel ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"sales_channel_id\": 3,\n    \"name\": \"POS\",\n    \"external_identifier\": \"pos\",\n    \"source_type\": \"point_of_sale\",\n    \"source_type_label\": \"Point of Sale\",\n    \"source_type_locked\": true,\n    \"is_point_of_sale\": true,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"created_at\": \"2026-06-17T09:15:00.000000Z\",\n    \"updated_at\": \"2026-06-17T09:15:00.000000Z\"\n  },\n  \"message\": \"Sub Sales Channel POS updated successfully.\"\n}"}]},{"name":"Get Sub Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single sub sales channel by ID with all related data loaded.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Amazon US\",\n    \"sales_channel_id\": 5\n  }\n}"}]},{"name":"Update Sub Sales Channel","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing sub sales channel. All fields are optional (partial update supported).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required.","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon US Updated\",\n  \"sales_nominal_code_id\": 10,\n  \"cogs_nominal_code_id\": 11\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sub Sales Channel 'Amazon US Updated' updated successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Amazon US Updated\"\n  }\n}"}]},{"name":"Delete Sub Sales Channel","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a sub sales channel.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sub Sales Channel 'Amazon US' deleted successfully.\"\n}"}]},{"name":"Get Sub Sales Channels by Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/by-sales-channel/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","by-sales-channel",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns all sub sales channels that belong to a specific sales channel.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/by-sales-channel/{id}","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","by-sales-channel",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Amazon US\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Amazon CA\"\n    }\n  ]\n}"}]},{"name":"List Sub Sales Channel Options (id/name)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/list","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","list"]},"description":"Returns a minimal list of sub sales channels (id and name only) for use in dropdown/combo box controls. Ordered by name.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/list","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Amazon CA\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Amazon US\"\n    }\n  ]\n}"}]},{"name":"Lookup Sales Channels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/lookup/sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","lookup","sales-channels"]},"description":"Returns all sales channels for use in dropdowns when creating/editing sub sales channels.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/lookup/sales-channels","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","lookup","sales-channels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Shopify Main Store\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Amazon Seller Central\"\n    }\n  ]\n}"}]},{"name":"Lookup Nominal Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sub-sales-channels/lookup/nominal-codes","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","lookup","nominal-codes"]},"description":"Returns all nominal codes for use in dropdowns when assigning accounting codes to sub sales channels. Ordered by code.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPower user access required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sub-sales-channels/lookup/nominal-codes","host":["{{baseUrl}}"],"path":["api","sub-sales-channels","lookup","nominal-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"name\": \"Sales Revenue\",\n      \"code\": \"4000\"\n    },\n    {\n      \"id\": 11,\n      \"name\": \"Cost of Goods Sold\",\n      \"code\": \"5000\"\n    }\n  ]\n}"}]}]},{"name":"Custom Report Builder","item":[{"name":"Get Metadata (Domains, Entities, Columns)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/metadata","host":["{{baseUrl}}"],"path":["api","v2","report-builder","metadata"]},"description":"Returns all available domains, entities, and columns that can be used to build a report definition. Use this to populate the report builder UI with selectable fields.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response contains the full schema of reportable data: which domains are available (e.g., inventory, sales), which entities exist within each domain, and which columns (dimensions and measures) can be selected for each entity."}},{"name":"Run Ad-Hoc Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/run","host":["{{baseUrl}}"],"path":["api","v2","report-builder","run"]},"description":"Run a report definition without saving it. Use this for previewing results before saving a custom report.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe definition object must include:\n- `base_entity` (string, required): The primary entity to query\n- `columns` (array, required, min 1): Columns to include. Each column needs `id`, `kind` (dimension|measure), `entity`, and `field`. Optional: `label`, `granularity`, `aggregation`\n- `filters` (object, optional): Filter tree with `conjunction` (and|or) and `children` array of conditions/groups\n- `sorts` (array, optional): Sort rules with `column_id` and `direction` (asc|desc)\n- `limit` (integer, optional): Max rows (1-5000)\n\nThe top-level `limit` parameter also caps the result set (1-5000).","body":{"mode":"raw","raw":"{\n  \"definition\": {\n    \"base_entity\": \"sales_orders\",\n    \"columns\": [\n      {\n        \"id\": \"sales_orders.order_number\",\n        \"kind\": \"dimension\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"order_number\"\n      },\n      {\n        \"id\": \"sales_orders.total\",\n        \"kind\": \"measure\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"total\",\n        \"aggregation\": \"sum\"\n      }\n    ],\n    \"filters\": {\n      \"conjunction\": \"and\",\n      \"children\": [\n        {\n          \"type\": \"condition\",\n          \"condition\": {\n            \"column\": \"sales_orders.status\",\n            \"operator\": \"=\",\n            \"value\": \"shipped\"\n          }\n        }\n      ]\n    },\n    \"sorts\": [\n      {\n        \"column_id\": \"sales_orders.total\",\n        \"direction\": \"desc\"\n      }\n    ],\n    \"limit\": 100\n  },\n  \"limit\": 100\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Custom Reports","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","v2","custom-reports"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true}]},"description":"List all custom reports for the authenticated user. Supports pagination, search by name, and filtering by domain.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse uses standard Laravel pagination with `data`, `current_page`, `last_page`, `per_page`, `total`, etc. Each item in `data` is a custom report object."}},{"name":"Create Custom Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports","host":["{{baseUrl}}"],"path":["api","v2","custom-reports"]},"description":"Create a new saved custom report.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- `name` (string, max 255): Report name\n- `domain` (string, max 50): Domain category (e.g., sales, inventory)\n- `base_entity` (string, max 100): Primary entity for the report\n- `definition` (object): Full report definition containing columns, filters, sorts, etc.\n\nOptional fields:\n- `description` (string, max 1000): Report description\n- `visibility` (string): \"private\" (default) or \"shared\"\n- `definition.version` (integer): Schema version number\n- `definition.domain` (string): Domain within the definition\n- `definition.filters` (object): Filter tree with conjunction and children\n- `definition.sorts` (array): Sort rules\n- `definition.limit` (integer, 1-5000): Default row limit\n\nColumn requirements:\n- `id` (string, required): Unique column identifier (e.g., \"entity.field\")\n- `kind` (string, required): \"dimension\" or \"measure\"\n- `entity` (string, required): Entity the column belongs to\n- `field` (string, required): Field name on the entity\n- `label` (string, optional): Display label\n- `granularity` (string, optional): Time granularity for date dimensions (e.g., day, month, year)\n- `aggregation` (string, optional): Aggregation function for measures (e.g., sum, count, avg)\n\nReturns 201 with the created custom report object.","body":{"mode":"raw","raw":"{\n  \"name\": \"Monthly Sales by Product\",\n  \"description\": \"Aggregated sales totals grouped by product and month\",\n  \"domain\": \"sales\",\n  \"base_entity\": \"sales_orders\",\n  \"definition\": {\n    \"base_entity\": \"sales_orders\",\n    \"domain\": \"sales\",\n    \"version\": 1,\n    \"columns\": [\n      {\n        \"id\": \"sales_orders.order_date\",\n        \"kind\": \"dimension\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"order_date\",\n        \"label\": \"Order Month\",\n        \"granularity\": \"month\"\n      },\n      {\n        \"id\": \"products.name\",\n        \"kind\": \"dimension\",\n        \"entity\": \"products\",\n        \"field\": \"name\",\n        \"label\": \"Product Name\"\n      },\n      {\n        \"id\": \"sales_orders.total\",\n        \"kind\": \"measure\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"total\",\n        \"label\": \"Total Sales\",\n        \"aggregation\": \"sum\"\n      }\n    ],\n    \"filters\": {\n      \"conjunction\": \"and\",\n      \"children\": [\n        {\n          \"type\": \"condition\",\n          \"condition\": {\n            \"column\": \"sales_orders.status\",\n            \"operator\": \"!=\",\n            \"value\": \"cancelled\"\n          }\n        }\n      ]\n    },\n    \"sorts\": [\n      {\n        \"column_id\": \"sales_orders.order_date\",\n        \"direction\": \"desc\"\n      }\n    ],\n    \"limit\": 500\n  },\n  \"visibility\": \"private\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Custom Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a single custom report by ID. The report must belong to or be shared with the authenticated user.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the full custom report object including the user name (eager-loaded). Returns 404 if the report is not found or not accessible."}},{"name":"Update Custom Report","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update an existing custom report. Only the report owner can update it (returns 403 otherwise).\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAll fields are optional (uses `sometimes` validation). When `definition` is provided, `definition.base_entity` and `definition.columns` become required.\n\nReturns 404 if the report is not found or not accessible. Returns 403 if the authenticated user is not the owner.","body":{"mode":"raw","raw":"{\n  \"name\": \"Monthly Sales by Product (Updated)\",\n  \"description\": \"Updated description for monthly sales report\",\n  \"definition\": {\n    \"base_entity\": \"sales_orders\",\n    \"domain\": \"sales\",\n    \"version\": 1,\n    \"columns\": [\n      {\n        \"id\": \"sales_orders.order_date\",\n        \"kind\": \"dimension\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"order_date\",\n        \"label\": \"Order Month\",\n        \"granularity\": \"month\"\n      },\n      {\n        \"id\": \"products.sku\",\n        \"kind\": \"dimension\",\n        \"entity\": \"products\",\n        \"field\": \"sku\",\n        \"label\": \"SKU\"\n      },\n      {\n        \"id\": \"products.name\",\n        \"kind\": \"dimension\",\n        \"entity\": \"products\",\n        \"field\": \"name\",\n        \"label\": \"Product Name\"\n      },\n      {\n        \"id\": \"sales_orders.total\",\n        \"kind\": \"measure\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"total\",\n        \"label\": \"Total Sales\",\n        \"aggregation\": \"sum\"\n      },\n      {\n        \"id\": \"sales_orders.id\",\n        \"kind\": \"measure\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"id\",\n        \"label\": \"Order Count\",\n        \"aggregation\": \"count\"\n      }\n    ],\n    \"filters\": {\n      \"conjunction\": \"and\",\n      \"children\": [\n        {\n          \"type\": \"condition\",\n          \"condition\": {\n            \"column\": \"sales_orders.status\",\n            \"operator\": \"!=\",\n            \"value\": \"cancelled\"\n          }\n        }\n      ]\n    },\n    \"sorts\": [\n      {\n        \"column_id\": \"sales_orders.order_date\",\n        \"direction\": \"desc\"\n      }\n    ],\n    \"limit\": 1000\n  },\n  \"visibility\": \"shared\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Custom Report","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete a custom report. Only the report owner can delete it (returns 403 otherwise). Also deletes associated shares.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 204 No Content on success. Returns 404 if not found. Returns 403 if not the owner."}},{"name":"Run Saved Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/run","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","run"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Execute a saved custom report by ID. The report must belong to or be shared with the authenticated user.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOptional body parameter:\n- `limit` (integer, default 500): Maximum number of rows to return\n\nReturns 404 if the report is not found. Returns 422 if the report definition is invalid (e.g., references unknown entities or columns).","body":{"mode":"raw","raw":"{\n  \"limit\": 500\n}","options":{"raw":{"language":"json"}}}}},{"name":"Drill Down Into Aggregated Row","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/drill-down","host":["{{baseUrl}}"],"path":["api","v2","report-builder","drill-down"]},"description":"Execute a drill-down query for a row in an aggregated report. Pass the same `definition` used to produce the parent row along with a `drill_values` map of {dimension_alias: value} pairs to isolate the underlying detail records.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns rows from the base entity that match all supplied drill values, respecting the definition's filters and tenant isolation. Use for powering drill-down drawers in the UI.","body":{"mode":"raw","raw":"{\n  \"definition\": {\n    \"base_entity\": \"sales_orders\",\n    \"columns\": [\n      {\n        \"id\": \"sales_orders.order_status\",\n        \"kind\": \"dimension\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"order_status\"\n      },\n      {\n        \"id\": \"sales_orders.id\",\n        \"kind\": \"measure\",\n        \"entity\": \"sales_orders\",\n        \"field\": \"id\",\n        \"aggregation\": \"count\"\n      }\n    ]\n  },\n  \"drill_values\": {\n    \"sales_orders__order_status\": \"shipped\"\n  },\n  \"limit\": 100\n}","options":{"raw":{"language":"json"}}}}},{"name":"Validate Formula Expression","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/validate-formula","host":["{{baseUrl}}"],"path":["api","v2","report-builder","validate-formula"]},"description":"Validate a user-entered formula expression before saving. The formula is parsed via Symfony ExpressionLanguage against a whitelist of functions (IF, COALESCE, ROUND, NULLIF, etc.) and field references (`{field_name}`).\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `formula` (string, required, max 2000): The expression to validate\n- `base_entity` (string, optional): Entity context for field reference resolution\n- `available_columns` (array, optional): Available columns in the current report for reference validation\n\nReturns `{ valid: true }` or `{ valid: false, error: '...' }`. Rejects SQL-injection attempts and unknown field references.","body":{"mode":"raw","raw":"{\n  \"formula\": \"{revenue} / NULLIF({units_sold}, 0)\",\n  \"base_entity\": \"sales_order_lines\",\n  \"available_columns\": [\n    {\n      \"id\": \"sales_order_lines.revenue\",\n      \"kind\": \"measure\"\n    },\n    {\n      \"id\": \"sales_order_lines.units_sold\",\n      \"kind\": \"measure\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Distinct Field Values (Autocomplete)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/field-values/sales_orders/order_status?search=&limit=50","host":["{{baseUrl}}"],"path":["api","v2","report-builder","field-values","sales_orders","order_status"],"query":[{"key":"search","value":"","description":"Optional search term for autocomplete","disabled":true},{"key":"limit","value":"50","description":"Max distinct values to return (default 50)","disabled":true}]},"description":"Return distinct values for a given entity/field. Used to populate autocomplete dropdowns in the filter builder UI (e.g., distinct `order_status` values).\n\nRespects tenant isolation. Supports an optional `search` query param for LIKE matching and a `limit` param to cap results."}},{"name":"Search Share Recipients","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/report-builder/users?search=alice","host":["{{baseUrl}}"],"path":["api","v2","report-builder","users"],"query":[{"key":"search","value":"alice","description":"Search by name or email","disabled":true}]},"description":"Search for users that can be added as share recipients on a custom report. Limited to users in the same tenant. Returns up to 20 matches. Used to power the share dialog's user picker.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Duplicate Custom Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/duplicate","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","duplicate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Create a personal copy of a report. The duplicate is always owned by the authenticated caller with visibility='private' regardless of the original's visibility. Works on shared reports too (lets a user fork a shared report into their own workspace).\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `name` (string, required, max 255): Name for the new copy\n\nReturns 201 with the new custom report object.","body":{"mode":"raw","raw":"{\n  \"name\": \"My Copy of Monthly Sales\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Toggle Favorite","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/toggle-favorite","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","toggle-favorite"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Toggle the `is_favorited` flag on a report. Only the owner can toggle favorites on their own report (returns 403 otherwise). The Favorites tab on the Reports Hub filters by this flag.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Export Custom Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/export","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","export"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Export a saved custom report. The response is a streamed/binary download in the requested format.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `format` (string, required): One of `csv`, `xlsx`, `pdf`\n\nReturns 200 with a file download. Returns 404 if the report is not owned by or shared with the caller.","body":{"mode":"raw","raw":"{\n  \"format\": \"xlsx\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Shares","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/shares","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","shares"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"List all explicit share grants for a report. Each entry includes the recipient user (eager-loaded) and the permission (`view` or `edit`). Returns 403 if the caller is not the report owner.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Add Share","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/shares","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","shares"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Add a user as an explicit share recipient. Upserts (updateOrCreate) so calling twice with a different permission updates the existing record.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `user_id` (integer, required): Recipient user ID (cannot be self)\n- `permission` (string, required): `view` or `edit`\n\nReturns 403 if the caller is not the report owner. Returns 422 if sharing with self or invalid permission.","body":{"mode":"raw","raw":"{\n  \"user_id\": 2,\n  \"permission\": \"view\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Remove Share","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/shares/{id2}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","shares",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Revoke an explicit share grant for a specific user. Returns 204 on success. Returns 403 if the caller is not the report owner.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List Schedules","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/schedules","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","schedules"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"List all schedules for a report. Each entry includes the creating user (eager-loaded), frequency, time_of_day (H:i:s), timezone, export_format, recipients, is_active, last_sent_at, and next_run_at. Accessible to anyone who can read the report.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create Schedule","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/schedules","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","schedules"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Create a new schedule.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- `frequency` (string): `daily`, `weekly`, or `monthly`\n- `time_of_day` (string): `H:i` or `H:i:s`\n- `recipients` (array of valid emails, min 1)\n\nOptional fields:\n- `day_of_week` (0-6) when frequency is `weekly`\n- `day_of_month` (1-31) when frequency is `monthly`\n- `timezone` (string, default `UTC`)\n- `export_format` (`csv`, `xlsx`, `pdf`, default `csv`)\n- `is_active` (boolean, default true)\n\nReturns 201 with the schedule resource. Returns 403 if the caller is not the report owner.","body":{"mode":"raw","raw":"{\n  \"frequency\": \"weekly\",\n  \"day_of_week\": 1,\n  \"time_of_day\": \"09:00\",\n  \"timezone\": \"America/New_York\",\n  \"export_format\": \"xlsx\",\n  \"recipients\": [\n    \"alice@example.com\",\n    \"bob@example.com\"\n  ],\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Schedule","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/schedules/{id2}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","schedules",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Update an existing schedule. All fields are optional (`sometimes` validation). `time_of_day` accepts both `H:i` and `H:i:s`; the server round-trips the value as `H:i:s` on reads, so re-submitting an unchanged time_of_day value from a prior GET works without 422 errors.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 404 if the schedule does not belong to the URL's report. Returns 403 if the caller is not the report owner.","body":{"mode":"raw","raw":"{\n  \"time_of_day\": \"10:30:00\",\n  \"is_active\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Schedule","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/custom-reports/{id}/schedules/{id2}","host":["{{baseUrl}}"],"path":["api","v2","custom-reports",":id","schedules",":id2"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Delete a schedule. Returns 204 on success. Returns 404 if the schedule does not belong to the URL's report. Returns 403 if the caller is not the report owner.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}}]},{"name":"Gift Cards","item":[{"name":"List Gift Cards","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/gift-cards","host":["{{baseUrl}}"],"path":["api","gift-cards"]},"description":"Paginated list of gift cards with their computed balance (N+1-safe). Filterable by status/customer/digital and searchable by code or recipient. Requires pos.operate.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/gift-cards","host":["{{baseUrl}}"],"path":["api","gift-cards"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 91,\n      \"code\": \"GC-4821-KDical-0097\",\n      \"status\": \"active\",\n      \"status_label\": \"Active\",\n      \"balance\": 42.5,\n      \"currency_id\": 1,\n      \"customer_id\": 88,\n      \"is_digital\": true,\n      \"recipient_name\": \"Ada Lovelace\",\n      \"recipient_email\": \"ada@example.com\",\n      \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n      \"activated_at\": \"2026-07-06T14:30:00+00:00\",\n      \"created_at\": \"2026-07-06T14:30:00+00:00\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1,\n  \"last_page\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Issue Gift Card","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/gift-cards","host":["{{baseUrl}}"],"path":["api","gift-cards"]},"description":"Issue (create + fund) a new gift card. The initial `amount` is written as an activation ledger entry and becomes the card's opening balance.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.manage`.\n\nRequest body fields:\n- `amount` (numeric, required, > 0) — the amount to fund the card with. Error message when not > 0: \"The gift card amount must be greater than zero.\"\n- `code` (string, nullable, max 255, unique in `gift_cards.code`) — explicit card code; auto-generated (unique) when omitted. Error message on collision: \"That gift card code is already in use.\"\n- `security_code` (string, nullable, max 255) — optional PIN / security code.\n- `is_digital` (boolean, nullable) — whether the card is digital (emailed) vs a physical card. Defaults to false.\n- `customer_id` (integer, nullable, must exist in `customers`) — owning customer.\n- `recipient_name` (string, nullable, max 255) — gift recipient's name.\n- `recipient_email` (email, nullable, max 255) — gift recipient's email.\n- `expires_at` (date, nullable) — expiry date.\n- `notes` (string, nullable, max 2000) — internal note.\n\nReturns 201 with `{ data: <gift card>, balance: <float>, message: \"Gift card issued.\" }`.","body":{"mode":"raw","raw":"{\n  \"amount\": 50,\n  \"code\": \"GC-7F3A9C2E4B10\",\n  \"security_code\": \"4821\",\n  \"is_digital\": true,\n  \"customer_id\": 842,\n  \"recipient_name\": \"Alex Rivera\",\n  \"recipient_email\": \"alex.rivera@example.com\",\n  \"expires_at\": \"2027-07-06\",\n  \"notes\": \"Birthday gift card issued at register.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/gift-cards","host":["{{baseUrl}}"],"path":["api","gift-cards"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"code\": \"GC-7F3A9C2E4B10\",\n    \"status\": \"active\",\n    \"status_label\": \"Active\",\n    \"balance\": 50,\n    \"currency_id\": 1,\n    \"customer_id\": 842,\n    \"is_digital\": true,\n    \"recipient_name\": \"Alex Rivera\",\n    \"recipient_email\": \"alex.rivera@example.com\",\n    \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n    \"activated_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"balance\": 50,\n  \"message\": \"Gift card issued.\"\n}"}]},{"name":"Lookup Gift Card by Code","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/gift-cards/lookup?code=GC-7F3A9C2E4B10","host":["{{baseUrl}}"],"path":["api","gift-cards","lookup"],"query":[{"key":"code","value":"GC-7F3A9C2E4B10","description":"Required. The gift card code as entered at the register (string, max 255).","disabled":true}]},"description":"Resolve a gift card by its code (POS entry) and return it alongside its current balance. Use this when a customer presents a card at checkout.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nQuery parameters:\n- `code` (string, required, max 255) — the gift card code.\n\nReturns 200 with `{ data: <gift card>, balance: <float> }`, or 404 `{ message }` when no card matches the code."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/gift-cards/lookup?code=GC-7F3A9C2E4B10","host":["{{baseUrl}}"],"path":["api","gift-cards","lookup"],"query":[{"key":"code","value":"GC-7F3A9C2E4B10","description":"Required. The gift card code as entered at the register (string, max 255).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"code\": \"GC-7F3A9C2E4B10\",\n    \"status\": \"active\",\n    \"status_label\": \"Active\",\n    \"balance\": 50,\n    \"currency_id\": 1,\n    \"customer_id\": 842,\n    \"is_digital\": true,\n    \"recipient_name\": \"Alex Rivera\",\n    \"recipient_email\": \"alex.rivera@example.com\",\n    \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n    \"activated_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"balance\": 50\n}"}]},{"name":"Get Gift Card","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id."}]},"description":"Show a single gift card by id, including its current balance and lifecycle status.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nStatus values: `active`, `inactive`, `redeemed`, `expired`, `voided`.\n\nReturns 200 with `{ data: <gift card> }`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"code\": \"GC-7F3A9C2E4B10\",\n    \"status\": \"active\",\n    \"status_label\": \"Active\",\n    \"balance\": 50,\n    \"currency_id\": 1,\n    \"customer_id\": 842,\n    \"is_digital\": true,\n    \"recipient_name\": \"Alex Rivera\",\n    \"recipient_email\": \"alex.rivera@example.com\",\n    \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n    \"activated_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  }\n}"}]},{"name":"Get Gift Card History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/history","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","history"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id."}]},"description":"Paginated ledger history for a gift card, newest first. Each entry records a value movement (activation, reload, redemption, refund, adjustment, or void), the resulting balance, and who created it.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nEntry `type` values: `activation`, `reload`, `redemption`, `refund`, `adjustment`, `void`. `is_credit` is true when the entry adds value.\n\nPagination: `per_page` (default 10), `page` (default 1). Response includes standard Laravel pagination metadata."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/history","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","history"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"gift_card_id\": 15,\n      \"reference\": \"GC-TXN-000088\",\n      \"amount\": 25,\n      \"balance_after\": 75,\n      \"type\": \"reload\",\n      \"type_label\": \"Reload\",\n      \"is_credit\": true,\n      \"currency_id\": 1,\n      \"notes\": \"Top-up at register.\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T15:10:00+00:00\"\n    },\n    {\n      \"id\": 84,\n      \"gift_card_id\": 15,\n      \"reference\": \"GC-TXN-000084\",\n      \"amount\": -20,\n      \"balance_after\": 50,\n      \"type\": \"redemption\",\n      \"type_label\": \"Redemption\",\n      \"is_credit\": false,\n      \"currency_id\": 1,\n      \"notes\": null,\n      \"source_type\": \"App\\\\Models\\\\PosTransaction\",\n      \"source_id\": 1001,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:45:00+00:00\"\n    },\n    {\n      \"id\": 80,\n      \"gift_card_id\": 15,\n      \"reference\": \"GC-TXN-000080\",\n      \"amount\": 50,\n      \"balance_after\": 70,\n      \"type\": \"activation\",\n      \"type_label\": \"Activation\",\n      \"is_credit\": true,\n      \"currency_id\": 1,\n      \"notes\": \"Birthday gift card issued at register.\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:30:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/gift-cards/15/history?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/gift-cards/15/history?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/gift-cards/15/history\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 3\n}"}]},{"name":"Reload Gift Card","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/reload","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","reload"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id to add value to."}]},"description":"Add value to an existing gift card. Writes a reload ledger entry and returns it with the card's new balance.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.manage`.\n\nRequest body fields:\n- `amount` (numeric, required, > 0) — the amount to add. Error message when not > 0: \"The reload amount must be greater than zero.\"\n- `notes` (string, nullable, max 2000) — internal note.\n- `reference` (string, nullable, max 255) — external reference for the reload (e.g. a receipt or payment reference).\n\nReturns 201 with `{ data: <ledger entry>, balance: <float>, message: \"Gift card reloaded.\" }`.","body":{"mode":"raw","raw":"{\n  \"amount\": 25,\n  \"notes\": \"Top-up at register.\",\n  \"reference\": \"POS-RELOAD-1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/reload","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","reload"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id to add value to."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 90,\n    \"gift_card_id\": 15,\n    \"reference\": \"POS-RELOAD-1042\",\n    \"amount\": 25,\n    \"balance_after\": 75,\n    \"type\": \"reload\",\n    \"type_label\": \"Reload\",\n    \"is_credit\": true,\n    \"currency_id\": 1,\n    \"notes\": \"Top-up at register.\",\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 7,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T15:10:00+00:00\"\n  },\n  \"balance\": 75,\n  \"message\": \"Gift card reloaded.\"\n}"}]},{"name":"Void Gift Card","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/void","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","void"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id to void."}]},"description":"Void a gift card. Drains any remaining balance (via a void ledger entry) and marks the card `voided` so it can no longer be redeemed. No request body.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.manage`.\n\nReturns 200 with `{ data: <gift card>, message: \"Gift card voided.\" }`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/gift-cards/{giftCard}/void","host":["{{baseUrl}}"],"path":["api","gift-cards",":giftCard","void"],"variable":[{"key":"giftCard","value":"15","description":"The gift card id to void."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"code\": \"GC-7F3A9C2E4B10\",\n    \"status\": \"voided\",\n    \"status_label\": \"Voided\",\n    \"balance\": 0,\n    \"currency_id\": 1,\n    \"customer_id\": 842,\n    \"is_digital\": true,\n    \"recipient_name\": \"Alex Rivera\",\n    \"recipient_email\": \"alex.rivera@example.com\",\n    \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n    \"activated_at\": \"2026-07-06T14:30:00+00:00\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"message\": \"Gift card voided.\"\n}"}]}]},{"name":"House Accounts","item":[{"name":"Get House Account Balance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]},"description":"Return the customer's house-account balance owed, credit limit, and remaining headroom.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\n\nResponse fields (under `data`):\n- `customer_id` (integer) — the customer.\n- `house_account_enabled` (boolean) — whether on-account charging is enabled for this customer.\n- `balance` (float) — the current balance owed on the account.\n- `credit_limit` (float | null) — the customer's credit limit, or null when uncapped.\n- `available_credit` (float | null) — remaining headroom (credit_limit − balance), or null when there is no limit.\n\nReturns 200 with `{ data: { ... } }`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"customer_id\": 842,\n    \"house_account_enabled\": true,\n    \"balance\": 250,\n    \"credit_limit\": 1000,\n    \"available_credit\": 750\n  }\n}"}]},{"name":"Get House Account History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","history"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]},"description":"Paginated house-account ledger history for the customer, newest first. Each entry records a value movement (charge, payment, adjustment, or write-off), the resulting balance, and who created it.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\n\nEntry `type` values: `charge`, `payment`, `adjustment`, `write_off`. `is_charge` is true when the entry's amount is positive (increases the balance owed). `reference` falls back to an `HA-000123`-style identifier when no explicit reference was recorded.\n\nPagination: `per_page` (default 10), `page` (default 1). Response includes standard Laravel pagination metadata."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","history"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"customer_id\": 842,\n      \"reference\": \"CHK-4021\",\n      \"amount\": -100,\n      \"balance_after\": 250,\n      \"type\": \"payment\",\n      \"type_label\": \"Payment\",\n      \"is_charge\": false,\n      \"currency_id\": 1,\n      \"notes\": \"Check #4021 applied.\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T15:10:00+00:00\"\n    },\n    {\n      \"id\": 84,\n      \"customer_id\": 842,\n      \"reference\": \"HA-000084\",\n      \"amount\": 250,\n      \"balance_after\": 350,\n      \"type\": \"charge\",\n      \"type_label\": \"Charge\",\n      \"is_charge\": true,\n      \"currency_id\": 1,\n      \"notes\": null,\n      \"source_type\": \"App\\\\Models\\\\PosTransaction\",\n      \"source_id\": 1001,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:45:00+00:00\"\n    },\n    {\n      \"id\": 80,\n      \"customer_id\": 842,\n      \"reference\": \"HA-000080\",\n      \"amount\": -25,\n      \"balance_after\": 100,\n      \"type\": \"adjustment\",\n      \"type_label\": \"Adjustment\",\n      \"is_charge\": false,\n      \"currency_id\": 1,\n      \"notes\": \"Goodwill credit.\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:30:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/customers/842/house-account/history?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/customers/842/house-account/history?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/customers/842/house-account/history\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 3\n}"}]},{"name":"Charge House Account","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/charge","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","charge"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]},"description":"Manually charge an amount to the customer's house account, increasing the balance owed. Writes a `charge` ledger entry and returns it with the account's new balance.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nRequest body fields:\n- `amount` (numeric, required, > 0) — the amount to charge. Error message when not > 0: \"The charge amount must be greater than zero.\"\n- `notes` (string, nullable, max 2000) — internal note.\n- `reference` (string, nullable, max 255) — external reference (e.g. a PO or receipt number).\n\nThe charge is rejected with 422 when the customer has no house account enabled, or when it would push the balance owed past the customer's credit limit.\n\nReturns 201 with `{ data: <ledger entry>, balance: <float>, message: \"Charge recorded.\" }`.","body":{"mode":"raw","raw":"{\n  \"amount\": 150,\n  \"notes\": \"On-account purchase at the register.\",\n  \"reference\": \"PO-4821\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/charge","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","charge"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 90,\n    \"customer_id\": 842,\n    \"reference\": \"PO-4821\",\n    \"amount\": 150,\n    \"balance_after\": 400,\n    \"type\": \"charge\",\n    \"type_label\": \"Charge\",\n    \"is_charge\": true,\n    \"currency_id\": 1,\n    \"notes\": \"On-account purchase at the register.\",\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 7,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T15:30:00+00:00\"\n  },\n  \"balance\": 400,\n  \"message\": \"Charge recorded.\"\n}"}]},{"name":"Record House Account Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/pay","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","pay"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]},"description":"Record a payment against the customer's house account, reducing the balance owed. Writes a `payment` ledger entry and returns it with the account's new balance.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nRequest body fields:\n- `amount` (numeric, required, > 0) — the payment amount. Error message when not > 0: \"The payment amount must be greater than zero.\"\n- `notes` (string, nullable, max 2000) — internal note.\n- `reference` (string, nullable, max 255) — external reference (e.g. a cheque or payment reference).\n\nReturns 201 with `{ data: <ledger entry>, balance: <float>, message: \"Payment recorded.\" }`.","body":{"mode":"raw","raw":"{\n  \"amount\": 100,\n  \"notes\": \"Check #4021.\",\n  \"reference\": \"CHK-4021\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/pay","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","pay"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 91,\n    \"customer_id\": 842,\n    \"reference\": \"CHK-4021\",\n    \"amount\": -100,\n    \"balance_after\": 300,\n    \"type\": \"payment\",\n    \"type_label\": \"Payment\",\n    \"is_charge\": false,\n    \"currency_id\": 1,\n    \"notes\": \"Check #4021.\",\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 7,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T15:40:00+00:00\"\n  },\n  \"balance\": 300,\n  \"message\": \"Payment recorded.\"\n}"}]},{"name":"Adjust House Account","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/adjust","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","adjust"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]},"description":"Manually adjust or write off the customer's house-account balance. Writes an `adjustment` or `write_off` ledger entry and returns it with the account's new balance.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nRequest body fields:\n- `amount` (numeric, required, non-zero) — signed for an adjustment (+ increases the balance owed, − decreases it); magnitude for a write-off (always reduces the balance). Error message when 0: \"The adjustment amount must be non-zero.\"\n- `type` (string, nullable, one of `adjustment`, `write_off`) — defaults to `adjustment` when omitted. Error message on invalid value: \"The type must be an adjustment or a write-off.\"\n- `notes` (string, nullable, max 2000) — internal note.\n\nReturns 201 with `{ data: <ledger entry>, balance: <float>, message: \"House account adjusted.\" }`.","body":{"mode":"raw","raw":"{\n  \"amount\": -50,\n  \"type\": \"write_off\",\n  \"notes\": \"Bad-debt write-off approved by finance.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/house-account/adjust","host":["{{baseUrl}}"],"path":["api","customers",":customer","house-account","adjust"],"variable":[{"key":"customer","value":"842","description":"The customer id (path parameter for every house-account endpoint)."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 92,\n    \"customer_id\": 842,\n    \"reference\": \"HA-000092\",\n    \"amount\": -50,\n    \"balance_after\": 250,\n    \"type\": \"write_off\",\n    \"type_label\": \"Write-off\",\n    \"is_charge\": false,\n    \"currency_id\": 1,\n    \"notes\": \"Bad-debt write-off approved by finance.\",\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 7,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T15:50:00+00:00\"\n  },\n  \"balance\": 250,\n  \"message\": \"House account adjusted.\"\n}"}]}]},{"name":"Export","item":[{"name":"Download Export File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/download?file=export-file.csv","host":["{{baseUrl}}"],"path":["api","export","download"],"query":[{"key":"file","value":"export-file.csv","description":"Filename of the completed export (from create-download-file). Required.","disabled":true}]},"description":"Downloads a completed export file from the model-exports disk by filename (the `file` returned from create-download-file). Streams the file as a CSV download (Content-Type: text/csv).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nQuery parameters:\n- file (required): Filename of the completed export. Returns 404 if omitted.\n\nResponses:\n- 200: File download (text/csv).\n- 404: The `file` param is missing, or the export file no longer exists / has expired / its metadata can't be read. Regenerate the export.\n\nNote: Response is a file download, not JSON."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/download?file=export-file.csv","host":["{{baseUrl}}"],"path":["api","export","download"],"query":[{"key":"file","value":"export-file.csv","description":"Filename of the completed export (from create-download-file). Required.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,name\n1,Widget\n2,Gadget"}]},{"name":"Export Initial Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/initial-inventory/{warehouse}/export","host":["{{baseUrl}}"],"path":["api","export","initial-inventory",":warehouse","export"],"variable":[{"key":"warehouse","value":"1","description":"Warehouse ID"}]},"description":"Exports initial inventory for a specific warehouse as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Export Sales Order Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-orders/{id}/export-lines","host":["{{baseUrl}}"],"path":["api","export","sales-orders",":id","export-lines"],"variable":[{"key":"id","value":"100","description":"Sales Order ID"}]},"description":"Exports lines for a specific sales order as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download\n\nColumns: sales_order_number, sku, description, quantity, price, warehouse_id, weight, weight_unit, length, width, height, dimension_unit, weight_extended (quantity x unit weight), volume_extended (quantity x unit volume). Weight and dimension values are sourced from the line's product. The header row is always returned even when the order has no lines."}},{"name":"Export Sales Order Line Financials (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/v2/sales-order-line-financials","host":["{{baseUrl}}"],"path":["api","export","v2","sales-order-line-financials"]},"description":"Exports sales order line financials (v2) as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Export Sales Order Packing Slips","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-orders/packing-slips","host":["{{baseUrl}}"],"path":["api","export","sales-orders","packing-slips"]},"description":"Exports packing slips for multiple sales orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: file download"}},{"name":"Download Sales Order Invoice PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-orders/{sales_order}/invoice/pdf","host":["{{baseUrl}}"],"path":["api","export","sales-orders",":sales_order","invoice","pdf"],"variable":[{"key":"sales_order","value":"100","description":"Sales Order ID"}]},"description":"Downloads the invoice PDF for a specific sales order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: application/pdf file download"}},{"name":"Download Sales Order Packing Slip PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-orders/{sales_order}/packing-slip/pdf","host":["{{baseUrl}}"],"path":["api","export","sales-orders",":sales_order","packing-slip","pdf"],"variable":[{"key":"sales_order","value":"100","description":"Sales Order ID"}]},"description":"Downloads the packing slip PDF for a specific sales order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: application/pdf file download"}},{"name":"Export Sales Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-credits","host":["{{baseUrl}}"],"path":["api","export","sales-credits"]},"description":"Exports sales credits as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Export Sales Order Fulfillment Packing Slips","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-order-fulfillments/packing-slips","host":["{{baseUrl}}"],"path":["api","export","sales-order-fulfillments","packing-slips"]},"description":"Exports packing slips for multiple sales order fulfillments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: file download"}},{"name":"Export Purchase Order Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/purchase-orders/{id}/export-lines","host":["{{baseUrl}}"],"path":["api","export","purchase-orders",":id","export-lines"],"variable":[{"key":"id","value":"50","description":"Purchase Order ID"}]},"description":"Exports lines for a specific purchase order as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Download Purchase Order Invoice CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/purchase-orders/{purchase_order}/invoice/csv","host":["{{baseUrl}}"],"path":["api","export","purchase-orders",":purchase_order","invoice","csv"],"variable":[{"key":"purchase_order","value":"50","description":"Purchase Order ID"}]},"description":"Downloads the invoice CSV for a specific purchase order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Download Purchase Order Invoice PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/purchase-orders/{purchase_order}/invoice/pdf","host":["{{baseUrl}}"],"path":["api","export","purchase-orders",":purchase_order","invoice","pdf"],"variable":[{"key":"purchase_order","value":"50","description":"Purchase Order ID"}]},"description":"Downloads the invoice PDF for a specific purchase order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: application/pdf file download"}},{"name":"Download Purchase Order Picklist PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/purchase-orders/{purchase_order}/picklist/pdf","host":["{{baseUrl}}"],"path":["api","export","purchase-orders",":purchase_order","picklist","pdf"],"variable":[{"key":"purchase_order","value":"50","description":"Purchase Order ID"}]},"description":"Downloads the picklist PDF for a specific purchase order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: application/pdf file download"}},{"name":"Export Stock Take Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/stock-takes/{stock_take}/export-lines","host":["{{baseUrl}}"],"path":["api","export","stock-takes",":stock_take","export-lines"],"variable":[{"key":"stock_take","value":"1","description":"Stock Take ID"}]},"description":"Exports lines for a specific stock take as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Export Warehouse Transfer Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/warehouse-transfers/{id}/export-lines","host":["{{baseUrl}}"],"path":["api","export","warehouse-transfers",":id","export-lines"],"variable":[{"key":"id","value":"1","description":"Warehouse Transfer ID"}]},"description":"Exports lines for a specific warehouse transfer as a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: text/csv file download"}},{"name":"Export Ship By Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/ship-by-schedule","host":["{{baseUrl}}"],"path":["api","export","ship-by-schedule"]},"description":"Exports ship-by schedule data as a CSV/JSON file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse: file download"}},{"name":"Export Financial Alerts (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/v2/financial-alerts","host":["{{baseUrl}}"],"path":["api","export","v2","financial-alerts"]},"description":"Exports all financial alerts using the V2 API. Returns JSON array for client-side CSV generation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/v2/financial-alerts","host":["{{baseUrl}}"],"path":["api","export","v2","financial-alerts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"salesOrder\": \"SO-1001\",\n      \"salesOrderId\": 1001,\n      \"sku\": \"WIDGET-001\",\n      \"product_id\": 42,\n      \"total_revenue\": 150,\n      \"cogs\": 80,\n      \"cogs_returned\": 0,\n      \"cost_allocated\": 10,\n      \"allocated_details\": [\n        {\n          \"description\": \"Shipping\",\n          \"amount\": 10\n        }\n      ],\n      \"total_cost\": 90,\n      \"profit\": 60,\n      \"profit_margin\": 40,\n      \"classification\": \"Low Margin\",\n      \"classification_id\": 2,\n      \"archived_by_user\": null,\n      \"archived_at\": null,\n      \"is_resolved\": \"false\"\n    }\n  ]\n}"}]},{"name":"Export Accounting Transactions (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/v2/accounting-transactions","host":["{{baseUrl}}"],"path":["api","export","v2","accounting-transactions"]},"description":"Streams a CSV export of accounting transactions with the same filters as the v3/transactions list endpoint. Response is a streaming text/csv file download.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nFilters use the same Spatie QueryBuilder parameters as GET /api/accounting/v3/transactions."}},{"name":"Export Profitability Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/v2/profitability-drilldown?dimension=brand&dimension_value=Nike","host":["{{baseUrl}}"],"path":["api","export","v2","profitability-drilldown"],"query":[{"key":"dimension","value":"brand","description":"Dimension to drilldown: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Nike","description":"Specific dimension value to filter by","disabled":true}]},"description":"Dispatch an asynchronous CSV export of all profitability drilldown orders for a dimension. The drilldown materialises every order and builds the whole file, which can exceed a ~100s edge-proxy limit (Cloudflare 524) — so it runs as a tracked export job. Returns a tracked_job_log_id; progress and the download link surface via the tracked job log endpoints. The finished file is fetched from GET /api/export/download?file={filename}.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params: dimension (brand|sku|supplier|sales_channel|product_type|sub_sales_channel|customer_tags; customer_tags fans out so an order counts toward each of its customer's tags and the grand total is deduplicated), dimension_value, flt_ids[] (financial line type ids for extra columns)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/v2/profitability-drilldown?dimension=brand&dimension_value=Nike","host":["{{baseUrl}}"],"path":["api","export","v2","profitability-drilldown"],"query":[{"key":"dimension","value":"brand","description":"Dimension to drilldown: brand | sku | supplier | sales_channel | product_type | sub_sales_channel | customer_tags. customer_tags fans out — an order counts toward each of its customer's tags — and the grand total is deduplicated. customer_tags does not require attribute_id.","disabled":true},{"key":"dimension_value","value":"Nike","description":"Specific dimension value to filter by","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5123,\n    \"queued\": true\n  },\n  \"message\": \"Export started — track progress in the job tray\"\n}"}]},{"name":"Export Daily Financials","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/daily-financials","host":["{{baseUrl}}"],"path":["api","export","daily-financials"]},"description":"Returns the full daily financial summary dataset as JSON for export, honoring the same filters and sorting as the daily summary listing (`GET /api/v2/financials/daily-summary`) but without pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row aggregates one day's financial activity for a subject: either a product (units sold, revenue, cost, profit for that SKU on that day) or a financial line type (order-level amounts such as shipping revenue or transaction fees). The `reportable` object identifies the subject.\n\nThe response contains every matching row, so filter by date range to keep payloads manageable on large accounts.\n\nLarge result sets are exported asynchronously: when the filtered dataset exceeds 1000 rows the endpoint dispatches a background CSV export job and responds with a tracked_job_log_id (queued=true) instead of the inline rows. Poll the job by its tracked_job_log_id and fetch the finished file from GET /api/export/download?file={filename}. Smaller result sets return the rows inline as shown below.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/daily-financials","host":["{{baseUrl}}"],"path":["api","export","daily-financials"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"date\": \"2026-06-15T00:00:00.000000Z\",\n      \"reportable\": {\n        \"id\": 101,\n        \"type\": \"App\\\\Models\\\\Product\",\n        \"product\": {\n          \"id\": 101,\n          \"sku\": \"TSHIRT-BLK-M\",\n          \"brand\": \"Acme\",\n          \"brand_id\": 3\n        }\n      },\n      \"quantity\": 14,\n      \"quantity_returned\": 1,\n      \"num_orders\": 12,\n      \"revenue\": 349.86,\n      \"revenue_allocated\": 0,\n      \"revenue_credits\": -24.99,\n      \"revenue_discount\": -10,\n      \"total_revenue\": 314.87,\n      \"cost\": 126,\n      \"cost_allocated\": 8.4,\n      \"cost_invoices\": 0,\n      \"cost_returned\": -9,\n      \"cost_breakdown\": null,\n      \"total_cost\": 125.4,\n      \"profit\": 189.47,\n      \"profit_margin\": 60.17,\n      \"created_at\": \"2026-06-16T02:10:00.000000Z\",\n      \"updated_at\": \"2026-06-16T02:10:00.000000Z\"\n    },\n    {\n      \"id\": 5013,\n      \"date\": \"2026-06-15T00:00:00.000000Z\",\n      \"reportable\": {\n        \"id\": 7,\n        \"type\": \"App\\\\Models\\\\FinancialLineType\",\n        \"financial_line_type\": {\n          \"id\": 7,\n          \"name\": \"Shipping Revenue\",\n          \"classification\": \"revenue\"\n        }\n      },\n      \"quantity\": 0,\n      \"quantity_returned\": 0,\n      \"num_orders\": 12,\n      \"revenue\": 58.8,\n      \"revenue_allocated\": 0,\n      \"revenue_credits\": 0,\n      \"revenue_discount\": 0,\n      \"total_revenue\": 58.8,\n      \"cost\": 0,\n      \"cost_allocated\": 0,\n      \"cost_invoices\": 0,\n      \"cost_returned\": 0,\n      \"cost_breakdown\": null,\n      \"total_cost\": 0,\n      \"profit\": 58.8,\n      \"profit_margin\": 100,\n      \"created_at\": \"2026-06-16T02:10:00.000000Z\",\n      \"updated_at\": \"2026-06-16T02:10:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Export Vendor Deposits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/v2/vendor-deposits","host":["{{baseUrl}}"],"path":["api","export","v2","vendor-deposits"]},"description":"Streams all vendor deposits matching the given filters as a CSV file download (`vendor-deposits.csv`). Honors the same filters and sorting as the vendor deposit list endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: Deposit #, Supplier, Purchase Order, Status, Currency, Amount, Amount Paid, Amount Applied, Amount Refunded, Available Balance, Deposit Date, Due Date, External Reference, Notes, Created At. Available Balance is computed as amount paid minus amounts applied and refunded (floored at 0).\n\nArchived deposits are excluded by default; pass `filter[archived]=1` to include them. The response is a file download (`text/csv`), not JSON.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/v2/vendor-deposits","host":["{{baseUrl}}"],"path":["api","export","v2","vendor-deposits"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Deposit #,Supplier,Purchase Order,Status,Currency,Amount,Amount Paid,Amount Applied,Amount Refunded,Available Balance,Deposit Date,Due Date,External Reference,Notes,Created At\nVD-00042,Acme Apparel Co,PO-350,paid,USD,5000.00,5000.00,2500.00,0.00,2500.00,2026-05-01,2026-05-15,WIRE-88213,30% deposit on spring order,2026-05-01 14:22:10\nVD-00043,Global Freight Co,PO-351,partially_paid,USD,1200.00,600.00,0.00,0.00,600.00,2026-05-20,2026-06-01,,,2026-05-20 09:03:41\n"}]}]},{"name":"Data Feeds","item":[{"name":"Get Data Feed","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single data feed by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Daily Product Feed\",\n    \"type\": \"product_feed\",\n    \"data_direction\": \"import\",\n    \"connection_type\": \"ftp_download\",\n    \"connection_settings\": {\n      \"host\": \"ftp.supplier.com\",\n      \"username\": \"feeduser\",\n      \"path\": \"/feeds/products.csv\"\n    },\n    \"field_settings\": null,\n    \"filters\": null,\n    \"schedule\": {\n      \"frequency\": \"daily\",\n      \"time\": \"02:00\"\n    },\n    \"processed_at\": \"2024-03-01T02:05:00.000000Z\",\n    \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T02:05:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Data Feed","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing data feed configuration.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nAll fields from Create are accepted.","body":{"mode":"raw","raw":"{\n  \"name\": \"Daily Product Feed Updated\",\n  \"type\": \"product_feed\",\n  \"data_direction\": \"import\",\n  \"connection_type\": \"google_sheets\",\n  \"connection_settings\": {\n    \"sheet_id\": \"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms\",\n    \"sheet_name\": \"Products\"\n  },\n  \"schedule\": {\n    \"frequency\": \"hourly\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Daily Product Feed Updated\",\n    \"type\": \"product_feed\",\n    \"connection_type\": \"google_sheets\",\n    \"updated_at\": \"2024-03-01T14:00:00.000000Z\"\n  },\n  \"message\": \"data feed Daily Product Feed Updated updated successfully\"\n}"}]},{"name":"Delete Data Feed","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a data feed. Returns an error if the feed is linked to other records.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/data-feeds/{id}","host":["{{baseUrl}}"],"path":["api","data-feeds",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"data feed 2 deleted successfully\"\n}"}]},{"name":"Create Data Feed","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/data-feeds","host":["{{baseUrl}}"],"path":["api","data-feeds"]},"description":"Creates a new data feed and immediately dispatches an import job.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, max:255)\n- type (required, string): product_feed\n- data_direction (required, string): import | export\n- connection_type (required, string): upload_file | download_file | ftp_download | google_sheets | rest_api | downloadable_file\n- connection_settings (optional, array — connection credentials and settings)\n- field_settings (optional, array — column mappings)\n- filters (optional, array — data filtering rules)\n- schedule (optional, array — scheduling configuration)\n\n**Requires permission:** `data_feeds.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Daily Product Feed\",\n  \"type\": \"product_feed\",\n  \"data_direction\": \"import\",\n  \"connection_type\": \"ftp_download\",\n  \"connection_settings\": {\n    \"host\": \"ftp.supplier.com\",\n    \"username\": \"feeduser\",\n    \"password\": \"secret\",\n    \"path\": \"/feeds/products.csv\"\n  },\n  \"field_settings\": {\n    \"sku_column\": \"SKU\",\n    \"name_column\": \"Product Name\",\n    \"price_column\": \"Price\"\n  },\n  \"filters\": {\n    \"active_only\": true\n  },\n  \"schedule\": {\n    \"frequency\": \"daily\",\n    \"time\": \"02:00\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/data-feeds","host":["{{baseUrl}}"],"path":["api","data-feeds"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Daily Product Feed\",\n    \"type\": \"product_feed\",\n    \"data_direction\": \"import\",\n    \"connection_type\": \"ftp_download\",\n    \"connection_settings\": {\n      \"host\": \"ftp.supplier.com\",\n      \"username\": \"feeduser\",\n      \"path\": \"/feeds/products.csv\"\n    },\n    \"field_settings\": {\n      \"sku_column\": \"SKU\",\n      \"name_column\": \"Product Name\",\n      \"price_column\": \"Price\"\n    },\n    \"filters\": {\n      \"active_only\": true\n    },\n    \"schedule\": {\n      \"frequency\": \"daily\",\n      \"time\": \"02:00\"\n    },\n    \"processed_at\": null,\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"data feed created successfully\"\n}"}]},{"name":"Bulk Delete Data Feeds","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds","host":["{{baseUrl}}"],"path":["api","data-feeds"]},"description":"Bulk deletes multiple data feeds by IDs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `data_feeds.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/data-feeds","host":["{{baseUrl}}"],"path":["api","data-feeds"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 data feeds deleted successfully\"\n}"}]},{"name":"Archive Data Feed","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds/{id}/archive","host":["{{baseUrl}}"],"path":["api","data-feeds",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a data feed. Returns a warning if already archived.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/data-feeds/{id}/archive","host":["{{baseUrl}}"],"path":["api","data-feeds",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"data feed 1 archived successfully\"\n}"}]},{"name":"Unarchive Data Feed","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","data-feeds",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a data feed. Returns a warning if not currently archived.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/data-feeds/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","data-feeds",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"data feed 1 unarchived successfully\"\n}"}]},{"name":"Bulk Archive Data Feeds","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/data-feeds/archive","host":["{{baseUrl}}"],"path":["api","data-feeds","archive"]},"description":"Bulk archives multiple data feeds by IDs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `data_feeds.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/data-feeds/archive","host":["{{baseUrl}}"],"path":["api","data-feeds","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 data feeds archived successfully\"\n}"}]},{"name":"Bulk Unarchive Data Feeds","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/data-feeds/unarchive","host":["{{baseUrl}}"],"path":["api","data-feeds","unarchive"]},"description":"Bulk unarchives multiple data feeds by IDs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `data_feeds.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/data-feeds/unarchive","host":["{{baseUrl}}"],"path":["api","data-feeds","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 data feeds unarchived successfully\"\n}"}]},{"name":"Check Data Feeds Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/data-feeds/deletable","host":["{{baseUrl}}"],"path":["api","data-feeds","deletable"]},"description":"Checks which data feeds can be safely deleted.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `data_feeds.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/data-feeds/deletable","host":["{{baseUrl}}"],"path":["api","data-feeds","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Daily Product Feed\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Hourly Price Feed\"\n    }\n  ]\n}"}]},{"name":"Get Import Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/data-feeds/import-config/product_feed","host":["{{baseUrl}}"],"path":["api","data-feeds","import-config","product_feed"]},"description":"Returns the import configuration schema for a specific data feed type. Used to determine available field mappings and settings for a given feed type.\n\nAuthentication: Requires Bearer token.\n\nThe {dataFeed} path parameter should be a feed type key (e.g., product_feed)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/data-feeds/import-config/product_feed","host":["{{baseUrl}}"],"path":["api","data-feeds","import-config","product_feed"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fields\": [\n    {\n      \"key\": \"sku\",\n      \"label\": \"SKU\",\n      \"required\": true\n    },\n    {\n      \"key\": \"name\",\n      \"label\": \"Product Name\",\n      \"required\": true\n    },\n    {\n      \"key\": \"price\",\n      \"label\": \"Price\",\n      \"required\": false\n    },\n    {\n      \"key\": \"quantity\",\n      \"label\": \"Quantity\",\n      \"required\": false\n    }\n  ],\n  \"connection_types\": [\n    \"upload_file\",\n    \"ftp_download\",\n    \"google_sheets\",\n    \"rest_api\"\n  ]\n}"}]}]},{"name":"Inventory Intelligence","item":[{"name":"Build Forecast","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/build","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","build"]},"description":"Build a replenishment forecast for one or more suppliers and return recommended order quantities per supplier, with a full per-line breakdown of how each number was derived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFORECAST TYPES (forecast_type)\n- with_sales_history: derive demand from historical sales velocity over the chosen window. The most common mode.\n- target_stock_level: order up to a fixed target quantity per product (target_quantity), or up to each product's minimum stock level when use_min_stock_level_as_target is true. Velocity is not used to set the target.\n- fill_backorders: order only what is needed to clear outstanding backorders. Baseline and trend settings do not apply.\n\nBASELINE METHODS (baseline_method) - how the daily velocity baseline is derived from sales history (applies to with_sales_history)\n- flat (default): plain mean over the window (total units / days covered). No trend. Legacy behaviour - stable and predictable. Use when demand is roughly level.\n- recency_weighted: weights recent history more heavily than older history, so a recent shift in demand is reflected faster without projecting a hard trend line. Use for choppy demand that has recently stepped up or down. Tune with trend_half_life_days.\n- damped_trend: fits the recent growth (or decline) trend and projects it forward, attenuated by trend_damping_factor so a short surge does not overshoot into over-ordering. Use for a SKU on a sustained growth or decline curve.\n\nDAMPED-TREND CONTROLS\n- trend_damping_factor (0..1, default 0.85): the damping factor phi. Each period further out keeps only phi of the previous period's growth, so the projected trend flattens instead of compounding forever. Lower = more damping (closer to flat mean); 1.0 = undamped.\n- trend_max_growth_pct (>= 0, default 100): caps how far the trend may lift the baseline above the flat mean. 100 means the trend may at most double the flat mean; 0 disables any lift. When the cap binds, the line reports trend_capped: true.\n- trend_half_life_days (>= 1, nullable, default 21): reserved tuning for recency_weighted - the age at which a day's weight halves.\n\nSPARSE-HISTORY FALLBACK\nA trend needs enough signal to be trustworthy. If a product has fewer than roughly 8 weeks of history or fewer than 8 orders in the window, the trend is skipped and the baseline falls back to the flat mean for that product (trend_factor 1.0), regardless of baseline_method. This stops a couple of early sales from projecting a runaway trend.\n\nANOMALY CLEANSING (exclude_detected_anomalies, default false)\nWhen true, days already resolved as excluded or smoothed anomalies for a product are dropped (excluded) or replaced with their expected value (smoothed) before the baseline is computed. This de-contaminates one-off promo spikes and stockout gaps so they do not distort ordinary velocity. Detect and resolve anomalies first (see the Anomalies folder). Each line reports how many days were affected via inputs.anomaly_days_excluded and inputs.anomaly_days_smoothed.\n\nDEMAND MODIFIERS (demand_modifiers[])\nAn array of adjustments layered onto the baseline. Each entry has a type:\n- percentage: scale demand by (1 + value/100), e.g. value 10 = +10%.\n- seasonal / event: a bounded uplift or reduction over a date range (start_date, end_date) for a known seasonal peak or one-time event; value is the percent change.\n- override: replace the daily average outright with value.\n- promo_lift: re-apply a previously measured promotion. Set promo_window_id to a promo window whose lift has been measured; the server hydrates that window's live measured lift and applies it as a MULTIPLICATIVE factor on the current baseline. Because it multiplies the CURRENT baseline (not a stored absolute number), the same promo automatically re-scales as the business grows. Send value 0 - it is ignored and hydrated server-side.\nOptional per-modifier fields: apply_to (all or a scope key), name (label), period_key, start_date, end_date, product_id (limit to one product), promo_window_id (promo_lift only).\n\nFILTERS (product_filters, sales_filters)\nBoth accept a filter_groups tree: a conjunction (and / or) plus a children array of conditions and nested groups. Each condition has column, operator, and value. product_filters narrows which products are forecast; sales_filters narrows which historical orders feed the velocity baseline. A legacy filters.filterSet shape is also accepted for older saved configurations.\nOperators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, greater_than, less_than, between.\nExample: {\"filter_groups\": {\"conjunction\": \"and\", \"children\": [{\"type\": \"condition\", \"condition\": {\"column\": \"order_status\", \"operator\": \"is_one_of\", \"value\": [\"shipped\", \"fulfilled\"]}}]}}\n\nDECOMPOSITION RETURNED PER LINE (inputs object)\nEach forecast line's inputs object exposes the multiplicative decomposition:\n- base_flat: the flat mean before any trend.\n- trend_factor: the multiplicative trend baked into the baseline (1.0 = none).\n- baseline_method: which method produced the baseline.\n- trend_capped: true if trend_max_growth_pct clamped the trend.\n- anomaly_days_excluded / anomaly_days_smoothed: how many history days were dropped / replaced by anomaly cleansing.\n- promo_factor: the multiplicative promo lift applied (null when no promo_lift modifier applied).\n- promo_window_name: the promo window that supplied the lift (null if none).\n- promo_current_baseline: the baseline the promo factor multiplied.\nThe effective daily_average is base_flat x trend_factor x (promo_factor or 1), then any percentage/event/override demand modifiers.\n\nSCENARIOS (copy a body variation for each)\n1) Flat baseline (default / legacy): omit baseline_method or send \"flat\". Velocity is the plain window mean; inputs.trend_factor is 1.0 and inputs.base_flat equals daily_average.\n2) Damped-trend for a growing SKU: baseline_method \"damped_trend\", trend_damping_factor 0.85, trend_max_growth_pct 100. Recent growth is projected forward but damped and capped at 2x the flat mean; inputs.trend_factor rises above 1.0 and inputs.trend_capped reports whether the cap bound.\n3) Recency-weighted: baseline_method \"recency_weighted\", trend_half_life_days 21. Recent days count more; no hard trend line is projected.\n4) Anomaly-cleansed baseline: exclude_detected_anomalies true (after resolving anomalies as excluded/smoothed). Promo spikes and stockout gaps are removed before the mean is taken; inputs.anomaly_days_excluded / inputs.anomaly_days_smoothed report the count.\n5) Re-apply a past promotion: add a demand_modifiers entry of type \"promo_lift\" with promo_window_id set to a measured promo window and value 0. The window's live lift multiplies the current baseline, so it auto-scales with growth; inputs.promo_factor, inputs.promo_window_name, and inputs.promo_current_baseline are populated.\n6) Target stock level / fill backorders: forecast_type \"target_stock_level\" (with target_quantity, or use_min_stock_level_as_target true) orders up to a fixed target; forecast_type \"fill_backorders\" clears backorders only. Baseline and trend settings do not apply to fill_backorders.\n\nMINIMUMS\nenforce_minimum_order_value / enforce_minimum_order_quantity: when true, the per-supplier minimums block flags whether the forecast totals fall below the supplier's minimum_purchase_order / minimum_purchase_order_quantity. Display-only here; enforcement is applied at PO creation time (POST /api/inventory-forecasting/purchase-orders).\n\nEach line also carries a confidence object (tier high/medium/low/new, 0-100 score, drivers, reasons, actions), a prediction_interval (point/lower/upper at a service level), and a plain-language rationale.\n\nReturns 422 if too many products are found for any supplier.","body":{"mode":"raw","raw":"{\n  \"supplier_ids\": [\n    1,\n    2\n  ],\n  \"forecast_type\": \"with_sales_history\",\n  \"target_stock_days\": 30,\n  \"sales_history_days\": 90,\n  \"sales_start_date\": null,\n  \"sales_end_date\": null,\n  \"use_leadtime\": true,\n  \"use_measured_lead_time\": false,\n  \"use_moq\": true,\n  \"use_case_pack\": false,\n  \"case_pack_rounding\": \"round_nearest\",\n  \"override_product_target_days\": false,\n  \"rounding_method\": \"round_half_up\",\n  \"destination_warehouse_id\": null,\n  \"pricing_tier_id\": null,\n  \"ignore_min_stock_level\": false,\n  \"baseline_method\": \"damped_trend\",\n  \"trend_damping_factor\": 0.85,\n  \"trend_max_growth_pct\": 100,\n  \"trend_half_life_days\": 21,\n  \"exclude_detected_anomalies\": true,\n  \"product_filters\": {\n    \"filter_groups\": {\n      \"conjunction\": \"and\",\n      \"children\": [\n        {\n          \"type\": \"condition\",\n          \"condition\": {\n            \"column\": \"sku\",\n            \"operator\": \"contains\",\n            \"value\": \"PROD\"\n          }\n        }\n      ]\n    }\n  },\n  \"sales_filters\": {\n    \"filter_groups\": {\n      \"conjunction\": \"and\",\n      \"children\": [\n        {\n          \"type\": \"condition\",\n          \"condition\": {\n            \"column\": \"order_status\",\n            \"operator\": \"is_one_of\",\n            \"value\": [\n              \"shipped\",\n              \"fulfilled\"\n            ]\n          }\n        }\n      ]\n    }\n  },\n  \"demand_modifiers\": [\n    {\n      \"type\": \"event\",\n      \"value\": 15,\n      \"apply_to\": \"all\",\n      \"name\": \"Holiday Boost\",\n      \"period_key\": null,\n      \"start_date\": \"2024-11-01\",\n      \"end_date\": \"2024-12-31\",\n      \"product_id\": null\n    },\n    {\n      \"type\": \"promo_lift\",\n      \"value\": 0,\n      \"apply_to\": \"all\",\n      \"name\": \"Re-apply Black Friday 2024\",\n      \"product_id\": 56,\n      \"promo_window_id\": 12\n    }\n  ],\n  \"enforce_minimum_order_value\": false,\n  \"enforce_minimum_order_quantity\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/build","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","build"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"summary\": {\n        \"total_products\": 25,\n        \"products_to_order\": 18,\n        \"total_units\": 512,\n        \"total_value\": 14380\n      },\n      \"lines\": [\n        {\n          \"supplier_product_id\": 101,\n          \"product_id\": 55,\n          \"sku\": \"PROD-001\",\n          \"name\": \"Widget A\",\n          \"recommended_quantity\": 88,\n          \"unit_cost\": 12.5,\n          \"total_cost\": 1100,\n          \"current_stock\": 10,\n          \"days_of_stock\": 2,\n          \"avg_daily_sales\": 5.1618,\n          \"leadtime_days\": 14,\n          \"status\": \"order\",\n          \"inputs\": {\n            \"target_days\": 30,\n            \"target_days_source\": \"config\",\n            \"leadtime\": 14,\n            \"leadtime_source\": \"supplier\",\n            \"supplier_lead_time\": 14,\n            \"effective_days\": 44,\n            \"daily_average\": 5.1618,\n            \"available\": 10,\n            \"inbound\": 0,\n            \"in_transit\": 0,\n            \"backordered\": 0,\n            \"moq\": 25,\n            \"moq_source\": \"supplier\",\n            \"min_stock_level\": 20,\n            \"min_stock_level_ignored\": false,\n            \"order_trigger\": \"velocity\",\n            \"rounding_method\": \"round_half_up\",\n            \"base_daily_average\": 5.1618,\n            \"base_flat\": 3.08,\n            \"trend_factor\": 1.6759,\n            \"baseline_method\": \"damped_trend\",\n            \"trend_capped\": false,\n            \"anomaly_days_excluded\": 2,\n            \"anomaly_days_smoothed\": 0,\n            \"promo_factor\": null,\n            \"promo_window_name\": null,\n            \"promo_current_baseline\": null,\n            \"formula\": \"(daily_average x effective_days) - available - inbound + backordered\"\n          },\n          \"confidence\": {\n            \"tier\": \"medium\",\n            \"score\": 62,\n            \"drivers\": [\n              {\n                \"key\": \"history_length\",\n                \"label\": \"History length\",\n                \"value\": \"90 days\",\n                \"status\": \"ok\"\n              },\n              {\n                \"key\": \"selling_density\",\n                \"label\": \"Selling density\",\n                \"value\": \"71/90 days had sales\",\n                \"status\": \"ok\"\n              },\n              {\n                \"key\": \"variability\",\n                \"label\": \"Demand variability (CV)\",\n                \"value\": \"0.80\",\n                \"status\": \"warn\"\n              },\n              {\n                \"key\": \"recency\",\n                \"label\": \"Last sale\",\n                \"value\": \"1 day ago\",\n                \"status\": \"ok\"\n              }\n            ],\n            \"reasons\": [\n              \"Demand is moderately variable (CV 0.80)\"\n            ],\n            \"actions\": [\n              {\n                \"type\": \"extend_window\",\n                \"label\": \"Extend the sales window\"\n              }\n            ]\n          },\n          \"prediction_interval\": {\n            \"point\": 88,\n            \"lower\": 66,\n            \"upper\": 116,\n            \"service_level\": 90,\n            \"method\": \"cv_heuristic\",\n            \"sigma\": 15.1\n          },\n          \"rationale\": \"Ordering 88: 90 days of history, damped-trend baseline lifting a 3.08/day flat mean to 5.16/day (trend factor 1.68), 2 promo-spike days excluded, 14-day lead time, 10 on hand. Confidence Medium. Likely range 66-116 at 90% service level.\"\n        },\n        {\n          \"supplier_product_id\": 102,\n          \"product_id\": 56,\n          \"sku\": \"PROD-002\",\n          \"name\": \"Widget B\",\n          \"recommended_quantity\": 140,\n          \"unit_cost\": 8,\n          \"total_cost\": 1120,\n          \"current_stock\": 25,\n          \"days_of_stock\": 3,\n          \"avg_daily_sales\": 7.77,\n          \"leadtime_days\": 14,\n          \"status\": \"order\",\n          \"inputs\": {\n            \"target_days\": 30,\n            \"target_days_source\": \"config\",\n            \"leadtime\": 14,\n            \"leadtime_source\": \"supplier\",\n            \"supplier_lead_time\": 14,\n            \"effective_days\": 44,\n            \"daily_average\": 7.77,\n            \"available\": 25,\n            \"inbound\": 0,\n            \"in_transit\": 0,\n            \"backordered\": 0,\n            \"moq\": 50,\n            \"moq_source\": \"supplier\",\n            \"min_stock_level\": 30,\n            \"min_stock_level_ignored\": false,\n            \"order_trigger\": \"velocity\",\n            \"rounding_method\": \"round_half_up\",\n            \"base_daily_average\": 4.2,\n            \"base_flat\": 4.2,\n            \"trend_factor\": 1,\n            \"baseline_method\": \"damped_trend\",\n            \"trend_capped\": false,\n            \"anomaly_days_excluded\": 0,\n            \"anomaly_days_smoothed\": 0,\n            \"promo_factor\": 1.85,\n            \"promo_window_name\": \"Black Friday 2024\",\n            \"promo_current_baseline\": 4.2,\n            \"demand_modifier_description\": \"Promo lift: Black Friday 2024 (x1.85)\",\n            \"formula\": \"(daily_average x effective_days) - available - inbound + backordered\"\n          },\n          \"confidence\": {\n            \"tier\": \"high\",\n            \"score\": 84,\n            \"drivers\": [\n              {\n                \"key\": \"history_length\",\n                \"label\": \"History length\",\n                \"value\": \"90 days\",\n                \"status\": \"ok\"\n              },\n              {\n                \"key\": \"selling_density\",\n                \"label\": \"Selling density\",\n                \"value\": \"88/90 days had sales\",\n                \"status\": \"ok\"\n              },\n              {\n                \"key\": \"variability\",\n                \"label\": \"Demand variability (CV)\",\n                \"value\": \"0.42\",\n                \"status\": \"ok\"\n              },\n              {\n                \"key\": \"recency\",\n                \"label\": \"Last sale\",\n                \"value\": \"today\",\n                \"status\": \"ok\"\n              }\n            ],\n            \"reasons\": [\n              \"Dense, recent, low-variability history\"\n            ],\n            \"actions\": []\n          },\n          \"prediction_interval\": {\n            \"point\": 140,\n            \"lower\": 118,\n            \"upper\": 168,\n            \"service_level\": 90,\n            \"method\": \"cv_heuristic\",\n            \"sigma\": 17.2\n          },\n          \"rationale\": \"Ordering 140: flat 4.2/day baseline re-scaled by the measured Black Friday 2024 lift (x1.85) to 7.77/day, 14-day lead time, 25 on hand. The lift is multiplicative on the current baseline, so it tracks this year's larger demand. Confidence High. Likely range 118-168 at 90% service level.\"\n        }\n      ],\n      \"active_lines_count\": 18,\n      \"skipped_lines_count\": 7,\n      \"pricing_tiers\": [],\n      \"default_pricing_tier_id\": null,\n      \"minimums\": {\n        \"enforce_value\": false,\n        \"enforce_quantity\": false,\n        \"minimum_value\": 1000,\n        \"minimum_quantity\": 100\n      }\n    }\n  ]\n}"}]},{"name":"Build Forecast (Single Supplier)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/build-single","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","build-single"]},"description":"Build a forecast for a single supplier. If the product count is large the request is queued as a background job and the response returns a job_id for polling; otherwise the result is returned synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse type field: sync (includes data) or async (includes job_id for status polling).\n\nThis endpoint accepts the same forecast controls as Build Forecast, including the baseline decomposition:\n- baseline_method: flat (default), recency_weighted, or damped_trend.\n- trend_damping_factor (0..1, default 0.85): damping factor phi for damped_trend; lower = more damping.\n- trend_max_growth_pct (>= 0, default 100): caps the trend lift above the flat mean (100 = may at most double it).\n- trend_half_life_days (>= 1, nullable, default 21): reserved tuning for recency_weighted.\n- exclude_detected_anomalies (default false): drop/replace resolved anomaly days before computing the baseline.\n- demand_modifiers[]: percentage, seasonal, event, override, or promo_lift (carry promo_window_id and send value 0 - the window's measured lift is applied multiplicatively to the current baseline).\n\nThe sparse-history fallback applies here too: a product with fewer than roughly 8 weeks of history or fewer than 8 orders falls back to the flat mean (trend_factor 1.0). See Build Forecast for the full field guide and the per-line inputs decomposition (base_flat, trend_factor, baseline_method, trend_capped, anomaly_days_excluded, anomaly_days_smoothed, promo_factor, promo_window_name, promo_current_baseline).\n\nenforce_minimum_order_value / enforce_minimum_order_quantity: when true, the minimums block flags whether the forecast totals fall below the supplier's minimum_purchase_order / minimum_purchase_order_quantity. Display-only here; enforcement is applied at PO creation time (POST /api/inventory-forecasting/purchase-orders).\n\nReturns 422 if too many products are found.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 1,\n  \"product_count\": 120,\n  \"supplier_ids\": [\n    1\n  ],\n  \"forecast_type\": \"with_sales_history\",\n  \"target_stock_days\": 30,\n  \"sales_history_days\": 90,\n  \"use_leadtime\": true,\n  \"use_measured_lead_time\": false,\n  \"use_moq\": true,\n  \"rounding_method\": \"round_half_up\",\n  \"baseline_method\": \"recency_weighted\",\n  \"trend_damping_factor\": 0.85,\n  \"trend_max_growth_pct\": 100,\n  \"trend_half_life_days\": 21,\n  \"exclude_detected_anomalies\": false,\n  \"product_filters\": {},\n  \"sales_filters\": {},\n  \"demand_modifiers\": [\n    {\n      \"type\": \"promo_lift\",\n      \"value\": 0,\n      \"apply_to\": \"all\",\n      \"name\": \"Re-apply Prime Day\",\n      \"product_id\": 55,\n      \"promo_window_id\": 8\n    }\n  ],\n  \"enforce_minimum_order_value\": false,\n  \"enforce_minimum_order_quantity\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/build-single","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","build-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"type\": \"sync\",\n    \"data\": {\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"active_lines_count\": 12,\n      \"skipped_lines_count\": 3,\n      \"minimums\": {\n        \"enforce_value\": false,\n        \"enforce_quantity\": false,\n        \"minimum_value\": 1000,\n        \"minimum_quantity\": 100\n      }\n    }\n  }\n}"}]},{"name":"Get Job Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/job/{jobId}/status","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","job",":jobId","status"],"variable":[{"key":"jobId","value":"abc123def456","description":"The job ID returned from build-single when dispatched async"}]},"description":"Poll the status of a background forecast job dispatched by build-single.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nStatus values: queued, processing, completed, failed.\n\nWhen status is 'completed', the result field is included with full forecast data.\n\nReturns 404 if job ID not found or has expired."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/job/{jobId}/status","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","job",":jobId","status"],"variable":[{"key":"jobId","value":"abc123def456","description":"The job ID returned from build-single when dispatched async"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"status\": \"processing\",\n    \"progress\": 45,\n    \"message\": \"Processing products 45 of 120\",\n    \"supplier_id\": 1,\n    \"product_count\": 120\n  }\n}"}]},{"name":"Get Sales History","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/sales-history","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","sales-history"]},"description":"Get aggregated sales history for products grouped by time period.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPeriod values: week, month, quarter, year (defaults to week).\n\nDate format: YYYY-MM-DD. start_date must be <= end_date.\n\nReturns an array keyed by product_id, each with periods array containing quantity and value per period.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56,\n    57\n  ],\n  \"start_date\": \"2023-10-01\",\n  \"end_date\": \"2024-10-01\",\n  \"period\": \"week\",\n  \"warehouse_id\": null,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/sales-history","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","sales-history"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 55,\n      \"periods\": [\n        {\n          \"period\": \"2024-W01\",\n          \"quantity\": 12,\n          \"value\": 150\n        },\n        {\n          \"period\": \"2024-W02\",\n          \"quantity\": 8,\n          \"value\": 100\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Sales Orders Behind a Forecast Cell","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/sales-orders?product_id=55&start_date=2023-10-01&end_date=2024-10-01&per_page=10","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","sales-orders"],"query":[{"key":"product_id","value":"55","description":"Required. Product ID to get sales orders for.","disabled":true},{"key":"start_date","value":"2023-10-01","description":"Required. Start date (YYYY-MM-DD).","disabled":true},{"key":"end_date","value":"2024-10-01","description":"Required. End date (YYYY-MM-DD).","disabled":true},{"key":"per_page","value":"10","description":"Optional. Items per page (1-100, default 10).","disabled":true}]},"description":"Get individual sales orders for a product (drill-down view). Used when clicking into a product's sales period in the forecast UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nDate format: YYYY-MM-DD. Returns paginated sales orders."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/sales-orders?product_id=55&start_date=2023-10-01&end_date=2024-10-01&per_page=10","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","sales-orders"],"query":[{"key":"product_id","value":"55","description":"Required. Product ID to get sales orders for.","disabled":true},{"key":"start_date","value":"2023-10-01","description":"Required. Start date (YYYY-MM-DD).","disabled":true},{"key":"end_date","value":"2024-10-01","description":"Required. End date (YYYY-MM-DD).","disabled":true},{"key":"per_page","value":"10","description":"Optional. Items per page (1-100, default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"order_number\": \"SO-1001\",\n      \"order_date\": \"2024-03-15\",\n      \"quantity\": 10,\n      \"unit_price\": 25,\n      \"total\": 250,\n      \"status\": \"fulfilled\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28\n}"}]},{"name":"Create Purchase Orders from Forecast","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","purchase-orders"]},"description":"Create purchase orders from forecast results. Creates a ForecastScheduleRun to track the creation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\napproval_status: draft (default) or approved — if approved, auto-approves the PO after creation.\n\nsubmit_to_supplier: if true, submits the PO to the supplier after creation.\n\nfore cast_config is optional but recommended for tracking — stores a snapshot of the config used.\n\nAlso syncs backorder coverage for all new PO lines.\n\nReturns 422 if no valid orders provided.\n\nSupplier minimum enforcement: when forecast_config.enforce_minimum_order_value or forecast_config.enforce_minimum_order_quantity is true and the order totals fall below the supplier's minimum_purchase_order or minimum_purchase_order_quantity, the request is rejected with 422 unless minimums_acknowledged is true on that order.","body":{"mode":"raw","raw":"{\n  \"orders\": [\n    {\n      \"supplier_id\": 1,\n      \"pricing_tier_id\": null,\n      \"destination_warehouse_id\": 2,\n      \"approval_status\": \"draft\",\n      \"submit_to_supplier\": false,\n      \"lines\": [\n        {\n          \"supplier_product_id\": 101,\n          \"quantity\": 50,\n          \"unit_cost\": 12.5\n        },\n        {\n          \"supplier_product_id\": 102,\n          \"quantity\": 25,\n          \"unit_cost\": null\n        }\n      ],\n      \"forecast_config\": {\n        \"supplier_ids\": [\n          1\n        ],\n        \"forecast_type\": \"sales_history\",\n        \"target_stock_days\": 30,\n        \"use_leadtime\": true,\n        \"use_measured_lead_time\": false,\n        \"use_moq\": true,\n        \"rounding_method\": \"round_half_up\",\n        \"sales_history_days\": 90,\n        \"product_filters\": {},\n        \"sales_filters\": {},\n        \"demand_modifiers\": [],\n        \"enforce_minimum_order_value\": false,\n        \"enforce_minimum_order_quantity\": false\n      },\n      \"minimums_acknowledged\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","purchase-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 500,\n      \"purchase_order_number\": \"PO-500\",\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"order_status\": \"draft\",\n      \"total_cost\": 850,\n      \"created_at\": \"2024-10-15T09:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Recalculate Costs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/recalculate-costs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","recalculate-costs"]},"description":"Recalculate supplier product costs using a different pricing tier. Used when the user switches pricing tier in the forecast UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\npriceing_tier_id: optional; pass null to use default pricing.\n\nReturns a map of supplier_product_id → new unit cost.","body":{"mode":"raw","raw":"{\n  \"supplier_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"pricing_tier_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/recalculate-costs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","recalculate-costs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"costs\": {\n      \"101\": 11.5,\n      \"102\": 8.75,\n      \"103\": 22\n    }\n  }\n}"}]},{"name":"Get Supplier Summary","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/suppliers/summary","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","suppliers","summary"]},"description":"Get a summary of suppliers with product counts. Used for lazy-loading supplier tabs in the forecast UI before running the full forecast.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nforecast_type: optional — if provided, filters product counts based on type compatibility.\n\nproduct_filters: optional filter_groups structure.","body":{"mode":"raw","raw":"{\n  \"supplier_ids\": [\n    1,\n    2,\n    3\n  ],\n  \"product_filters\": {},\n  \"forecast_type\": \"sales_history\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/suppliers/summary","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","suppliers","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"product_count\": 120,\n      \"active_product_count\": 105\n    },\n    {\n      \"supplier_id\": 2,\n      \"supplier_name\": \"Beta Parts Ltd.\",\n      \"product_count\": 45,\n      \"active_product_count\": 42\n    }\n  ]\n}"}]},{"name":"List Forecast Run Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines"],"variable":[{"key":"runId","value":"","description":"The run ID."}]},"description":"List the stored per-line breakdown for a forecast run, paginated. Each line captures the recommended quantity, confidence tier and drivers, and the inventory/sales snapshots that fed the calculation.\n\nAuthentication: Requires Bearer token.\n\nPath parameter: runId - the forecast run to read lines for.\n\nPagination: page (default 1), per_page (default 15)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines"],"variable":[{"key":"runId","value":"","description":"The run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8801,\n      \"forecast_schedule_run_id\": 512,\n      \"product_id\": 55,\n      \"supplier_id\": 1,\n      \"final_quantity\": 50,\n      \"confidence_tier\": \"high\",\n      \"confidence_drivers\": {\n        \"history_days\": 742,\n        \"selling_density\": 0.86,\n        \"coefficient_of_variation\": 0.22,\n        \"days_with_sales\": 78,\n        \"from_fallback\": false,\n        \"reason\": \"Long, dense, stable sales history\"\n      },\n      \"inputs\": {\n        \"forecast_type\": \"sales_history\",\n        \"target_stock_days\": 30,\n        \"sales_history_days\": 90,\n        \"avg_daily_sales\": 2.5,\n        \"leadtime_days\": 14\n      },\n      \"inventory_snapshot\": {\n        \"current_stock\": 10,\n        \"incoming\": 0,\n        \"allocated\": 3\n      },\n      \"sales_snapshot\": {\n        \"total_sold\": 225,\n        \"period_days\": 90,\n        \"avg_daily_sales\": 2.5\n      },\n      \"forecast_method\": \"sales_history\",\n      \"baseline_method\": \"moving_average\",\n      \"product\": {\n        \"id\": 55,\n        \"sku\": \"PROD-001\",\n        \"name\": \"Widget A\"\n      },\n      \"created_at\": \"2024-10-15T09:00:00+00:00\",\n      \"updated_at\": \"2024-10-15T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 18\n}"}]},{"name":"Persist Forecast Run Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines"],"variable":[{"key":"runId","value":"","description":"The run ID."}]},"description":"Build a forecast from the supplied configuration and store its per-line breakdown against an existing forecast run. The work runs in the background; the response returns immediately with a job reference to poll for progress.\n\nAuthentication: Requires Bearer token.\n\nPath parameter: runId - the forecast run to attach the persisted lines to.\n\nBody: configuration (required) - the full forecast configuration (forecast type, stock targets, filters, and demand modifiers) to build from.\n\nReturns 202 Accepted with a job reference (tracked_job_log_id).","body":{"mode":"raw","raw":"{\n  \"configuration\": {\n    \"supplier_ids\": [\n      1\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_stock_days\": 30,\n    \"sales_history_days\": 90,\n    \"use_leadtime\": true,\n    \"use_moq\": true,\n    \"rounding_method\": \"round_half_up\",\n    \"product_filters\": {},\n    \"sales_filters\": {},\n    \"demand_modifiers\": []\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines"],"variable":[{"key":"runId","value":"","description":"The run ID."}]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Forecast run persistence started\"\n}"}]},{"name":"Get Forecast Run Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines/{productId}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines",":productId"],"variable":[{"key":"runId","value":"","description":"The run ID."},{"key":"productId","value":"","description":"The product ID."}]},"description":"Get the stored forecast run line for a single product within a run, including the full confidence drivers and the inventory and sales snapshots taken at build time.\n\nAuthentication: Requires Bearer token.\n\nPath parameters: runId - the forecast run; productId - the product whose line to read.\n\nReturns 404 if no line exists for that run and product."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/lines/{productId}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","lines",":productId"],"variable":[{"key":"runId","value":"","description":"The run ID."},{"key":"productId","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8801,\n    \"forecast_schedule_run_id\": 512,\n    \"product_id\": 55,\n    \"supplier_id\": 1,\n    \"final_quantity\": 50,\n    \"confidence_tier\": \"high\",\n    \"confidence_drivers\": {\n      \"history_days\": 742,\n      \"selling_density\": 0.86,\n      \"coefficient_of_variation\": 0.22,\n      \"days_with_sales\": 78,\n      \"from_fallback\": false,\n      \"reason\": \"Long, dense, stable sales history\"\n    },\n    \"inputs\": {\n      \"forecast_type\": \"sales_history\",\n      \"target_stock_days\": 30,\n      \"sales_history_days\": 90,\n      \"avg_daily_sales\": 2.5,\n      \"leadtime_days\": 14\n    },\n    \"inventory_snapshot\": {\n      \"current_stock\": 10,\n      \"incoming\": 0,\n      \"allocated\": 3\n    },\n    \"sales_snapshot\": {\n      \"total_sold\": 225,\n      \"period_days\": 90,\n      \"avg_daily_sales\": 2.5\n    },\n    \"forecast_method\": \"sales_history\",\n    \"baseline_method\": \"moving_average\",\n    \"product\": {\n      \"id\": 55,\n      \"sku\": \"PROD-001\",\n      \"name\": \"Widget A\"\n    },\n    \"created_at\": \"2024-10-15T09:00:00+00:00\",\n    \"updated_at\": \"2024-10-15T09:00:00+00:00\"\n  }\n}"}]},{"name":"Get My Default Configuration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","default"]},"description":"Get the current user's default forecast configuration, if one has been set.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe demand-planning UI calls this on initial load and pre-applies the returned configuration.\n\nReturns `{ \"data\": null }` (200) when the user has no default set.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","default"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Weekly Replenishment - Supplier A\",\n    \"forecast_type\": \"sales_history\",\n    \"supplier_ids\": [\n      1\n    ],\n    \"is_default\": true,\n    \"created_at\": \"2024-10-15T10:00:00+00:00\",\n    \"updated_at\": \"2024-10-15T10:00:00+00:00\"\n  }\n}"}]},{"name":"Clear My Default Configuration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","default"]},"description":"Unset the current user's default configuration. Subsequent visits to demand planning load with a blank slate.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 204 No Content on success. Safe to call when no default is set.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations","default"]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Set as My Default Configuration","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/set-default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","set-default"],"variable":[{"key":"configuration","value":"1","description":"Configuration ID"}]},"description":"Mark this configuration as the current user's default. The default is loaded automatically in the demand-planning UI on page load.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAt most one default per user. Calling this on a different configuration replaces the previous default (no need to clear first).\n\nThe response's `is_default` flag will reflect the new state.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/configurations/{configuration}/set-default","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","configurations",":configuration","set-default"],"variable":[{"key":"configuration","value":"1","description":"Configuration ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Weekly Replenishment - Supplier A\",\n    \"forecast_type\": \"sales_history\",\n    \"supplier_ids\": [\n      1\n    ],\n    \"is_default\": true,\n    \"created_at\": \"2024-10-15T10:00:00+00:00\",\n    \"updated_at\": \"2024-10-15T10:00:00+00:00\"\n  }\n}"}]},{"name":"List Schedules","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules?is_enabled=&supplier_id=&forecast_type=&search=","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules"],"query":[{"key":"is_enabled","value":"","description":"Optional. Filter by enabled status (1 or 0).","disabled":true},{"key":"supplier_id","value":"","description":"Optional. Filter by supplier ID.","disabled":true},{"key":"forecast_type","value":"","description":"Optional. Filter by forecast type.","disabled":true},{"key":"search","value":"","description":"Optional. Search by name.","disabled":true}]},"description":"List all forecast schedules (non-paginated).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules?is_enabled=&supplier_id=&forecast_type=&search=","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules"],"query":[{"key":"is_enabled","value":"","description":"Optional. Filter by enabled status (1 or 0).","disabled":true},{"key":"supplier_id","value":"","description":"Optional. Filter by supplier ID.","disabled":true},{"key":"forecast_type","value":"","description":"Optional. Filter by forecast type.","disabled":true},{"key":"search","value":"","description":"Optional. Search by name.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Weekly Monday Run\",\n      \"is_enabled\": true,\n      \"schedule_time\": \"06:00:00\",\n      \"days_of_week\": [\n        1\n      ],\n      \"timezone\": \"America/New_York\",\n      \"forecast_configuration_id\": 1,\n      \"alert_channels\": [\n        \"email\"\n      ],\n      \"alert_email_recipients\": [\n        \"ops@company.com\"\n      ],\n      \"slack_webhook_url\": null,\n      \"auto_create_po\": true,\n      \"po_status\": \"approved\",\n      \"separate_po_by_brand\": false,\n      \"auto_receive_po\": false,\n      \"misfire_policy\": \"run_once\",\n      \"misfire_policy_label\": \"Run Once\",\n      \"starting_deadline_minutes\": 60,\n      \"last_run_at\": \"2024-10-14T06:05:00+00:00\",\n      \"next_run_at\": \"2024-10-21T10:00:00+00:00\",\n      \"created_at\": \"2024-01-15T08:00:00+00:00\",\n      \"updated_at\": \"2024-06-20T14:30:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Schedule","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules"]},"description":"Create a new forecast schedule.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nschedule_time: HH:MM:SS format.\n\ndays_of_week: array of integers 0-6 (0=Sunday, 1=Monday, ..., 6=Saturday).\n\nalert_channels: array of 'email' and/or 'slack'.\n\nPO settings:\n- auto_create_po (boolean): create POs automatically from the forecast results.\n- po_status: draft, approved, or approved_sent.\n- separate_po_by_brand (boolean): split POs per brand instead of one per supplier.\n- auto_receive_po (boolean): automatically mark the created PO as received once it has been created and approved. Ignored when po_status is draft (a draft PO cannot be received).\n\nReturns 201.","body":{"mode":"raw","raw":"{\n  \"name\": \"Weekly Monday Run\",\n  \"is_enabled\": true,\n  \"schedule_time\": \"06:00:00\",\n  \"days_of_week\": [\n    1\n  ],\n  \"timezone\": \"America/New_York\",\n  \"forecast_configuration_id\": 1,\n  \"alert_channels\": [\n    \"email\"\n  ],\n  \"alert_email_recipients\": [\n    \"ops@company.com\"\n  ],\n  \"slack_webhook_url\": null,\n  \"auto_create_po\": true,\n  \"po_status\": \"approved\",\n  \"separate_po_by_brand\": false,\n  \"auto_receive_po\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Weekly Monday Run\",\n    \"is_enabled\": true,\n    \"schedule_time\": \"06:00:00\",\n    \"days_of_week\": [\n      1\n    ],\n    \"timezone\": \"America/New_York\",\n    \"auto_create_po\": true,\n    \"po_status\": \"approved\",\n    \"separate_po_by_brand\": false,\n    \"auto_receive_po\": false,\n    \"next_run_at\": \"2024-10-21T10:00:00+00:00\",\n    \"created_at\": \"2024-10-15T09:00:00+00:00\"\n  }\n}"}]},{"name":"Get Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Get a single forecast schedule with full details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nLoads configuration, createdByUser, updatedByUser, latestRun relationships."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Weekly Monday Run\",\n    \"is_enabled\": true,\n    \"schedule_time\": \"06:00:00\",\n    \"days_of_week\": [\n      1\n    ],\n    \"timezone\": \"America/New_York\",\n    \"forecast_configuration_id\": 1,\n    \"configuration\": {\n      \"id\": 1,\n      \"name\": \"Weekly Replenishment - Supplier A\"\n    },\n    \"auto_create_po\": true,\n    \"po_status\": \"approved\",\n    \"separate_po_by_brand\": false,\n    \"auto_receive_po\": false,\n    \"last_run_at\": \"2024-10-14T06:05:00+00:00\",\n    \"next_run_at\": \"2024-10-21T10:00:00+00:00\",\n    \"latest_run\": {\n      \"id\": 50,\n      \"status\": \"completed\",\n      \"started_at\": \"2024-10-14T06:00:12+00:00\",\n      \"completed_at\": \"2024-10-14T06:05:44+00:00\"\n    }\n  }\n}"}]},{"name":"Update Schedule","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Update a forecast schedule. All fields are optional; merges with existing data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPO settings (all optional):\n- auto_create_po (boolean), po_status (draft|approved|approved_sent), separate_po_by_brand (boolean), auto_receive_po (boolean). auto_receive_po is ignored when po_status is draft.","body":{"mode":"raw","raw":"{\n  \"schedule_time\": \"07:00:00\",\n  \"days_of_week\": [\n    1,\n    4\n  ],\n  \"auto_create_po\": true,\n  \"po_status\": \"approved\",\n  \"auto_receive_po\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Weekly Monday Run\",\n    \"schedule_time\": \"07:00:00\",\n    \"days_of_week\": [\n      1,\n      4\n    ],\n    \"updated_at\": \"2024-10-16T11:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Schedule","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Delete a forecast schedule.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 204 on success."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Toggle Schedule","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/toggle","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","toggle"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Toggle a schedule's enabled/disabled status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/toggle","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","toggle"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Weekly Monday Run\",\n    \"is_enabled\": false,\n    \"updated_at\": \"2024-10-16T11:00:00+00:00\"\n  }\n}"}]},{"name":"Run Schedule Now","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/run","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","run"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Manually trigger a forecast schedule immediately.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 500 if execution fails."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/run","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","run"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"forecast_schedule_id\": 1,\n    \"status\": \"completed\",\n    \"run_type\": \"Manual\",\n    \"started_at\": \"2024-10-15T09:00:00+00:00\",\n    \"completed_at\": \"2024-10-15T09:05:00+00:00\",\n    \"duration_seconds\": 300,\n    \"results_summary\": {\n      \"suppliers_processed\": 1,\n      \"skus_to_order\": 18,\n      \"purchase_orders_created\": 1\n    }\n  }\n}"}]},{"name":"Get Schedule Runs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/runs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","runs"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Get paginated run history for a specific schedule.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/runs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","runs"],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"status\": \"completed\",\n      \"run_type\": \"Scheduled\",\n      \"started_at\": \"2024-10-14T06:00:12+00:00\",\n      \"completed_at\": \"2024-10-14T06:05:44+00:00\",\n      \"duration_seconds\": 332\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 22\n}"}]},{"name":"Get Schedule Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/activity-log?per_page=25","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","activity-log"],"query":[{"key":"per_page","value":"25","description":"Optional. Items per page (default 25).","disabled":true}],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]},"description":"Get the Spatie activity log for a specific schedule showing all changes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/{schedule}/activity-log?per_page=25","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules",":schedule","activity-log"],"query":[{"key":"per_page","value":"25","description":"Optional. Items per page (default 25).","disabled":true}],"variable":[{"key":"schedule","value":"1","description":"Schedule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"properties\": {\n        \"old\": {\n          \"is_enabled\": true\n        },\n        \"attributes\": {\n          \"is_enabled\": false\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2024-10-15T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 5\n}"}]},{"name":"Get Schedule Limits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/limits?supplier_ids[]=1&date=2024-10-15","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","limits"],"query":[{"key":"supplier_ids[]","value":"1","description":"Required. Array of supplier IDs to check limits for.","disabled":true},{"key":"date","value":"2024-10-15","description":"Optional. Date to check limits for (defaults to today).","disabled":true}]},"description":"Get supplier run limits status. Shows how many runs are scheduled for each supplier on a given date.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/limits?supplier_ids[]=1&date=2024-10-15","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","limits"],"query":[{"key":"supplier_ids[]","value":"1","description":"Required. Array of supplier IDs to check limits for.","disabled":true},{"key":"date","value":"2024-10-15","description":"Optional. Date to check limits for (defaults to today).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"runs_today\": 1,\n      \"limit\": 3,\n      \"can_run\": true\n    }\n  ]\n}"}]},{"name":"Get Schedule Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/statistics","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","statistics"]},"description":"Get aggregate statistics for all forecast schedules.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/statistics","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_schedules\": 5,\n    \"enabled_schedules\": 4,\n    \"total_runs_this_month\": 16,\n    \"successful_runs\": 15,\n    \"failed_runs\": 1\n  }\n}"}]},{"name":"Get Schedule Timeline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/timeline?start_date=2024-10-15&end_date=2024-10-22","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","timeline"],"query":[{"key":"start_date","value":"2024-10-15","description":"Optional. Start date for timeline (defaults to today).","disabled":true},{"key":"end_date","value":"2024-10-22","description":"Optional. End date for timeline (defaults to today + 7 days).","disabled":true}]},"description":"Get upcoming schedule runs for a date range.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/timeline?start_date=2024-10-15&end_date=2024-10-22","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","timeline"],"query":[{"key":"start_date","value":"2024-10-15","description":"Optional. Start date for timeline (defaults to today).","disabled":true},{"key":"end_date","value":"2024-10-22","description":"Optional. End date for timeline (defaults to today + 7 days).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"date\": \"2024-10-21\",\n      \"schedules\": [\n        {\n          \"id\": 1,\n          \"name\": \"Weekly Monday Run\",\n          \"schedule_time\": \"06:00:00\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Today's Schedules","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/today?date=2024-10-15","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","today"],"query":[{"key":"date","value":"2024-10-15","description":"Optional. Date to get schedules for (defaults to today).","disabled":true}]},"description":"Get schedules that run on the given day of the week.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedules/today?date=2024-10-15","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedules","today"],"query":[{"key":"date","value":"2024-10-15","description":"Optional. Date to get schedules for (defaults to today).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Weekly Monday Run\",\n      \"is_enabled\": true,\n      \"schedule_time\": \"06:00:00\",\n      \"next_run_at\": \"2024-10-21T10:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"List All Runs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs"]},"description":"Get all forecast runs across all schedules (both manual and scheduled), paginated. Loads the schedule, triggering user, and linked purchase orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nText search uses filter[search] (matches run ID, schedule name, or user name). Advanced filtering uses filter_groups — a base64-encoded tree of AND/OR condition groups over: id, status, run_type (manual or scheduled), started_at, purge_at, created_at, updated_at. Sortable: id, started_at, status, run_type, purge_at (default -started_at, newest first)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"forecast_schedule_id\": 1,\n      \"user_id\": 10,\n      \"is_manual_run\": false,\n      \"is_scheduled_run\": true,\n      \"run_type\": \"Scheduled\",\n      \"status\": \"completed\",\n      \"started_at\": \"2024-10-14T06:00:12+00:00\",\n      \"completed_at\": \"2024-10-14T06:05:44+00:00\",\n      \"duration_seconds\": 332,\n      \"duration_human\": \"5m 32s\",\n      \"results_summary\": {\n        \"suppliers_processed\": 1,\n        \"skus_to_order\": 18,\n        \"purchase_orders_created\": 1,\n        \"total_value\": 12500\n      },\n      \"error_message\": null,\n      \"purchase_order_ids\": [\n        500\n      ],\n      \"has_purchase_orders\": true,\n      \"schedule\": {\n        \"id\": 1,\n        \"name\": \"Weekly Monday Run\"\n      },\n      \"user\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 48\n}"}]},{"name":"Get Recent Runs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/recent?limit=5","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs","recent"],"query":[{"key":"limit","value":"5","description":"Optional. Number of recent runs to return (default 5, max 20).","disabled":true}]},"description":"Get recent runs (not paginated). Useful for dashboard widgets.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/recent?limit=5","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs","recent"],"query":[{"key":"limit","value":"5","description":"Optional. Number of recent runs to return (default 5, max 20).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"status\": \"completed\",\n      \"run_type\": \"Scheduled\",\n      \"started_at\": \"2024-10-14T06:00:12+00:00\",\n      \"completed_at\": \"2024-10-14T06:05:44+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Run Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId"],"variable":[{"key":"runId","value":"55","description":"Run ID"}]},"description":"Get full details for a single forecast run.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nLoads schedule, user, supplierRuns, linkedPurchaseOrders.\n\nReturns 404 if run not found."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId"],"variable":[{"key":"runId","value":"55","description":"Run ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"forecast_schedule_id\": 1,\n    \"status\": \"completed\",\n    \"run_type\": \"Scheduled\",\n    \"started_at\": \"2024-10-14T06:00:12+00:00\",\n    \"completed_at\": \"2024-10-14T06:05:44+00:00\",\n    \"duration_seconds\": 332,\n    \"results_summary\": {\n      \"purchase_orders_created\": 1\n    },\n    \"linked_purchase_orders\": [\n      {\n        \"id\": 500,\n        \"purchase_order_number\": \"PO-500\",\n        \"supplier_name\": \"Acme Supplier Co.\",\n        \"total_cost\": 12500,\n        \"order_status\": \"draft\"\n      }\n    ]\n  }\n}"}]},{"name":"Create Manual Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/manual","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs","manual"]},"description":"Create and persist a manual (ad-hoc) forecast run record. Called when users run forecasts manually from the UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nconfiguration_snapshot: required — stores the forecast config used.\n\nresults_summary: required — stores aggregate results.\n\npurchase_order_ids: optional — IDs of POs created from this run.\n\nReturns 201.","body":{"mode":"raw","raw":"{\n  \"configuration_snapshot\": {\n    \"supplier_ids\": [\n      1\n    ],\n    \"forecast_type\": \"sales_history\",\n    \"target_stock_days\": 30\n  },\n  \"results_summary\": {\n    \"suppliers_processed\": 1,\n    \"skus_to_order\": 18,\n    \"purchase_orders_created\": 0,\n    \"total_value\": 12500\n  },\n  \"purchase_order_ids\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/manual","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs","manual"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"is_manual_run\": true,\n    \"status\": \"completed\",\n    \"run_type\": \"Manual\",\n    \"results_summary\": {\n      \"suppliers_processed\": 1,\n      \"skus_to_order\": 18\n    },\n    \"created_at\": \"2024-10-15T09:00:00+00:00\"\n  }\n}"}]},{"name":"Link Purchase Orders to Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/link-purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","link-purchase-orders"],"variable":[{"key":"runId","value":"60","description":"Run ID"}]},"description":"Link purchase orders to an existing manual forecast run. Can only be used for manual runs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 404 if run not found. Returns 400 if not a manual run.","body":{"mode":"raw","raw":"{\n  \"purchase_order_ids\": [\n    500,\n    501\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/link-purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","link-purchase-orders"],"variable":[{"key":"runId","value":"60","description":"Run ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"purchase_order_ids\": [\n      500,\n      501\n    ],\n    \"has_purchase_orders\": true\n  }\n}"}]},{"name":"Re-run Forecast from Previous Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/rerun","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","rerun"],"variable":[{"key":"runId","value":"55","description":"Run ID"}]},"description":"Re-run a forecast using the configuration from a previous run.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFor scheduled runs with an active schedule, re-executes the schedule. For manual runs or runs whose schedule was deleted, returns the configuration_snapshot for manual re-execution.\n\nRequest body fields:\n- preview (boolean, optional, default false): When true, computes the forecast for inspection only. Skips PO creation (even when the schedule has auto_create_po enabled), skips alerts, and does not advance the schedule's next_run_at. The resulting run is recorded with results_summary.is_preview = true. Has no effect on manual runs (configuration_only path).\n\nAuthentication: Requires Bearer token.\n\nReturns 404 if run not found. Returns 500 if execution fails.","body":{"mode":"raw","raw":"{\n  \"preview\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/rerun","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","rerun"],"variable":[{"key":"runId","value":"55","description":"Run ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 56,\n    \"status\": \"completed\",\n    \"run_type\": \"Scheduled\",\n    \"results_summary\": {\n      \"is_preview\": false,\n      \"purchase_orders_created\": 1\n    }\n  }\n}"}]},{"name":"Export Forecast","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/export","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","export"]},"description":"Build a forecast and export the results to a file. Returns a download URL/filename.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nformat: csv (default) or excel.\n\ninclude_calculation_details: include the per-product calculation breakdown (default true).\n\ninclude_sales_history: include historical sales totals (default false).\n\nconfig: the same forecast settings used for the build (forecast_type, sales window, lead time, MOQ, rounding, filters, demand_modifiers, and so on).\n\nBASELINE DECOMPOSITION COLUMNS\nWith include_calculation_details on (the default), the export adds the baseline-decomposition columns that mirror each line's inputs object:\n- Baseline Method\n- Base Velocity (the flat mean before trend, base_flat)\n- Trend Factor\n- Trend Capped\n- Promo Factor\n- Promo Window\n- Promo Current Baseline\n- Anomaly Days Excluded\n- Anomaly Days Smoothed\nSend the same baseline_method / trend / exclude_detected_anomalies / demand_modifiers settings inside config that you would pass to the build endpoint so the exported numbers match.\n\ninclude_confidence (boolean, default true) adds the confidence tier/score, the prediction interval, and the plain-language rationale columns to the export.\n\nReturns 422 if too many products.","body":{"mode":"raw","raw":"{\n  \"supplier_ids\": [\n    1,\n    2\n  ],\n  \"format\": \"csv\",\n  \"include_calculation_details\": true,\n  \"include_sales_history\": false,\n  \"config\": {\n    \"forecast_type\": \"sales_history\",\n    \"sales_history_days\": 90,\n    \"target_stock_days\": 30,\n    \"use_leadtime\": true,\n    \"use_measured_lead_time\": false,\n    \"use_moq\": true,\n    \"rounding_method\": \"round_half_up\",\n    \"product_filters\": {},\n    \"sales_filters\": {},\n    \"demand_modifiers\": []\n  },\n  \"include_confidence\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/export","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"filename\": \"forecast_export_20241015_090000.csv\",\n    \"download_url\": \"/api/inventory-forecasting/download/forecast_export_20241015_090000.csv\"\n  }\n}"}]},{"name":"Download Export File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/download/{filename}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","download",":filename"],"variable":[{"key":"filename","value":"forecast_export_20241015_090000.csv","description":"Filename returned from export endpoint"}]},"description":"Download an exported forecast file. The filename is returned from the POST /export endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse is a file download (text/csv or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet).\n\nReturns 404 if file not found or has expired."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/download/{filename}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","download",":filename"],"variable":[{"key":"filename","value":"forecast_export_20241015_090000.csv","description":"Filename returned from export endpoint"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"sku,name,recommended_quantity,unit_cost,total_cost\nPROD-001,Widget A,50,12.50,625.00"}]},{"name":"Detect Demand Anomalies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/detect","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies","detect"]},"description":"Detect one-off demand anomalies (spikes, drops, and stockout gaps) in the daily sales history of one or more products. Runs synchronously, persists each flagged point, and returns them.\n\nAuthentication: Requires Bearer token.\n\nThe detector scores each day with a robust modified z-score built from the median and median absolute deviation, so a handful of extreme days cannot mask the rest. The k threshold is expressed in robust standard deviations; lower values flag more points. Each day is classified as:\n- spike_up: demand far above the local norm (often a promotion).\n- drop_down: demand far below the local norm.\n- stockout_zero: a zero-sales gap consistent with being out of stock.\n\nDetected points feed two workflows:\n1. Resolve them (see Resolve / Bulk Resolve Demand Anomalies) as excluded, smoothed, or kept_tagged. Points resolved as excluded or smoothed are the ones a build with exclude_detected_anomalies true removes or replaces before computing the baseline, de-contaminating the velocity.\n2. Cluster spike_up points into candidate promotions via Suggest Promo Windows. A spike can also be linked to a promo_window_id when resolved as kept_tagged.\n\nBody fields:\n- product_ids (required): array of product IDs, at least one.\n- k (optional): sensitivity threshold in robust standard deviations, 0.1-20 (default 3.0). Lower flags more points.\n- start_date / end_date (optional, YYYY-MM-DD): detection window. Defaults to the trailing 365 days.\n- sales_filters (optional): object narrowing which sales feed the series.\n- warehouse_id (optional): restrict the series to one warehouse.\n\nEach flagged point has a direction of spike_up, drop_down, or stockout_zero and a status of detected until it is resolved.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56\n  ],\n  \"k\": 3,\n  \"start_date\": \"2023-07-01\",\n  \"end_date\": \"2024-07-01\",\n  \"sales_filters\": {},\n  \"warehouse_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/detect","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies","detect"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 55,\n      \"anomaly_date\": \"2024-07-04\",\n      \"direction\": \"spike_up\",\n      \"actual_value\": 145,\n      \"expected_value\": 22,\n      \"residual_score\": 8.7,\n      \"status\": \"detected\",\n      \"is_stockout\": false\n    },\n    {\n      \"product_id\": 55,\n      \"anomaly_date\": \"2024-09-02\",\n      \"direction\": \"stockout_zero\",\n      \"actual_value\": 0,\n      \"expected_value\": 18,\n      \"residual_score\": 5.1,\n      \"status\": \"detected\",\n      \"is_stockout\": true\n    }\n  ]\n}"}]},{"name":"List Demand Anomalies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies?product_id=55","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies"],"query":[{"key":"product_id","value":"55","description":"Required. Product to list anomalies for.","disabled":true}]},"description":"List a product's detected demand anomalies, most recent first, optionally scoped to a single resolution status.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- product_id (required): the product to list anomalies for.\n- status (optional): filter by resolution status.\n  - detected: flagged, not yet actioned.\n  - excluded: dropped from the baseline (a build with exclude_detected_anomalies true removes these days).\n  - smoothed: replaced with the expected value before the baseline is computed.\n  - kept_tagged: kept in the baseline, optionally attributed to a promotion via promo_window_id."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies?product_id=55","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies"],"query":[{"key":"product_id","value":"55","description":"Required. Product to list anomalies for.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3001,\n      \"product_id\": 55,\n      \"anomaly_date\": \"2024-07-04\",\n      \"direction\": \"spike_up\",\n      \"actual_value\": 145,\n      \"expected_value\": 22,\n      \"residual_score\": 8.7,\n      \"method\": \"mad_zscore\",\n      \"status\": \"detected\",\n      \"promo_window_id\": null,\n      \"resolved_by\": null,\n      \"resolved_at\": null\n    }\n  ]\n}"}]},{"name":"Resolve Demand Anomaly","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/{id}/resolve","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies",":id","resolve"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Record a decision for a single demand anomaly so future forecasts treat the point correctly.\n\nAuthentication: Requires Bearer token.\n\nHow each status affects a subsequent build (only when that build sets exclude_detected_anomalies true):\n- excluded: drop the day from the history before the baseline is computed. Use for a true one-off that should not count.\n- smoothed: replace the day with its expected (model) value, keeping the day but removing the spike/gap. Use when the day should contribute a normal amount.\n- kept_tagged: keep the day as-is, optionally attributed to a promotion via promo_window_id. Excluded and smoothed days are the ones anomaly cleansing acts on; kept_tagged days stay in the baseline. detected resets the point to unresolved.\n\nPath parameter: id - the anomaly to resolve.\n\nBody fields:\n- status (required): excluded, smoothed, kept_tagged, or detected.\n- promo_window_id (optional): link the point to a promo window when kept_tagged, associating the spike with a known promotion.","body":{"mode":"raw","raw":"{\n  \"status\": \"kept_tagged\",\n  \"promo_window_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/{id}/resolve","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies",":id","resolve"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3001,\n    \"product_id\": 55,\n    \"anomaly_date\": \"2024-07-04\",\n    \"direction\": \"spike_up\",\n    \"actual_value\": 145,\n    \"expected_value\": 22,\n    \"residual_score\": 8.7,\n    \"method\": \"mad_zscore\",\n    \"status\": \"kept_tagged\",\n    \"promo_window_id\": 12,\n    \"resolved_by\": 10,\n    \"resolved_at\": \"2024-10-15T09:30:00+00:00\"\n  }\n}"}]},{"name":"Bulk Resolve Demand Anomalies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/bulk-resolve","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies","bulk-resolve"]},"description":"Apply the same resolution decision to many demand anomalies at once - the fast path after Detect Demand Anomalies. Unknown IDs are skipped; the response reports how many were actually updated.\n\nAuthentication: Requires Bearer token.\n\nStatus meanings match Resolve Demand Anomaly: excluded (drop from baseline), smoothed (replace with expected value), kept_tagged (keep, optionally tagged to a promotion), detected (reset). Only excluded and smoothed points are removed/replaced when a build runs with exclude_detected_anomalies true.\n\nBody fields:\n- anomaly_ids (required): array of anomaly IDs, at least one.\n- status (required): excluded, smoothed, kept_tagged, or detected.\n- promo_window_id (optional): link the points to a promo window when kept_tagged.","body":{"mode":"raw","raw":"{\n  \"anomaly_ids\": [\n    3001,\n    3002,\n    3003\n  ],\n  \"status\": \"excluded\",\n  \"promo_window_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/anomalies/bulk-resolve","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","anomalies","bulk-resolve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"resolved_count\": 3\n  }\n}"}]},{"name":"List Promo Windows","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows"]},"description":"List all promo windows, including any realised lift (measured_lift_pct) and post-promo dip (post_promo_dip_pct) already measured for each. Use a window's id as the promo_window_id of a promo_lift demand modifier to re-apply its lift on a build.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Black Friday 2024\",\n      \"start_date\": \"2024-11-25\",\n      \"end_date\": \"2024-11-30\",\n      \"order_tag\": \"black-friday\",\n      \"product_scope\": [\n        55,\n        56\n      ],\n      \"channel_scope\": [\n        \"shopify\"\n      ],\n      \"recurrence\": \"annual\",\n      \"measured_lift_pct\": 34.78,\n      \"post_promo_dip_pct\": -11.2,\n      \"measured_at\": \"2024-12-05T08:00:00+00:00\",\n      \"created_by\": 10,\n      \"created_at\": \"2024-11-01T12:00:00+00:00\",\n      \"updated_at\": \"2024-12-05T08:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Promo Window","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows"]},"description":"Create a promo window - a named date range, optionally scoped to an order tag, a set of products, and sales channels. A promo window is the anchor for measuring a promotion's demand lift and later re-applying it.\n\nAuthentication: Requires Bearer token.\n\nTypical flow:\n1. Create the window over the promotion's date range (optionally scoped by order_tag, product_scope, channel_scope).\n2. Call Measure Promo Lift for a product to compute the realised in-window lift and the post-promo dip; the measured lift is stored on the window.\n3. Reference the window from a build request as a demand_modifiers entry of type promo_lift (promo_window_id). The stored lift is applied MULTIPLICATIVELY to the current baseline, so a window measured last year automatically re-scales to this year's larger baseline.\n\nBody fields:\n- name (required): label for the window, up to 255 characters.\n- start_date (required, YYYY-MM-DD): must be on or before end_date.\n- end_date (required, YYYY-MM-DD): must be on or after start_date.\n- order_tag (optional): the order tag that marks orders belonging to this promotion.\n- recurrence (optional): one_off (a single-date promotion) or annual (repeats on the same dates each year, so its lift can be re-applied to the next occurrence). Default one_off.\n- product_scope (optional): array of product IDs the window applies to.\n- channel_scope (optional): array of sales channels the window applies to.","body":{"mode":"raw","raw":"{\n  \"name\": \"Black Friday 2024\",\n  \"start_date\": \"2024-11-25\",\n  \"end_date\": \"2024-11-30\",\n  \"order_tag\": \"black-friday\",\n  \"recurrence\": \"annual\",\n  \"product_scope\": [\n    55,\n    56\n  ],\n  \"channel_scope\": [\n    \"shopify\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Black Friday 2024\",\n    \"start_date\": \"2024-11-25\",\n    \"end_date\": \"2024-11-30\",\n    \"order_tag\": \"black-friday\",\n    \"product_scope\": [\n      55,\n      56\n    ],\n    \"channel_scope\": [\n      \"shopify\"\n    ],\n    \"recurrence\": \"annual\",\n    \"measured_lift_pct\": null,\n    \"post_promo_dip_pct\": null,\n    \"measured_at\": null,\n    \"created_by\": 10,\n    \"created_at\": \"2024-11-01T12:00:00+00:00\",\n    \"updated_at\": \"2024-12-05T08:00:00+00:00\"\n  }\n}"}]},{"name":"Suggest Promo Windows","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/suggest","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows","suggest"]},"description":"Suggest candidate promo windows for a product by clustering its detected upward demand spikes into contiguous date ranges, so a promotion can be confirmed instead of typed by hand.\n\nAuthentication: Requires Bearer token.\n\nThis consumes the same spike_up points produced by Detect Demand Anomalies: it clusters unresolved upward spikes into candidate date ranges. Downward and stockout anomalies are never suggested. Candidates are ranked by peak spike severity and capped at 10. A confirmed suggestion can be created as a promo window (Create Promo Window), measured (Measure Promo Lift), and then re-applied on a future build as a promo_lift demand modifier.\n\nBody fields:\n- product_id (required): the product to analyse.\n- min_gap_days (optional): a gap larger than this many days splits two spike clusters into separate windows, 0-60 (default 3).\n- lookback_days (optional): how far back to scan for spikes, 1-1095 (default 365).\n\nEach suggestion reports the cluster's start_date and end_date, the peak spike score, the total excess units above expectation, the number of flagged days, and whether an existing promo window already overlaps the range.","body":{"mode":"raw","raw":"{\n  \"product_id\": 55,\n  \"min_gap_days\": 3,\n  \"lookback_days\": 365\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/suggest","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows","suggest"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"start_date\": \"2024-11-22\",\n      \"end_date\": \"2024-11-29\",\n      \"peak_residual_score\": 6.1,\n      \"total_excess_units\": 420,\n      \"day_count\": 8,\n      \"already_has_window\": false\n    },\n    {\n      \"start_date\": \"2024-07-03\",\n      \"end_date\": \"2024-07-06\",\n      \"peak_residual_score\": 4.2,\n      \"total_excess_units\": 180,\n      \"day_count\": 4,\n      \"already_has_window\": true\n    }\n  ]\n}"}]},{"name":"Get Promo Window","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get a single promo window by ID.\n\nAuthentication: Requires Bearer token.\n\nPath parameter: id - the promo window to read.\n\nReturns 404 if the promo window does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Black Friday 2024\",\n    \"start_date\": \"2024-11-25\",\n    \"end_date\": \"2024-11-30\",\n    \"order_tag\": \"black-friday\",\n    \"product_scope\": [\n      55,\n      56\n    ],\n    \"channel_scope\": [\n      \"shopify\"\n    ],\n    \"recurrence\": \"annual\",\n    \"measured_lift_pct\": 34.78,\n    \"post_promo_dip_pct\": -11.2,\n    \"measured_at\": \"2024-12-05T08:00:00+00:00\",\n    \"created_by\": 10,\n    \"created_at\": \"2024-11-01T12:00:00+00:00\",\n    \"updated_at\": \"2024-12-05T08:00:00+00:00\"\n  }\n}"}]},{"name":"Update Promo Window","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Update a promo window. A full representation is expected, mirroring create.\n\nAuthentication: Requires Bearer token.\n\nEditing the date range, order_tag, or scope changes what a future Measure Promo Lift call will consider; re-measure afterwards so any promo_lift demand modifier that references this window applies the refreshed lift. Because the lift is applied multiplicatively to the current baseline, the same window keeps re-scaling as demand grows.\n\nPath parameter: id - the promo window to update.\n\nBody fields:\n- name (required): label for the window, up to 255 characters.\n- start_date (required, YYYY-MM-DD): must be on or before end_date.\n- end_date (required, YYYY-MM-DD): must be on or after start_date.\n- order_tag (optional): the order tag that marks orders belonging to this promotion.\n- recurrence (optional): one_off or annual (default one_off).\n- product_scope (optional): array of product IDs the window applies to.\n- channel_scope (optional): array of sales channels the window applies to.\n\nReturns 404 if the promo window does not exist.","body":{"mode":"raw","raw":"{\n  \"name\": \"Black Friday 2024\",\n  \"start_date\": \"2024-11-25\",\n  \"end_date\": \"2024-11-30\",\n  \"order_tag\": \"black-friday\",\n  \"recurrence\": \"annual\",\n  \"product_scope\": [\n    55,\n    56\n  ],\n  \"channel_scope\": [\n    \"shopify\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Black Friday 2024\",\n    \"start_date\": \"2024-11-25\",\n    \"end_date\": \"2024-11-30\",\n    \"order_tag\": \"black-friday\",\n    \"product_scope\": [\n      55,\n      56\n    ],\n    \"channel_scope\": [\n      \"shopify\"\n    ],\n    \"recurrence\": \"annual\",\n    \"measured_lift_pct\": 34.78,\n    \"post_promo_dip_pct\": -11.2,\n    \"measured_at\": \"2024-12-05T08:00:00+00:00\",\n    \"created_by\": 10,\n    \"created_at\": \"2024-11-01T12:00:00+00:00\",\n    \"updated_at\": \"2024-12-05T08:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Promo Window","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Delete a promo window.\n\nAuthentication: Requires Bearer token.\n\nPath parameter: id - the promo window to delete.\n\nReturns 204 on success, or 404 if the promo window does not exist."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Measure Promo Lift","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}/measure","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id","measure"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Measure the realised demand lift during a promo window and the dip in the days after it, for one product. The result is persisted onto the window and returned alongside suggested forward demand modifiers for next year's occurrence.\n\nAuthentication: Requires Bearer token.\n\nThe measured lift is what a promo_lift demand modifier applies at build time. It is reported as a percentage but is applied MULTIPLICATIVELY to whatever the current baseline is, so it stays correct as demand grows - a promotion that lifted demand 85% last year still lifts this year's larger baseline by 85%. Re-measure whenever you want the applied lift refreshed (for example after editing the window or accruing more sales).\n\nPath parameter: id - the promo window to measure.\n\nBody fields:\n- product_id (required): the product to measure.\n- dip_days (optional): number of days after the window to measure the post-promo dip, 1-365 (default 14).\n- sales_filters (optional): object narrowing which sales are counted.\n- warehouse_id (optional): restrict the measurement to one warehouse.\n\nThe response reports measured_lift_pct, post_promo_dip_pct, the in-window and expected daily rates, and suggested_modifiers - event demand modifiers pre-dated to the same window one year forward, ready to add to a build or configuration.","body":{"mode":"raw","raw":"{\n  \"product_id\": 55,\n  \"dip_days\": 14,\n  \"sales_filters\": {},\n  \"warehouse_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/promo-windows/{id}/measure","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","promo-windows",":id","measure"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"measured_lift_pct\": 34.7821,\n    \"post_promo_dip_pct\": -11.2,\n    \"in_window_daily\": 8.5,\n    \"expected_daily\": 6.3,\n    \"suggested_modifiers\": [\n      {\n        \"type\": \"event\",\n        \"value\": 35,\n        \"apply_to\": \"all\",\n        \"name\": \"Black Friday 2024 lift\",\n        \"period_key\": null,\n        \"start_date\": \"2025-11-25\",\n        \"end_date\": \"2025-11-30\",\n        \"product_id\": null\n      },\n      {\n        \"type\": \"event\",\n        \"value\": -11,\n        \"apply_to\": \"all\",\n        \"name\": \"Black Friday 2024 post-promo dip\",\n        \"period_key\": null,\n        \"start_date\": \"2025-12-01\",\n        \"end_date\": \"2025-12-14\",\n        \"product_id\": null\n      }\n    ]\n  }\n}"}]},{"name":"List Forecast Accuracy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/accuracy?product_id=55","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","accuracy"],"query":[{"key":"product_id","value":"55","description":"Required. Product to list accuracy history for.","disabled":true}]},"description":"List a product's forecast-accuracy history across runs, paginated. Each entry compares a run's projected demand against the actual quantity sold in the evaluation window.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- product_id (required): the product to read accuracy for.\n- page (default 1), per_page (default 15).\n\nEach entry reports ape (absolute percentage error), signed_bias with a bias_direction of over, under, or none, a tracking_signal, and is_drifting when the forecast is trending off."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/accuracy?product_id=55","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","accuracy"],"query":[{"key":"product_id","value":"55","description":"Required. Product to list accuracy history for.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 700,\n      \"forecast_schedule_run_id\": 512,\n      \"product_id\": 55,\n      \"product_link\": \"/products/55\",\n      \"product_sku\": \"PROD-001\",\n      \"product_name\": \"Widget A\",\n      \"evaluation_start\": \"2024-09-01\",\n      \"evaluation_end\": \"2024-09-30\",\n      \"forecast_quantity\": 75,\n      \"actual_quantity\": 68,\n      \"ape\": 10.29,\n      \"signed_bias\": 7,\n      \"bias_direction\": \"over\",\n      \"tracking_signal\": 1.8,\n      \"is_drifting\": false,\n      \"computed_at\": \"2024-10-15T09:00:00+00:00\",\n      \"created_at\": \"2024-10-15T09:00:00+00:00\",\n      \"updated_at\": \"2024-10-15T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 6\n}"}]},{"name":"Evaluate Forecast Accuracy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/accuracy/evaluate","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","accuracy","evaluate"]},"description":"Backtest a completed forecast run by comparing its projected demand against actual sales, and store the resulting accuracy metrics per product. The work runs in the background; the response returns immediately with a job reference to poll for progress.\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- run_id (required): the forecast run to evaluate.\n- eval_start (optional, YYYY-MM-DD): start of the evaluation window; must be on or before eval_end.\n- eval_end (optional, YYYY-MM-DD): end of the evaluation window.\n\nReturns a job reference (tracked_job_log_id).","body":{"mode":"raw","raw":"{\n  \"run_id\": 512,\n  \"eval_start\": \"2024-09-01\",\n  \"eval_end\": \"2024-09-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/accuracy/evaluate","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","accuracy","evaluate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Forecast accuracy evaluation started.\"\n}"}]},{"name":"Get Run Forecast Accuracy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/accuracy","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","accuracy"],"variable":[{"key":"runId","value":"","description":"The run ID."}]},"description":"Get all forecast-accuracy metrics computed for a single forecast run - one entry per evaluated product.\n\nAuthentication: Requires Bearer token.\n\nPath parameter: runId - the forecast run to read accuracy for.\n\nEach entry reports ape, signed_bias with a bias_direction, a tracking_signal, and is_drifting. Returns an empty list if the run has not been evaluated yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/schedule-runs/{runId}/accuracy","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","schedule-runs",":runId","accuracy"],"variable":[{"key":"runId","value":"","description":"The run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 700,\n      \"forecast_schedule_run_id\": 512,\n      \"product_id\": 55,\n      \"product_link\": \"/products/55\",\n      \"product_sku\": \"PROD-001\",\n      \"product_name\": \"Widget A\",\n      \"evaluation_start\": \"2024-09-01\",\n      \"evaluation_end\": \"2024-09-30\",\n      \"forecast_quantity\": 75,\n      \"actual_quantity\": 68,\n      \"ape\": 10.29,\n      \"signed_bias\": 7,\n      \"bias_direction\": \"over\",\n      \"tracking_signal\": 1.8,\n      \"is_drifting\": false,\n      \"computed_at\": \"2024-10-15T09:00:00+00:00\",\n      \"created_at\": \"2024-10-15T09:00:00+00:00\",\n      \"updated_at\": \"2024-10-15T09:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Measured Lead Time Coverage Summary","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/summary","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage","summary"]},"description":"Coverage counts and averages for the measured (purchase-order-derived) lead times available across a forecast scope. Answers, for the selected suppliers and optional destination warehouse, how many supplier-products have a measured lead time versus fall back to the configured value.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- supplier_ids (required, integer array) — suppliers in scope.\n- destination_warehouse_id (optional, integer) — when set, the destination-scoped measured actual is preferred over the blended per-supplier-product average.\n- product_filters (optional, object) — filter_groups structure to narrow the products in scope.","body":{"mode":"raw","raw":"{\n  \"supplier_ids\": [\n    1,\n    2,\n    3\n  ],\n  \"destination_warehouse_id\": 4,\n  \"product_filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/summary","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_products\": 310,\n    \"with_measured\": 142,\n    \"falls_back\": 168,\n    \"avg_measured_days\": 34,\n    \"avg_on_time_pct\": 78\n  }\n}"}]},{"name":"List Measured Lead Time Coverage Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/products","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage","products"]},"description":"Paginated per-product breakdown of configured versus measured lead time for a forecast scope, including which value would drive the forecast when measured lead times are enabled.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- supplier_ids (required, integer array) — suppliers in scope.\n- destination_warehouse_id (optional, integer) — prefers the destination-scoped measured actual.\n- product_filters (optional, object) — filter_groups structure to narrow the products.\n- search (optional, string) — matches product SKU or name.\n- measured (optional, string) — one of 'has_measured' or 'falls_back' to only return products that do or do not have measured data.\n- page (optional, integer, default 1).\n- per_page (optional, integer, default 10, max 100).\n\nResponse fields per product:\n- configured_lead_time / configured_source — the configured lead time and where it comes from.\n- measured_avg_days, measured_sample_size, measured_reliability_pct, measured_variance — the measured evidence (null when none exists).\n- measured_scope — 'warehouse' (destination-scoped), 'blended' (across all warehouses), or null.\n- resolved_lead_time / resolved_source / uses_measured — the value that would drive the forecast and whether measured data won.","body":{"mode":"raw","raw":"{\n  \"supplier_ids\": [\n    1,\n    2,\n    3\n  ],\n  \"destination_warehouse_id\": 4,\n  \"product_filters\": {},\n  \"search\": \"widget\",\n  \"measured\": \"has_measured\",\n  \"page\": 1,\n  \"per_page\": 10\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/products","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage","products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"supplier_product_id\": 8842,\n      \"product_id\": 55,\n      \"sku\": \"WIDGET-BLK\",\n      \"name\": \"Widget - Black\",\n      \"supplier_id\": 1,\n      \"supplier_name\": \"Acme Supplier Co.\",\n      \"configured_lead_time\": 30,\n      \"configured_source\": \"product\",\n      \"configured_source_label\": \"Product Override\",\n      \"measured_avg_days\": 19,\n      \"measured_sample_size\": 11,\n      \"measured_reliability_pct\": 91,\n      \"measured_variance\": 2.1,\n      \"measured_scope\": \"warehouse\",\n      \"measured_computed_at\": \"2026-07-20T02:00:00+00:00\",\n      \"has_measured\": true,\n      \"resolved_lead_time\": 19,\n      \"resolved_source\": \"measured\",\n      \"resolved_source_label\": \"Measured Actual\",\n      \"uses_measured\": true,\n      \"product_route\": \"/products/55\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 15,\n  \"per_page\": 10,\n  \"total\": 142,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Measured Lead Time Contributing Purchase Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/{supplierProduct}/purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage",":supplierProduct","purchase-orders"],"variable":[{"key":"supplierProduct","value":"8842","description":"Supplier-product id whose measured lead time you want the evidence for."}]},"description":"The closed purchase orders a supplier-product's measured lead time is derived from: the same closed-PO population (last 12 months, with submitted, received and estimated delivery dates present) that the measured average is computed over. Each row shows the submitted-to-received span and whether it landed on or before its estimated delivery date.\n\nAuthentication: Requires Bearer token.\n\nPath parameter:\n- supplierProduct (required, integer) — the supplier-product id.\n\nQuery parameter:\n- warehouse_id (optional, integer) — restrict to POs delivered to a specific destination warehouse.\n\nOrdered by received date, most recent first."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-forecasting/lead-time-coverage/{supplierProduct}/purchase-orders","host":["{{baseUrl}}"],"path":["api","inventory-forecasting","lead-time-coverage",":supplierProduct","purchase-orders"],"variable":[{"key":"supplierProduct","value":"8842","description":"Supplier-product id whose measured lead time you want the evidence for."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_id\": 1042,\n      \"purchase_order_number\": \"PO-1042\",\n      \"submitted_at\": \"2026-03-03T09:00:00+00:00\",\n      \"received_at\": \"2026-03-22T14:30:00+00:00\",\n      \"estimated_delivery_date\": \"2026-03-24T00:00:00+00:00\",\n      \"lead_time_days\": 19,\n      \"on_time\": true,\n      \"late_days\": 0,\n      \"destination_warehouse_id\": 4,\n      \"destination_warehouse_name\": \"Main Warehouse\",\n      \"link_route\": \"/orders/purchase-orders/1042\"\n    },\n    {\n      \"purchase_order_id\": 1051,\n      \"purchase_order_number\": \"PO-1051\",\n      \"submitted_at\": \"2026-03-17T09:00:00+00:00\",\n      \"received_at\": \"2026-04-09T16:00:00+00:00\",\n      \"estimated_delivery_date\": \"2026-04-06T00:00:00+00:00\",\n      \"lead_time_days\": 23,\n      \"on_time\": false,\n      \"late_days\": 3,\n      \"destination_warehouse_id\": 4,\n      \"destination_warehouse_name\": \"Main Warehouse\",\n      \"link_route\": \"/orders/purchase-orders/1051\"\n    }\n  ]\n}"}]},{"name":"Get Inventory Aging Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging?view=product_summary","host":["{{baseUrl}}"],"path":["api","inventory-aging"],"query":[{"key":"view","value":"product_summary","description":"product_summary (one row per product, enriched) or fifo_detail (raw cost layers). Default fifo_detail","disabled":true}]},"description":"Paginated inventory aging report.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTwo views:\n- `view=product_summary` — one row per product aggregated across its FIFO layers, enriched with listings, sales velocity (7/14/30/90 days), days of supply, channel sales, margin, bracket-scoped `aged_value` (dollars in the active bracket, or 181+ days when no bracket filter is set), an estimated 90-day `holding_cost_90d`, a rule-based `suggested_action`, and the recorded `action` state.\n- `view=fifo_detail` — raw cost layers (one row per layer) with age bracket, layer date, source document and value.\n\nSorting (product summary): pass `sort_by` + `sort_dir`; sorting runs server-side over the full filtered dataset. Allowed sorts: sku, total_quantity, avg_unit_cost, total_value, aged_value, max_days_old, holding_cost, velocity_30d.\n\nAction scope (product summary): `action_scope` partitions rows by their recorded action state; metrics and distribution deliberately ignore it so totals keep counting accepted/resolved stock.\n\nAll other filters apply identically to this endpoint, the metrics, the distribution and the CSV export. `sales_period` governs every sales-window filter (has_sales, channel sold-on / no-sales-on, margin)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-aging?view=product_summary","host":["{{baseUrl}}"],"path":["api","inventory-aging"],"query":[{"key":"view","value":"product_summary","description":"product_summary (one row per product, enriched) or fifo_detail (raw cost layers). Default fifo_detail","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 1935,\n      \"sku\": \"SZ909\",\n      \"product_name\": \"Brand New Hayg OEM Fuel Pump\",\n      \"brand_name\": \"Hayg\",\n      \"brand_id\": 12,\n      \"supplier_name\": \"Hayg Distribution\",\n      \"age_bracket\": \"365+\",\n      \"max_days_old\": 412,\n      \"total_quantity\": 115,\n      \"avg_unit_cost\": 13.51,\n      \"total_value\": 1553.2,\n      \"warehouses\": [\n        \"FBA US\",\n        \"ShipMyOrders Warehouse\"\n      ],\n      \"aged_value\": 1553.2,\n      \"aged_quantity\": 115,\n      \"aged_value_label\": \"181+ days\",\n      \"holding_cost_90d\": 97.08,\n      \"listings\": [\n        {\n          \"id\": 881,\n          \"sales_channel_name\": \"AMZ partusa\",\n          \"integration_name\": \"amazon\",\n          \"listing_price\": 39.95,\n          \"default_tier_price\": 39.95,\n          \"discount_percentage\": 0,\n          \"listing_sku\": \"SZ909-FBA\",\n          \"listing_type\": null,\n          \"listing_status\": null,\n          \"condition\": null\n        }\n      ],\n      \"listing_count\": 1,\n      \"has_listings\": true,\n      \"all_full_price\": true,\n      \"has_fba_layers\": true,\n      \"sold_7d\": 0,\n      \"sold_14d\": 0,\n      \"sold_30d\": 0,\n      \"sold_90d\": 5,\n      \"days_of_supply\": null,\n      \"channel_sales_30d\": [],\n      \"total_channel_sales_30d\": 0,\n      \"total_channel_revenue_30d\": 0,\n      \"default_retail_price\": 39.95,\n      \"avg_selling_price_30d\": null,\n      \"avg_cogs_per_unit_30d\": null,\n      \"total_revenue_30d\": null,\n      \"total_cogs_30d\": null,\n      \"margin_pct_30d\": null,\n      \"suggested_action\": {\n        \"action\": \"expand_channels\",\n        \"label\": \"Expand channels\",\n        \"reason\": \"Listed on 1 of 4 active channels\"\n      },\n      \"action\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 8,\n  \"per_page\": 50,\n  \"total\": 382,\n  \"from\": 1,\n  \"to\": 50\n}"}]},{"name":"Get Inventory Aging Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/metrics","host":["{{baseUrl}}"],"path":["api","inventory-aging","metrics"]},"description":"Summary metrics for the aging report: total inventory value at cost, value-weighted average age, product counts (total, slow-moving 180+, dead stock 365+), value at risk (181+ days), and per-bracket value/quantity/percentage breakdowns.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nHonors every filter the report honors (warehouse, brand, supplier, search, quantity, age bracket, listings, sales, channels, margin), so these figures always describe the same population as the filtered report. `action_scope` is deliberately ignored — accepted/resolved stock stays counted."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-aging/metrics","host":["{{baseUrl}}"],"path":["api","inventory-aging","metrics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_inventory_value\": 716964.57,\n  \"average_age\": 279,\n  \"total_skus\": 569,\n  \"slow_moving_skus\": 382,\n  \"dead_stock_skus\": 177,\n  \"value_at_risk\": 366573.77,\n  \"value_by_age_bracket\": {\n    \"0-30\": 249322.11,\n    \"31-60\": 54210.09,\n    \"61-90\": 46858.6,\n    \"91-180\": 101243.4,\n    \"181-365\": 158218.9,\n    \"365+\": 208354.87\n  },\n  \"quantity_by_age_bracket\": {\n    \"0-30\": 1204,\n    \"31-60\": 310,\n    \"61-90\": 280,\n    \"91-180\": 642,\n    \"181-365\": 801,\n    \"365+\": 1388\n  },\n  \"percentage_by_age_bracket\": {\n    \"0-30\": 34.8,\n    \"31-60\": 7.6,\n    \"61-90\": 6.5,\n    \"91-180\": 14.1,\n    \"181-365\": 22.1,\n    \"365+\": 29.1\n  }\n}"}]},{"name":"Get Inventory Aging Distribution","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/distribution","host":["{{baseUrl}}"],"path":["api","inventory-aging","distribution"]},"description":"Per-bracket distribution for the value-at-risk funnel: quantity, value, percentage of total value and a display color per age bracket. Always returns all six brackets (zeroed when empty).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nHonors the same filters as the report and metrics, so the funnel always reconciles with both."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-aging/distribution","host":["{{baseUrl}}"],"path":["api","inventory-aging","distribution"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"age_bracket\": \"0-30\",\n    \"quantity\": 1204,\n    \"value\": 249322.11,\n    \"percentage\": 34.8,\n    \"color\": \"#4CAF50\"\n  },\n  {\n    \"age_bracket\": \"31-60\",\n    \"quantity\": 310,\n    \"value\": 54210.09,\n    \"percentage\": 7.6,\n    \"color\": \"#8BC34A\"\n  },\n  {\n    \"age_bracket\": \"61-90\",\n    \"quantity\": 280,\n    \"value\": 46858.6,\n    \"percentage\": 6.5,\n    \"color\": \"#FFEB3B\"\n  },\n  {\n    \"age_bracket\": \"91-180\",\n    \"quantity\": 642,\n    \"value\": 101243.4,\n    \"percentage\": 14.1,\n    \"color\": \"#FF9800\"\n  },\n  {\n    \"age_bracket\": \"181-365\",\n    \"quantity\": 801,\n    \"value\": 158218.9,\n    \"percentage\": 22.1,\n    \"color\": \"#FF5722\"\n  },\n  {\n    \"age_bracket\": \"365+\",\n    \"quantity\": 1388,\n    \"value\": 208354.87,\n    \"percentage\": 29.1,\n    \"color\": \"#F44336\"\n  }\n]"}]},{"name":"Get Inventory Aging Trend","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/trend","host":["{{baseUrl}}"],"path":["api","inventory-aging","trend"]},"description":"Aged-value trend series from nightly snapshots: per-bracket inventory value and quantity per snapshot date, for charting whether aged value is shrinking over time.\n\nWithout `warehouse_id` the tenant-wide rollup series is returned. Snapshots are recorded nightly going forward — history begins the day the feature is enabled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-aging/trend","host":["{{baseUrl}}"],"path":["api","inventory-aging","trend"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"snapshot_date\": \"2026-07-12\",\n      \"age_bracket\": \"181-365\",\n      \"total_value\": 158218.9,\n      \"total_quantity\": 801\n    },\n    {\n      \"snapshot_date\": \"2026-07-12\",\n      \"age_bracket\": \"365+\",\n      \"total_value\": 208354.87,\n      \"total_quantity\": 1388\n    },\n    {\n      \"snapshot_date\": \"2026-07-13\",\n      \"age_bracket\": \"181-365\",\n      \"total_value\": 155102.4,\n      \"total_quantity\": 788\n    },\n    {\n      \"snapshot_date\": \"2026-07-13\",\n      \"age_bracket\": \"365+\",\n      \"total_value\": 206220.11,\n      \"total_quantity\": 1371\n    }\n  ]\n}"}]},{"name":"Export Inventory Aging to CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/export?view=product_summary","host":["{{baseUrl}}"],"path":["api","inventory-aging","export"],"query":[{"key":"view","value":"product_summary","description":"product_summary (one row per product, enriched) or fifo_detail (raw cost layers). Default fifo_detail","disabled":true}]},"description":"Stream the aging report as a CSV download. `view=product_summary` exports enriched product rows (including aged value, holding cost, suggested action and recorded action state); the default view exports raw FIFO layer detail.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nHonors every report filter plus `sort_by`/`sort_dir` and `action_scope`, so the file matches what the filtered report shows. Response is a `text/csv` attachment, not JSON."}},{"name":"List Sales Channels (Aging Report Filter Values)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/sales-channels","host":["{{baseUrl}}"],"path":["api","inventory-aging","sales-channels"]},"description":"Sales channels that have had sales in the last 90 days — the option list for the sold-on / no-sales-on / not-listed-on channel filters.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-aging/sales-channels","host":["{{baseUrl}}"],"path":["api","inventory-aging","sales-channels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 2,\n    \"channelName\": \"AMZ partusa\",\n    \"integrationName\": \"amazon\"\n  },\n  {\n    \"id\": 5,\n    \"channelName\": \"EBAY fuelpumpsusa\",\n    \"integrationName\": \"ebay\"\n  }\n]"}]},{"name":"Record Product Aging Action","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/{product}","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions",":product"],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Create or update the aging action state for a product. One state per product:\n\n- `needs_action` — default; nothing recorded yet\n- `in_progress` — a clearance action was recorded (`action_type` required: price_reduced, listed_on_channel, promotion, bundled, transferred, removal_ordered, written_down, other)\n- `resolved` — the aged stock was dealt with (`resolution` required: sold_through, cleared, written_off)\n- `accepted` — deliberate long-tail stock; optional `snooze_until` (today or later) keeps it out of the needs-attention scope until that date\n\n`note` (max 1000 chars) and `assigned_to` (an active user belonging to the current account) are optional on every status; `action_type` is rejected for accepted/needs_action and `resolution` outside resolved. Each write stamps who acted and when.\n\nWhen granular permissions are enabled for the account, this endpoint requires the `inventory.manage_aging` permission.","body":{"mode":"raw","raw":"{\n  \"status\": \"in_progress\",\n  \"action_type\": \"price_reduced\",\n  \"note\": \"Dropped price 15% on Amazon and eBay\",\n  \"assigned_to\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/{product}","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions",":product"],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"product_id\": 1935,\n  \"status\": \"in_progress\",\n  \"action_type\": \"price_reduced\",\n  \"resolution\": null,\n  \"note\": \"Dropped price 15% on Amazon and eBay\",\n  \"assigned_to\": {\n    \"id\": 4,\n    \"name\": \"Jo Merchant\"\n  },\n  \"snooze_until\": null,\n  \"acted_at\": \"2026-07-13T14:05:22+00:00\",\n  \"updated_by\": {\n    \"id\": 1,\n    \"name\": \"Administrator\"\n  }\n}"}]},{"name":"Clear Product Aging Action","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/{product}","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions",":product"],"variable":[{"key":"product","value":"","description":"The product ID."}]},"description":"Remove a product's recorded aging action state, returning it to needs-action.\n\nWhen granular permissions are enabled for the account, this endpoint requires the `inventory.manage_aging` permission."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/{product}","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions",":product"],"variable":[{"key":"product","value":"","description":"The product ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Bulk Record Product Aging Actions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/bulk","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions","bulk"]},"description":"Record the same aging action state for up to 50 products in one call. Field rules match the single-product endpoint (`action_type` required for in_progress, `resolution` required for resolved, `snooze_until` only for accepted).\n\nReturns a per-product result list; a failure on one product does not roll back the others.\n\nWhen granular permissions are enabled for the account, this endpoint requires the `inventory.manage_aging` permission.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    1935,\n    1994,\n    2017\n  ],\n  \"status\": \"accepted\",\n  \"note\": \"Evergreen replacement-part stock\",\n  \"snooze_until\": \"2026-10-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/bulk","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"results\": [\n    {\n      \"product_id\": 1935,\n      \"ok\": true\n    },\n    {\n      \"product_id\": 1994,\n      \"ok\": true\n    },\n    {\n      \"product_id\": 2017,\n      \"ok\": true\n    }\n  ]\n}"}]},{"name":"Generate AI Aging Suggestions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/generate-ai-suggestions","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions","generate-ai-suggestions"]},"description":"Start a background process that scores aged products with AI and caches a recommended next action on each. Returns a tracked job id you can poll for completion; when the job finishes, the aging report shows the AI-scored suggestions in place of the rule-based ones. If AI is disabled or unavailable for the account, the job completes immediately and rows keep their rule-based suggestions.\n\nTakes no request body.\n\nWhen granular permissions are enabled for the account, this endpoint requires the `inventory.manage_aging` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-aging/actions/generate-ai-suggestions","host":["{{baseUrl}}"],"path":["api","inventory-aging","actions","generate-ai-suggestions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84213\n  },\n  \"message\": \"AI aging suggestions are being generated.\"\n}"}]}]},{"name":"Inventory Expiry & Shelf-Life","item":[{"name":"Get Expiry & Shelf-Life Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry","host":["{{baseUrl}}"],"path":["api","inventory-expiry"]},"description":"Paginated Inventory Expiry & Shelf-Life report. Blends internal lot-tracked FIFO layers with Amazon FBA/AWD layers, bucketed by days-to-expiry. Defaults to the lot_detail view (one row per lot/FIFO layer, each carrying a real fifo_layer_id for disposition actions); pass view=product_summary for one row per product rolled up to the worst-case (soonest) expiry.\n\nAvailable on both GET and POST (the POST variant mirrors all filters and additionally accepts the filter_groups product advanced-filter tree in the body).\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\nBuckets: expired, 0-30, 31-60, 61-90, 91-180, 180+, no_expiry.\nSort: fixed — soonest-to-expire first, undated lots last.\nPagination: page (default 1), per_page (default 50, max 500).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis endpoint accepts the canonical list view param contract used by the application UI: filters as filter[&lt;key>], a `sort` param (see below), `page`/`per_page`, and a base64-encoded `filter_groups` tree — in addition to the flat params shown."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry","host":["{{baseUrl}}"],"path":["api","inventory-expiry"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"fifo_layer_id\": 8842,\n      \"product_id\": 42,\n      \"sku\": \"VIT-D3-1000\",\n      \"product_name\": \"Vitamin D3 1000 IU\",\n      \"brand_name\": \"Acme\",\n      \"brand_id\": 3,\n      \"supplier_name\": \"Wellness Distributors\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"bucket\": \"0-30\",\n      \"days_to_expiry\": 18,\n      \"expiry_date\": \"2026-07-04T00:00:00.000000Z\",\n      \"manufacture_date\": \"2024-07-04T00:00:00.000000Z\",\n      \"batch_number\": \"LOT-2026-01\",\n      \"shelf_life_remaining_pct\": 2.5,\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n      \"link_type_name\": \"Purchase Order Line\",\n      \"link_id\": 5521,\n      \"quantity\": 120,\n      \"avg_unit_cost\": 8.5,\n      \"total_value\": 1020,\n      \"valuation_source\": \"internal\",\n      \"is_fba\": false,\n      \"review_status\": \"open\",\n      \"review_status_label\": \"Open\",\n      \"review_notes\": null,\n      \"reviewed_at\": null,\n      \"reviewed_by_name\": null,\n      \"inventory_hold_id\": null\n    }\n  ],\n  \"per_page\": 50,\n  \"total\": 137,\n  \"last_page\": 3\n}"}]},{"name":"Get Expiry & Shelf-Life Report (POST, Advanced Filters)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry","host":["{{baseUrl}}"],"path":["api","inventory-expiry"]},"description":"POST variant of the expiry report. Mirrors every GET filter and additionally carries the larger product advanced-filter tree (filter_groups) in the request body.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\nProduct advanced-filter tree (GroupedFilterSupport). POSTed in the body to carry larger filter sets than the query string allows; bridged into the report via a products.id subquery.\n\nStructure: { conjunction: 'and'|'or', children: [ { type: 'condition', condition: { column, operator, value } } | { type: 'group', group: {…} } ] } (groups may nest).\n\nAllowed columns: sku, name, barcode, mpn, type (text); brand_name, supplier_name, category, tag (relationship text); shelf_life_days, near_expiry_threshold_days (numeric).\nText operators: contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\nNumeric operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\nLegacy { filters: { conjunction, filterSet } } format is also accepted for backward compatibility.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"view\": \"lot_detail\",\n  \"bucket\": \"0-30\",\n  \"warehouse_id\": 1,\n  \"near_expiry_only\": true,\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"brand_name\",\n          \"operator\": \"is\",\n          \"value\": \"Acme\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"shelf_life_days\",\n                \"operator\": \"less_than\",\n                \"value\": 365\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"category\",\n                \"operator\": \"contains\",\n                \"value\": \"Supplement\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  },\n  \"page\": 1,\n  \"per_page\": 50\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry","host":["{{baseUrl}}"],"path":["api","inventory-expiry"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"fifo_layer_id\": 8842,\n      \"product_id\": 42,\n      \"sku\": \"VIT-D3-1000\",\n      \"product_name\": \"Vitamin D3 1000 IU\",\n      \"brand_name\": \"Acme\",\n      \"brand_id\": 3,\n      \"supplier_name\": \"Wellness Distributors\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"bucket\": \"0-30\",\n      \"days_to_expiry\": 18,\n      \"expiry_date\": \"2026-07-04T00:00:00.000000Z\",\n      \"manufacture_date\": \"2024-07-04T00:00:00.000000Z\",\n      \"batch_number\": \"LOT-2026-01\",\n      \"shelf_life_remaining_pct\": 2.5,\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n      \"link_type_name\": \"Purchase Order Line\",\n      \"link_id\": 5521,\n      \"quantity\": 120,\n      \"avg_unit_cost\": 8.5,\n      \"total_value\": 1020,\n      \"valuation_source\": \"internal\",\n      \"is_fba\": false,\n      \"review_status\": \"open\",\n      \"review_status_label\": \"Open\",\n      \"review_notes\": null,\n      \"reviewed_at\": null,\n      \"reviewed_by_name\": null,\n      \"inventory_hold_id\": null\n    }\n  ],\n  \"per_page\": 50,\n  \"total\": 137,\n  \"last_page\": 3\n}"}]},{"name":"Get Expiry Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/metrics","host":["{{baseUrl}}"],"path":["api","inventory-expiry","metrics"]},"description":"Summary metric cards for the expiry dashboard: total tracked value, expired value, value expiring within 30/60/90 days, at-risk and expired lot counts, the Amazon auto-disposal-risk value (FBA lots within Amazon's 50-day disposal window), and per-bucket value/quantity/percentage breakdowns.\n\nHonours the same filters as the report (GET query string or POST filter_groups body).\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/metrics","host":["{{baseUrl}}"],"path":["api","inventory-expiry","metrics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_tracked_value\": 184920.5,\n  \"expired_value\": 4210,\n  \"value_within_30_days\": 12040,\n  \"value_within_60_days\": 28110,\n  \"value_within_90_days\": 41880,\n  \"at_risk_lot_count\": 63,\n  \"expired_lot_count\": 9,\n  \"amazon_disposal_risk_value\": 7300,\n  \"value_by_bucket\": {\n    \"expired\": 4210,\n    \"0-30\": 12040,\n    \"31-60\": 16070,\n    \"61-90\": 13770,\n    \"91-180\": 38900,\n    \"180+\": 99930.5,\n    \"no_expiry\": 0\n  },\n  \"quantity_by_bucket\": {\n    \"expired\": 540,\n    \"0-30\": 1420,\n    \"31-60\": 1890,\n    \"61-90\": 1620,\n    \"91-180\": 4580,\n    \"180+\": 11760,\n    \"no_expiry\": 0\n  },\n  \"percentage_by_bucket\": {\n    \"expired\": 2.3,\n    \"0-30\": 6.5,\n    \"31-60\": 8.7,\n    \"61-90\": 7.4,\n    \"91-180\": 21,\n    \"180+\": 54,\n    \"no_expiry\": 0\n  }\n}"}]},{"name":"Get Expiry Metrics (POST, Advanced Filters)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/metrics","host":["{{baseUrl}}"],"path":["api","inventory-expiry","metrics"]},"description":"POST variant of the metric cards — same response as the GET, with the product advanced-filter tree in the body.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\nProduct advanced-filter tree (GroupedFilterSupport). POSTed in the body to carry larger filter sets than the query string allows; bridged into the report via a products.id subquery.\n\nStructure: { conjunction: 'and'|'or', children: [ { type: 'condition', condition: { column, operator, value } } | { type: 'group', group: {…} } ] } (groups may nest).\n\nAllowed columns: sku, name, barcode, mpn, type (text); brand_name, supplier_name, category, tag (relationship text); shelf_life_days, near_expiry_threshold_days (numeric).\nText operators: contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\nNumeric operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\nLegacy { filters: { conjunction, filterSet } } format is also accepted for backward compatibility.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"brand_name\",\n          \"operator\": \"is\",\n          \"value\": \"Acme\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"shelf_life_days\",\n                \"operator\": \"less_than\",\n                \"value\": 365\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"category\",\n                \"operator\": \"contains\",\n                \"value\": \"Supplement\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/metrics","host":["{{baseUrl}}"],"path":["api","inventory-expiry","metrics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_tracked_value\": 184920.5,\n  \"expired_value\": 4210,\n  \"value_within_30_days\": 12040,\n  \"value_within_60_days\": 28110,\n  \"value_within_90_days\": 41880,\n  \"at_risk_lot_count\": 63,\n  \"expired_lot_count\": 9,\n  \"amazon_disposal_risk_value\": 7300,\n  \"value_by_bucket\": {\n    \"expired\": 4210,\n    \"0-30\": 12040,\n    \"31-60\": 16070,\n    \"61-90\": 13770,\n    \"91-180\": 38900,\n    \"180+\": 99930.5,\n    \"no_expiry\": 0\n  },\n  \"quantity_by_bucket\": {\n    \"expired\": 540,\n    \"0-30\": 1420,\n    \"31-60\": 1890,\n    \"61-90\": 1620,\n    \"91-180\": 4580,\n    \"180+\": 11760,\n    \"no_expiry\": 0\n  },\n  \"percentage_by_bucket\": {\n    \"expired\": 2.3,\n    \"0-30\": 6.5,\n    \"31-60\": 8.7,\n    \"61-90\": 7.4,\n    \"91-180\": 21,\n    \"180+\": 54,\n    \"no_expiry\": 0\n  }\n}"}]},{"name":"Get Expiry Distribution","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/distribution","host":["{{baseUrl}}"],"path":["api","inventory-expiry","distribution"]},"description":"Expiry bucket distribution for charts — one entry per bucket (in display order) with quantity, value, percentage-of-total-value, label and colour. Honours the same filters as the report.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/distribution","host":["{{baseUrl}}"],"path":["api","inventory-expiry","distribution"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"bucket\": \"expired\",\n    \"label\": \"Expired\",\n    \"quantity\": 540,\n    \"value\": 4210,\n    \"percentage\": 2.3,\n    \"color\": \"#F44336\"\n  },\n  {\n    \"bucket\": \"0-30\",\n    \"label\": \"0–30 days\",\n    \"quantity\": 1420,\n    \"value\": 12040,\n    \"percentage\": 6.5,\n    \"color\": \"#FF5722\"\n  },\n  {\n    \"bucket\": \"31-60\",\n    \"label\": \"31–60 days\",\n    \"quantity\": 1890,\n    \"value\": 16070,\n    \"percentage\": 8.7,\n    \"color\": \"#FF9800\"\n  },\n  {\n    \"bucket\": \"61-90\",\n    \"label\": \"61–90 days\",\n    \"quantity\": 1620,\n    \"value\": 13770,\n    \"percentage\": 7.4,\n    \"color\": \"#FFC107\"\n  },\n  {\n    \"bucket\": \"91-180\",\n    \"label\": \"91–180 days\",\n    \"quantity\": 4580,\n    \"value\": 38900,\n    \"percentage\": 21,\n    \"color\": \"#8BC34A\"\n  },\n  {\n    \"bucket\": \"180+\",\n    \"label\": \"180+ days\",\n    \"quantity\": 11760,\n    \"value\": 99930.5,\n    \"percentage\": 54,\n    \"color\": \"#4CAF50\"\n  },\n  {\n    \"bucket\": \"no_expiry\",\n    \"label\": \"No expiry\",\n    \"quantity\": 0,\n    \"value\": 0,\n    \"percentage\": 0,\n    \"color\": \"#9E9E9E\"\n  }\n]"}]},{"name":"Get Expiry Distribution (POST, Advanced Filters)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/distribution","host":["{{baseUrl}}"],"path":["api","inventory-expiry","distribution"]},"description":"POST variant of the bucket distribution — same response as the GET, with the product advanced-filter tree in the body.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\nProduct advanced-filter tree (GroupedFilterSupport). POSTed in the body to carry larger filter sets than the query string allows; bridged into the report via a products.id subquery.\n\nStructure: { conjunction: 'and'|'or', children: [ { type: 'condition', condition: { column, operator, value } } | { type: 'group', group: {…} } ] } (groups may nest).\n\nAllowed columns: sku, name, barcode, mpn, type (text); brand_name, supplier_name, category, tag (relationship text); shelf_life_days, near_expiry_threshold_days (numeric).\nText operators: contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\nNumeric operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\nLegacy { filters: { conjunction, filterSet } } format is also accepted for backward compatibility.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"brand_name\",\n          \"operator\": \"is\",\n          \"value\": \"Acme\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"shelf_life_days\",\n                \"operator\": \"less_than\",\n                \"value\": 365\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"category\",\n                \"operator\": \"contains\",\n                \"value\": \"Supplement\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/distribution","host":["{{baseUrl}}"],"path":["api","inventory-expiry","distribution"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"bucket\": \"expired\",\n    \"label\": \"Expired\",\n    \"quantity\": 540,\n    \"value\": 4210,\n    \"percentage\": 2.3,\n    \"color\": \"#F44336\"\n  },\n  {\n    \"bucket\": \"0-30\",\n    \"label\": \"0–30 days\",\n    \"quantity\": 1420,\n    \"value\": 12040,\n    \"percentage\": 6.5,\n    \"color\": \"#FF5722\"\n  },\n  {\n    \"bucket\": \"31-60\",\n    \"label\": \"31–60 days\",\n    \"quantity\": 1890,\n    \"value\": 16070,\n    \"percentage\": 8.7,\n    \"color\": \"#FF9800\"\n  },\n  {\n    \"bucket\": \"61-90\",\n    \"label\": \"61–90 days\",\n    \"quantity\": 1620,\n    \"value\": 13770,\n    \"percentage\": 7.4,\n    \"color\": \"#FFC107\"\n  },\n  {\n    \"bucket\": \"91-180\",\n    \"label\": \"91–180 days\",\n    \"quantity\": 4580,\n    \"value\": 38900,\n    \"percentage\": 21,\n    \"color\": \"#8BC34A\"\n  },\n  {\n    \"bucket\": \"180+\",\n    \"label\": \"180+ days\",\n    \"quantity\": 11760,\n    \"value\": 99930.5,\n    \"percentage\": 54,\n    \"color\": \"#4CAF50\"\n  },\n  {\n    \"bucket\": \"no_expiry\",\n    \"label\": \"No expiry\",\n    \"quantity\": 0,\n    \"value\": 0,\n    \"percentage\": 0,\n    \"color\": \"#9E9E9E\"\n  }\n]"}]},{"name":"Export Expiry Report (async)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/export","host":["{{baseUrl}}"],"path":["api","inventory-expiry","export"]},"description":"Starts an asynchronous CSV export of the expiry report (lot-detail or product-summary view).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe export runs as a tray-tracked job: a full lot-detail export can run for minutes, and a synchronous response that long is terminated by the edge proxy (Cloudflare 524). The CSV is built off the request cycle, written to the model-exports disk, and surfaced as a download via the tracked job log endpoints.\n\nReturns the tracked job log id; poll the tracked job log endpoints (or GET /api/export/download?file=...) for the finished file.\n\nAuthentication: Requires Bearer token (scope reports:read). Accepts the same filters as the report endpoint (view, warehouse_id, search, batch_number, bucket, brand_id, supplier_id, min_quantity, fba_only, near_expiry_only, and the advanced filter_groups tree on the POST variant)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/export","host":["{{baseUrl}}"],"path":["api","inventory-expiry","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Export started — track progress in the job tray.\"\n}"}]},{"name":"Export Expiry Report (async, POST + filter_groups)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/export","host":["{{baseUrl}}"],"path":["api","inventory-expiry","export"]},"description":"Starts an asynchronous CSV export of the expiry report (lot-detail or product-summary view).\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe export runs as a tray-tracked job: a full lot-detail export can run for minutes, and a synchronous response that long is terminated by the edge proxy (Cloudflare 524). The CSV is built off the request cycle, written to the model-exports disk, and surfaced as a download via the tracked job log endpoints.\n\nReturns the tracked job log id; poll the tracked job log endpoints (or GET /api/export/download?file=...) for the finished file.\n\nAuthentication: Requires Bearer token (scope reports:read). Accepts the same filters as the report endpoint (view, warehouse_id, search, batch_number, bucket, brand_id, supplier_id, min_quantity, fba_only, near_expiry_only, and the advanced filter_groups tree on the POST variant).","body":{"mode":"raw","raw":"{\n  \"view\": \"lot_detail\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"brand_name\",\n          \"operator\": \"is\",\n          \"value\": \"Acme\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"shelf_life_days\",\n                \"operator\": \"less_than\",\n                \"value\": 365\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"category\",\n                \"operator\": \"contains\",\n                \"value\": \"Supplement\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/export","host":["{{baseUrl}}"],"path":["api","inventory-expiry","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Export started — track progress in the job tray.\"\n}"}]},{"name":"Get Actionable Lot Count","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/alert-count","host":["{{baseUrl}}"],"path":["api","inventory-expiry","alert-count"]},"description":"Lightweight count of lot-tracked lots that are expired or within their near-expiry threshold and still need attention (no review record yet, or one left \"open\"). Acknowledged, quarantined and written-off lots drop out. Powers the navigation badge.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/alert-count","host":["{{baseUrl}}"],"path":["api","inventory-expiry","alert-count"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"actionable_lot_count\": 63\n  }\n}"}]},{"name":"Get Near-Expiry Alert Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/alert-summary","host":["{{baseUrl}}"],"path":["api","inventory-expiry","alert-summary"]},"description":"Near-expiry alert summary for the report-header risk banner and the daily digest: expired and near-expiry lot counts/values (threshold-aware per product), the Amazon auto-disposal-risk value, the actionable (needs-review) lot count, and the highest-value at-risk products (worst-case first).\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/alert-summary","host":["{{baseUrl}}"],"path":["api","inventory-expiry","alert-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"expired_lot_count\": 9,\n    \"expired_value\": 4210,\n    \"near_expiry_lot_count\": 54,\n    \"near_expiry_value\": 24080,\n    \"amazon_disposal_risk_value\": 7300,\n    \"actionable_lot_count\": 63,\n    \"top_products\": [\n      {\n        \"product_id\": 42,\n        \"sku\": \"VIT-D3-1000\",\n        \"product_name\": \"Vitamin D3 1000 IU\",\n        \"soonest_days_to_expiry\": 18,\n        \"at_risk_quantity\": 120,\n        \"at_risk_value\": 1020\n      },\n      {\n        \"product_id\": 77,\n        \"sku\": \"FISH-OIL-500\",\n        \"product_name\": \"Fish Oil 500mg\",\n        \"soonest_days_to_expiry\": -3,\n        \"at_risk_quantity\": 80,\n        \"at_risk_value\": 640\n      }\n    ]\n  }\n}"}]},{"name":"Write Off Lot","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/write-off","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","write-off"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]},"description":"Write off a lot's remaining (or partial) quantity via an expired-stock DECREASE inventory adjustment (reason: expired). quantity is optional — when omitted the layer's full remaining available quantity is written off; when set, only that portion is consumed (partial write-off).\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory (write) + permission inventory.adjust.\n\nPath param: fifoLayer — the FIFO layer (lot) id, route-model-bound.\n\nvoid_confirmations (array, optional) — when the write-off would consume stock that is hard-allocated to a fulfillment with a printed shipping label, list one entry per fulfillment to authorize voiding that label and proceeding. Omit it and the request is rejected with a 422 conflict if hard-allocated stock is in the way.\nvoid_confirmations[].fulfillment_id (integer, required) — the fulfillment whose label may be voided.\nvoid_confirmations[].attempt_void (boolean, required) — true to void the label and consume its stock.\nvoid_confirmations[].reason (string, optional) — free-text audit note for the void.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"quantity\": 50,\n  \"notes\": \"Past expiry — destroyed on site.\",\n  \"void_confirmations\": [\n    {\n      \"fulfillment_id\": 77120,\n      \"attempt_void\": true,\n      \"reason\": \"Customer cancelled after the label was printed\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/write-off","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","write-off"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 301,\n    \"fifo_layer_id\": 8842,\n    \"status\": \"written_off\",\n    \"status_label\": \"Written Off\",\n    \"notes\": \"Past expiry — destroyed on site.\",\n    \"inventory_hold_id\": null,\n    \"reviewed_at\": \"2026-06-16T14:32:10+00:00\",\n    \"reviewed_by\": {\n      \"id\": 4,\n      \"name\": \"Dana Ops\"\n    },\n    \"fifo_layer\": {\n      \"id\": 8842,\n      \"available_quantity\": 0,\n      \"batch_number\": \"LOT-2026-01\",\n      \"expiry_date\": \"2026-07-04\"\n    }\n  }\n}"}]},{"name":"Quarantine Lot","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/quarantine","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","quarantine"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]},"description":"Quarantine a lot — remove its quantity from available-to-promise via a reversible inventory hold (no stock movement). quantity is optional — when omitted the layer's full remaining available quantity is held. Returns the review record including the inventory_hold_id.\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory (write) + permission inventory.adjust.\n\nPath param: fifoLayer — the FIFO layer (lot) id, route-model-bound.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"quantity\": 120,\n  \"notes\": \"Hold pending QA inspection.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/quarantine","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","quarantine"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 302,\n    \"fifo_layer_id\": 8842,\n    \"status\": \"quarantined\",\n    \"status_label\": \"Quarantined\",\n    \"notes\": \"Hold pending QA inspection.\",\n    \"inventory_hold_id\": 1190,\n    \"reviewed_at\": \"2026-06-16T14:35:02+00:00\",\n    \"reviewed_by\": {\n      \"id\": 4,\n      \"name\": \"Dana Ops\"\n    },\n    \"fifo_layer\": {\n      \"id\": 8842,\n      \"available_quantity\": 120,\n      \"batch_number\": \"LOT-2026-01\",\n      \"expiry_date\": \"2026-07-04\"\n    }\n  }\n}"}]},{"name":"Release Quarantine","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/release-quarantine","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","release-quarantine"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]},"description":"Release a lot from quarantine — return the held quantity to available-to-promise by lifting the inventory hold. No request body. The lot's review status returns to open.\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory (write) + permission inventory.adjust.\n\nPath param: fifoLayer — the FIFO layer (lot) id, route-model-bound.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/release-quarantine","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","release-quarantine"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 302,\n    \"fifo_layer_id\": 8842,\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"notes\": \"Hold pending QA inspection.\",\n    \"inventory_hold_id\": null,\n    \"reviewed_at\": \"2026-06-16T15:01:44+00:00\",\n    \"reviewed_by\": {\n      \"id\": 4,\n      \"name\": \"Dana Ops\"\n    },\n    \"fifo_layer\": {\n      \"id\": 8842,\n      \"available_quantity\": 120,\n      \"batch_number\": \"LOT-2026-01\",\n      \"expiry_date\": \"2026-07-04\"\n    }\n  }\n}"}]},{"name":"Set Lot Review Status","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/review-status","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","review-status"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]},"description":"Set a lot's non-stock review disposition (acknowledge a near-expiry lot, or re-open it). status is restricted to the bookkeeping states open and acknowledged — the stock-mutating dispositions (written_off / quarantined) are set only by their dedicated endpoints.\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory (write) + permission inventory.adjust.\n\nPath param: fifoLayer — the FIFO layer (lot) id, route-model-bound.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"status\": \"acknowledged\",\n  \"notes\": \"Reviewed — will sell through before expiry.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/review-status","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","review-status"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 303,\n    \"fifo_layer_id\": 8842,\n    \"status\": \"acknowledged\",\n    \"status_label\": \"Acknowledged\",\n    \"notes\": \"Reviewed — will sell through before expiry.\",\n    \"inventory_hold_id\": null,\n    \"reviewed_at\": \"2026-06-16T15:10:00+00:00\",\n    \"reviewed_by\": {\n      \"id\": 4,\n      \"name\": \"Dana Ops\"\n    },\n    \"fifo_layer\": {\n      \"id\": 8842,\n      \"available_quantity\": 120,\n      \"batch_number\": \"LOT-2026-01\",\n      \"expiry_date\": \"2026-07-04\"\n    }\n  }\n}"}]},{"name":"Preview Lot Write-Off Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/write-off-impact","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","write-off-impact"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]},"description":"Preview the demotion and label-void impact of writing off a lot before committing the write-off. Read-only — mutates nothing.\n\nReturns one row per product the write-off would consume stock for. shortfall_quantity is how much MORE than available the write-off removes (stock goes negative if greater than zero). unallocated_quantity / soft_allocated_quantity / hard_allocated_quantity split the consumed quantity into free / soft-reserved / hard-allocated (label-printed). affected_allocations[] lists the order allocations that would be consumed, highest priority first; allocation_type is soft or hard. For hard rows, fulfillment_id / carrier identify the printed shipping label and carrier_void_supported / voidable_status (voidable, or otherwise) indicate whether it can be voided through the API.\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory + permission inventory.adjust.\n\nPath param: fifoLayer — the FIFO layer (lot) id, route-model-bound.\nQuery param: quantity (optional) — the portion to write off; omit to preview writing off the layer's full remaining available quantity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lots/{fifoLayer}/write-off-impact","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lots",":fifoLayer","write-off-impact"],"variable":[{"key":"fifoLayer","value":"","description":"The fifo layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 4,\n      \"soft_allocated_quantity\": 3,\n      \"hard_allocated_quantity\": 2,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88213,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 4521,\n          \"order_number\": \"SO-10442\",\n          \"customer_name\": \"Acme Retail\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 3\n        },\n        {\n          \"allocation_id\": 88240,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 4530,\n          \"order_number\": \"SO-10450\",\n          \"customer_name\": \"Beta Wholesale\",\n          \"fulfillment_id\": 77120,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Download Lot Backfill Template (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lot-backfill/template","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lot-backfill","template"]},"description":"Download the lot-data backfill CSV template (header row + one example row) so uploads start from the exact header layout the importer expects (filename: lot-data-backfill-template.csv, Content-Type: text/csv).\n\nColumns: sku, warehouse, batch, manufacture_date, expiry_date, quantity.\n\nAuthentication: Requires Bearer token. Scope: reports:read.\n\nThis is a file download — the response is CSV text, not JSON.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lot-backfill/template","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lot-backfill","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"sku,warehouse,batch,manufacture_date,expiry_date,quantity\\nABC-123,Main Warehouse,LOT-2026-01,2026-01-15,2027-01-15,100\\n"}]},{"name":"Import Lot Backfill CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-expiry/lot-backfill","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lot-backfill"]},"description":"Upload a lot-data backfill CSV (multipart/form-data). The file is parsed, then a tray-tracked job is dispatched that splits the named quantities off each product's existing un-lotted FIFO stock into dated lots (cost preserved). Returns the tracked_job_log_id so the frontend can follow progress via the tracked job log endpoints; per-row outcomes (assigned / partial / skipped / failed) are reported in the job summary.\n\nBody: multipart/form-data with a single file field. Accepted mime: csv, txt. Max size: 10 MB.\n\nAuthentication: Requires Bearer token. Scope: scope.rw:inventory (write) + permission inventory.adjust.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-expiry/lot-backfill","host":["{{baseUrl}}"],"path":["api","inventory-expiry","lot-backfill"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9921\n  },\n  \"message\": \"Lot data backfill started — track progress in the job tray.\"\n}"}]}]},{"name":"Connection","item":[{"name":"Test Connection","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/test-connection","host":["{{baseUrl}}"],"path":["api","magento2","test-connection"]},"description":"Validates the supplied Magento 2 credentials by calling the REST API. Returns the store views and MSI (Multi-Source Inventory) sources the merchant has access to — used by the UI to preview before persisting.\n\nNothing is persisted by this endpoint.\n\n**Body parameters:**\n- `base_url` (required, URL): The storefront base URL — e.g. `https://shop.example.com`. Trailing slash is trimmed server-side.\n- `access_token` (required, string, min 8 chars, max 255): The integration access token from Magento Admin → System → Integrations.\n\n**Error responses:**\n- `422` — validation failure OR Magento rejected the credentials (`success: false` with a human-readable `message`).\n- `401` — caller is not authenticated to SKU.io.","body":{"mode":"raw","raw":"{\n  \"base_url\": \"https://shop.example.com\",\n  \"access_token\": \"magento_integration_access_token_xxxxxxxx\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/test-connection","host":["{{baseUrl}}"],"path":["api","magento2","test-connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"store_views\": [\n      {\n        \"id\": 0,\n        \"code\": \"admin\",\n        \"name\": \"Admin\",\n        \"website_id\": 0,\n        \"store_group_id\": 0\n      },\n      {\n        \"id\": 1,\n        \"code\": \"default\",\n        \"name\": \"Default Store View\",\n        \"website_id\": 1,\n        \"store_group_id\": 1\n      },\n      {\n        \"id\": 2,\n        \"code\": \"en_us\",\n        \"name\": \"United States\",\n        \"website_id\": 1,\n        \"store_group_id\": 1\n      }\n    ],\n    \"inventory_sources\": [\n      {\n        \"source_code\": \"default\",\n        \"name\": \"Default Source\",\n        \"enabled\": true,\n        \"country_id\": \"US\"\n      },\n      {\n        \"source_code\": \"us_warehouse\",\n        \"name\": \"US Warehouse\",\n        \"enabled\": true,\n        \"country_id\": \"US\"\n      }\n    ]\n  }\n}"}]},{"name":"Install","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/install","host":["{{baseUrl}}"],"path":["api","magento2","install"]},"description":"Provisions a new Magento 2 IntegrationInstance after re-validating the supplied credentials server-side. The probe runs again here — clients cannot skip validation by calling `/install` directly.\n\nThe returned instance includes the access token in masked form only (last 4 chars). The full token is encrypted at rest and never echoed back.\n\n**Body parameters:**\n- `name` (required, string, max 255): Human-readable instance name. Must be unique within your tenant.\n- `base_url` (required, URL): Magento storefront base URL.\n- `access_token` (required, string, min 8 chars): The integration access token from Magento Admin.\n- `country` (optional, nullable, ISO 3166-1 alpha-2): Two-letter country code, e.g. `US`.\n\n**Behavior:**\n- Server probes Magento for store views + MSI sources and persists the discovery into `integration_settings.discovery` so downstream phases can read them without re-fetching.\n- Default `integration_settings` are seeded: orders auto-download disabled, email_customers enabled.\n\n**Error responses:**\n- `422` — name already taken OR Magento rejected the credentials.\n- `401` — caller is not authenticated to SKU.io.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme — US Storefront\",\n  \"base_url\": \"https://shop.example.com\",\n  \"access_token\": \"magento_integration_access_token_xxxxxxxx\",\n  \"country\": \"US\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/install","host":["{{baseUrl}}"],"path":["api","magento2","install"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 42,\n    \"integration_id\": 17,\n    \"name\": \"Acme — US Storefront\",\n    \"country\": \"US\",\n    \"sync_status\": null,\n    \"connection_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"connection_settings\": {\n      \"base_url\": \"https://shop.example.com\",\n      \"access_token_masked\": \"••••••••••••••••••••xxxx\"\n    },\n    \"integration_settings\": {\n      \"orders\": {\n        \"download\": {\n          \"last_updated_after\": null,\n          \"status\": [],\n          \"auto_download\": {\n            \"enabled\": false,\n            \"frequency_mins\": 15\n          }\n        }\n      },\n      \"inventory\": {\n        \"master_of_stock\": null\n      },\n      \"communications\": {\n        \"email_customers\": true\n      },\n      \"discovery\": {\n        \"store_views\": [\n          {\n            \"id\": 1,\n            \"code\": \"default\",\n            \"name\": \"Default Store View\"\n          }\n        ],\n        \"inventory_sources\": [\n          {\n            \"source_code\": \"default\",\n            \"name\": \"Default Source\",\n            \"enabled\": true\n          }\n        ]\n      }\n    },\n    \"created_at\": \"2026-06-10T12:34:56+00:00\",\n    \"updated_at\": \"2026-06-10T12:34:56+00:00\"\n  }\n}"}]},{"name":"Test Instance Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","test-connection"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Probe an EXISTING instance's STORED credentials against the Magento 2 REST API. Backs the live Connection Status chip on the settings Connection tab — the frontend never sees the raw access token, so the server re-uses what's persisted in connection_settings. No request body.\n\nReturns 200 with `data.connected = true` when the token authenticates, or 422 with `data.connected = false` and an actionable `message` when Magento rejects it (invalid/expired token, missing resource scopes, or unreachable host).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","test-connection"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"connected\": true\n  }\n}"}]}]},{"name":"Odoo 3PL","item":[{"name":"List Shipping Methods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"List the available Odoo 3PL carriers for this integration instance together with the SKU.io shipping methods available to map onto. Each carrier row includes its current SKU shipping-method mapping (if any). Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"services\": [\n      {\n        \"id\": 1,\n        \"odoo_3pl_carrier_id\": 5,\n        \"name\": \"Fedex Canada Ground\",\n        \"delivery_type\": \"fedex_rest\",\n        \"shipping_method_id\": null,\n        \"sku_shipping_method_name\": null\n      },\n      {\n        \"id\": 3,\n        \"odoo_3pl_carrier_id\": 10,\n        \"name\": \"ups ground\",\n        \"delivery_type\": \"ups_rest\",\n        \"shipping_method_id\": 5,\n        \"sku_shipping_method_name\": \"UPS Ground\"\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 5,\n        \"name\": \"Ground\",\n        \"full_name\": \"UPS Ground\",\n        \"type\": \"domestic\"\n      },\n      {\n        \"id\": 16,\n        \"name\": \"1 Day Freight\",\n        \"full_name\": \"FedEx 1 Day Freight\",\n        \"type\": \"domestic\"\n      }\n    ],\n    \"last_synced_at\": \"2026-07-15T14:05:00.000000Z\"\n  }\n}"}]},{"name":"Sync Shipping Methods","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"Refresh the carrier catalog from Odoo 3PL, then auto-link any unmapped carriers to SKU.io shipping methods whose name matches. Returns how many carriers were fetched and how many were auto-matched. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Synced 3 shipping method(s); 1 auto-matched.\",\n  \"data\": {\n    \"carriers_fetched\": 3,\n    \"auto_matched\": 1\n  }\n}"}]},{"name":"Export Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"Download the current carrier-to-SKU shipping-method mappings as a re-importable CSV. A row with a blank shipping_method_id and shipping_method_name clears that mapping on import. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"odoo_3pl_carrier_id,name,delivery_type,shipping_method_id,shipping_method_name\r\n5,Fedex Canada Ground,fedex_rest,,\r\n10,ups ground,ups_rest,5,UPS Ground\r\n"}]},{"name":"Import Shipping Method Mappings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"Upload a CSV of carrier-to-SKU shipping-method mappings. Each row is keyed by odoo_3pl_carrier_id and resolves the SKU.io method by shipping_method_id (authoritative) or shipping_method_name (fallback). Both blank clears that mapping. Content-Type is multipart/form-data; the file must be a CSV (max 2 MB). Requires a Bearer token.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import processed\",\n  \"data\": {\n    \"created\": 1,\n    \"updated\": 1,\n    \"deleted\": 0,\n    \"errors\": []\n  }\n}"}]},{"name":"Auto-Match Shipping Methods","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/auto-match","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","auto-match"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"Auto-link unmapped Odoo 3PL carriers to SKU.io shipping methods whose name matches (case, spacing and punctuation insensitive). Never overwrites an existing mapping. Returns how many carriers were newly linked. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/auto-match","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","auto-match"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"1 shipping method(s) auto-matched\",\n  \"data\": {\n    \"matched_count\": 1\n  }\n}"}]},{"name":"Bulk Map Shipping Methods","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]},"description":"Map many Odoo 3PL carriers to a single SKU.io shipping method at once, or clear them by sending a null shipping_method_id. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    3\n  ],\n  \"shipping_method_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 mapping(s) saved\",\n  \"data\": {\n    \"updated_count\": 2\n  }\n}"}]},{"name":"Update Shipping Method Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/{shippingMethodId}/mapping","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods",":shippingMethodId","mapping"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"},{"key":"shippingMethodId","value":"3","description":"Odoo 3PL shipping-method (carrier) row ID"}]},"description":"Set or clear the SKU.io shipping-method mapping for a single Odoo 3PL carrier. Send a null shipping_method_id to unmap. Once mapped, orders using that SKU shipping method submit to Odoo 3PL with the carrier's name as the requested shipping method. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipping_method_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/odoo-3pl/{integration_instance}/shipping-methods/{shippingMethodId}/mapping","host":["{{baseUrl}}"],"path":["api","odoo-3pl",":integration_instance","shipping-methods",":shippingMethodId","mapping"],"variable":[{"key":"integration_instance","value":"3","description":"Integration instance ID"},{"key":"shippingMethodId","value":"3","description":"Odoo 3PL shipping-method (carrier) row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipping method mapped.\",\n  \"data\": {\n    \"id\": 3,\n    \"integration_instance_id\": 3,\n    \"odoo_3pl_carrier_id\": 10,\n    \"name\": \"ups ground\",\n    \"delivery_type\": \"ups_rest\",\n    \"shipping_method_id\": 5,\n    \"is_mapped\": true,\n    \"sku_shipping_method\": {\n      \"id\": 5,\n      \"name\": \"Ground\",\n      \"full_name\": \"UPS Ground\",\n      \"carrier_name\": \"UPS\"\n    },\n    \"last_synced_at\": \"2026-07-15T14:05:00.000000Z\",\n    \"created_at\": \"2026-07-15T14:05:00.000000Z\",\n    \"updated_at\": \"2026-07-15T14:06:00.000000Z\"\n  }\n}"}]}]},{"name":"Google Sheets","item":[{"name":"Get Google Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/connection","host":["{{baseUrl}}"],"path":["api","v2","google","connection"]},"description":"Return the authenticated user's Google connection status. The connection is per-user and grants access only to sheets the app creates or the user picks (drive.file scope).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/google/connection","host":["{{baseUrl}}"],"path":["api","v2","google","connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connected\": true,\n    \"google_email\": \"jane@acme.com\",\n    \"scopes\": [\n      \"https://www.googleapis.com/auth/drive.file\"\n    ],\n    \"status\": \"connected\"\n  }\n}"}]},{"name":"Disconnect Google","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/connection","host":["{{baseUrl}}"],"path":["api","v2","google","connection"]},"description":"Revoke and remove the authenticated user's Google connection.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/google/connection","host":["{{baseUrl}}"],"path":["api","v2","google","connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connected\": false,\n    \"google_email\": null,\n    \"scopes\": [],\n    \"status\": \"disconnected\"\n  },\n  \"message\": \"Google disconnected.\"\n}"}]},{"name":"Connect Google","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/connection/initiate","host":["{{baseUrl}}"],"path":["api","v2","google","connection","initiate"]},"description":"Start the Google authorization flow. Returns a consent URL to open in the browser; after the user consents, the connection is stored server-side. Only the non-sensitive drive.file scope is requested.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/google/connection/initiate","host":["{{baseUrl}}"],"path":["api","v2","google","connection","initiate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://accounts.google.com/o/oauth2/v2/auth?client_id=...&scope=https://www.googleapis.com/auth/drive.file&state=...\"\n  }\n}"}]},{"name":"Export to Google Sheet","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/google/sheets/export","host":["{{baseUrl}}"],"path":["api","v2","google","sheets","export"]},"description":"Create a new Google Sheet (or refresh an existing linked sheet when sheet_link_id is provided) populated with the supplied rows. entity_type must be a supported import entity (e.g. products). Include an `id` column so edits pulled back are applied as updates; rows with a blank id are inserts.\n\nRow sets above the sync limit are written as a background job — the response returns tracked_job_log_id and no url until it completes.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"entity_type\": \"products\",\n  \"rows\": [\n    {\n      \"id\": 5,\n      \"sku\": \"ABC-123\",\n      \"name\": \"Blue Widget\"\n    },\n    {\n      \"id\": \"\",\n      \"sku\": \"NEW-001\",\n      \"name\": \"New Product\"\n    }\n  ],\n  \"title\": \"SKU Products\",\n  \"filter_signature\": null,\n  \"sheet_link_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/google/sheets/export","host":["{{baseUrl}}"],"path":["api","v2","google","sheets","export"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sheet_link_id\": 12,\n    \"spreadsheet_id\": \"1AbCdEfGhIjKlMnOpQrStUvWxYz0123456789ABCDEFG\",\n    \"url\": \"https://docs.google.com/spreadsheets/d/1AbCdEfGhIjKlMnOpQrStUvWxYz0123456789ABCDEFG/edit\",\n    \"row_count\": 2,\n    \"tracked_job_log_id\": null\n  }\n}"}]},{"name":"List Linked Google Sheets","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/sheets/links?entity_type=products","host":["{{baseUrl}}"],"path":["api","v2","google","sheets","links"],"query":[{"key":"entity_type","value":"products","description":"Entity type to list linked sheets for (required).","disabled":true}]},"description":"List the authenticated user's linked Google Sheets for an entity type.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/google/sheets/links?entity_type=products","host":["{{baseUrl}}"],"path":["api","v2","google","sheets","links"],"query":[{"key":"entity_type","value":"products","description":"Entity type to list linked sheets for (required).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"entity_type\": \"products\",\n      \"spreadsheet_id\": \"1AbCdEfGhIjKlMnOpQrStUvWxYz0123456789ABCDEFG\",\n      \"url\": \"https://docs.google.com/spreadsheets/d/1AbCdEfGhIjKlMnOpQrStUvWxYz0123456789ABCDEFG/edit\",\n      \"data_sheet_name\": \"Data\",\n      \"title\": \"SKU Products\",\n      \"column_mapping\": {\n        \"id\": \"id\",\n        \"SKU\": \"sku\",\n        \"Name\": \"name\"\n      },\n      \"filter_signature\": null,\n      \"row_count\": 2,\n      \"is_stale\": false,\n      \"created_by\": \"Jane\",\n      \"last_pulled_at\": null,\n      \"created_at\": \"2026-07-11T14:30:00.000000Z\",\n      \"updated_at\": \"2026-07-11T14:30:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Pull Changes From Google Sheet","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}/pull","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink","pull"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]},"description":"Read a linked sheet's current rows and start validation of the changes. Rows are matched on the `id` column (blank id inserts a new record). The response returns a data_import_id whose validation results and execution are handled through the standard import endpoints.\n\nReturns total_rows 0 with a null data_import_id when the sheet has only a header row.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}/pull","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink","pull"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"data_import_id\": 45,\n    \"tracked_job_log_id\": 9881,\n    \"total_rows\": 2\n  },\n  \"message\": \"Sheet read; validation started.\"\n}"}]},{"name":"Rename Google Sheet","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]},"description":"Rename a linked Google Sheet. Renames the Google Sheet in your Drive and updates the stored label so the two stay in sync. Only the sheet's owner can rename it.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"title\": \"Q3 reorder planning\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"entity_type\": \"products\",\n    \"spreadsheet_id\": \"1ymf6PauZBgU0dWgLDWcZKUCBZ_bvPVVb1JOUWMTsM3A\",\n    \"url\": \"https://docs.google.com/spreadsheets/d/1ymf6PauZBgU0dWgLDWcZKUCBZ_bvPVVb1JOUWMTsM3A/edit\",\n    \"data_sheet_name\": \"Data\",\n    \"title\": \"Q3 reorder planning\",\n    \"column_mapping\": {\n      \"id\": \"id\",\n      \"SKU\": \"sku\",\n      \"Name\": \"name\"\n    },\n    \"filter_signature\": null,\n    \"row_count\": 27,\n    \"is_stale\": false,\n    \"created_by\": \"Jane\",\n    \"last_pulled_at\": \"2026-07-13T08:19:50.000000Z\",\n    \"created_at\": \"2026-07-13T08:10:00.000000Z\",\n    \"updated_at\": \"2026-07-13T09:02:00.000000Z\"\n  }\n}"}]},{"name":"Unlink Google Sheet","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]},"description":"Unlink a Google Sheet from SKU. This removes the link only — the Google Sheet itself stays untouched in your Google Drive. Only the sheet's owner can unlink it.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/google/sheets/{sheetLink}","host":["{{baseUrl}}"],"path":["api","v2","google","sheets",":sheetLink"],"variable":[{"key":"sheetLink","value":"12","description":"Linked sheet id (from List Linked Google Sheets)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sheet unlinked.\"\n}"}]}]},{"name":"Airtable","item":[{"name":"Get OAuth Authorize URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/authorize?instance_id=7","host":["{{baseUrl}}"],"path":["api","airtable","authorize"],"query":[{"key":"instance_id","value":"7","disabled":true}]},"description":"Build the Airtable authorization URL that starts the connect flow. Open the returned authorization_url in a browser so the account owner can grant access; Airtable then redirects back to SKU.io to finish the connection. Pass the optional instance_id query parameter to re-authorize an existing connection instead of creating a new one.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/authorize?instance_id=7","host":["{{baseUrl}}"],"path":["api","airtable","authorize"],"query":[{"key":"instance_id","value":"7","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorization_url\": \"https://airtable.com/oauth2/v1/authorize?client_id=abc123&redirect_uri=https%3A%2F%2Facme.sku.io%2Fairtable%2Fauth%2Fcallback&response_type=code&scope=data.records%3Aread%20data.records%3Awrite%20schema.bases%3Aread%20schema.bases%3Awrite&state=acme.t0k3n&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256\"\n  }\n}"}]},{"name":"List Airtable Connections","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/integrations","host":["{{baseUrl}}"],"path":["api","airtable","integrations"]},"description":"List the Airtable connections for the current account, including connection status, the granting Airtable account, granted scopes, and monthly API usage against the plan cap.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/integrations","host":["{{baseUrl}}"],"path":["api","airtable","integrations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"name\": \"Ops Hub\",\n      \"connection_status\": \"connected\",\n      \"is_connected\": true,\n      \"account_id\": \"usr8Yh2Qw9Lm4Zx0\",\n      \"account_email\": \"jane@acme.com\",\n      \"granted_scopes\": [\n        \"data.records:read\",\n        \"data.records:write\",\n        \"schema.bases:read\",\n        \"schema.bases:write\"\n      ],\n      \"is_automatic_sync_enabled\": true,\n      \"api_usage\": {\n        \"used\": 1840,\n        \"cap\": 50000,\n        \"percent\": 4,\n        \"near_cap\": false,\n        \"over_cap\": false\n      },\n      \"created_at\": \"2026-07-01T09:15:00+00:00\",\n      \"updated_at\": \"2026-07-22T08:30:00+00:00\"\n    },\n    {\n      \"id\": 9,\n      \"name\": \"Analytics Base\",\n      \"connection_status\": \"connected\",\n      \"is_connected\": true,\n      \"account_id\": \"usr8Yh2Qw9Lm4Zx0\",\n      \"account_email\": \"jane@acme.com\",\n      \"granted_scopes\": [\n        \"data.records:read\",\n        \"data.records:write\",\n        \"schema.bases:read\",\n        \"schema.bases:write\"\n      ],\n      \"is_automatic_sync_enabled\": true,\n      \"api_usage\": {\n        \"used\": 1840,\n        \"cap\": 50000,\n        \"percent\": 4,\n        \"near_cap\": false,\n        \"over_cap\": false\n      },\n      \"created_at\": \"2026-07-01T09:15:00+00:00\",\n      \"updated_at\": \"2026-07-22T08:30:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Verify Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/whoami","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","whoami"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Verify a connection by calling Airtable with the stored token and returning the connected Airtable account id, email, and the scopes granted to the connection.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/whoami","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","whoami"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"account_id\": \"usr8Yh2Qw9Lm4Zx0\",\n    \"account_email\": \"jane@acme.com\",\n    \"scopes\": [\n      \"data.records:read\",\n      \"data.records:write\",\n      \"schema.bases:read\",\n      \"schema.bases:write\"\n    ]\n  }\n}"}]},{"name":"Disconnect Airtable","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Disconnect an Airtable connection. This revokes the stored token and removes every dataset mapping that belonged to the connection.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Syncable Datasets","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/datasets","host":["{{baseUrl}}"],"path":["api","airtable","datasets"]},"description":"List the catalog of SKU.io datasets that can be synced to Airtable. Each dataset lists the exportable fields available to map (with the target cell type) and whether it accepts inbound changes back from Airtable.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/datasets","host":["{{baseUrl}}"],"path":["api","airtable","datasets"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"dataset\": \"products\",\n      \"label\": \"Products\",\n      \"supports_inbound\": true,\n      \"fields\": [\n        {\n          \"source\": \"sku_io_id\",\n          \"label\": \"SKU.io ID\",\n          \"type\": \"text\",\n          \"key\": true\n        },\n        {\n          \"source\": \"name\",\n          \"label\": \"Name\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"barcode\",\n          \"label\": \"Barcode\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"average_cost\",\n          \"label\": \"Average Cost\",\n          \"type\": \"currency\"\n        },\n        {\n          \"source\": \"price\",\n          \"label\": \"Price\",\n          \"type\": \"currency\"\n        },\n        {\n          \"source\": \"brand.name\",\n          \"label\": \"Brand\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"gross_margin_pct\",\n          \"label\": \"Gross Margin %\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"on_hand\",\n          \"label\": \"On Hand\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"units_sold_90d\",\n          \"label\": \"Units Sold (90d)\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"days_of_cover\",\n          \"label\": \"Days of Cover\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"sell_through_pct\",\n          \"label\": \"Sell-through % (90d)\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"is_archived\",\n          \"label\": \"Archived\",\n          \"type\": \"checkbox\"\n        },\n        {\n          \"source\": \"updated_at\",\n          \"label\": \"Updated At\",\n          \"type\": \"datetime\"\n        }\n      ]\n    },\n    {\n      \"dataset\": \"sales_orders\",\n      \"label\": \"Sales Orders\",\n      \"supports_inbound\": true,\n      \"fields\": [\n        {\n          \"source\": \"sku_io_id\",\n          \"label\": \"SKU.io ID\",\n          \"type\": \"text\",\n          \"key\": true\n        },\n        {\n          \"source\": \"order_status\",\n          \"label\": \"Order Status\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"order_date\",\n          \"label\": \"Order Date\",\n          \"type\": \"datetime\"\n        },\n        {\n          \"source\": \"customer_name\",\n          \"label\": \"Customer Name\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"customer_email\",\n          \"label\": \"Customer Email\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"customer_company\",\n          \"label\": \"Customer Company\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"customer_phone\",\n          \"label\": \"Customer Phone\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"customer_po_number\",\n          \"label\": \"Customer PO\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"memo_for_customer\",\n          \"label\": \"Customer Memo\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"is_archived\",\n          \"label\": \"Archived\",\n          \"type\": \"checkbox\"\n        },\n        {\n          \"source\": \"updated_at\",\n          \"label\": \"Updated At\",\n          \"type\": \"datetime\"\n        }\n      ]\n    },\n    {\n      \"dataset\": \"suppliers\",\n      \"label\": \"Suppliers\",\n      \"supports_inbound\": true,\n      \"fields\": [\n        {\n          \"source\": \"sku_io_id\",\n          \"label\": \"SKU.io ID\",\n          \"type\": \"text\",\n          \"key\": true\n        },\n        {\n          \"source\": \"name\",\n          \"label\": \"Name\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"company_name\",\n          \"label\": \"Company\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"primary_contact_name\",\n          \"label\": \"Contact Name\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"email\",\n          \"label\": \"Email\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"messaging_phone\",\n          \"label\": \"Phone\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"website\",\n          \"label\": \"Website\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"is_archived\",\n          \"label\": \"Archived\",\n          \"type\": \"checkbox\"\n        },\n        {\n          \"source\": \"updated_at\",\n          \"label\": \"Updated At\",\n          \"type\": \"datetime\"\n        }\n      ]\n    },\n    {\n      \"dataset\": \"inventory_levels\",\n      \"label\": \"Inventory Levels\",\n      \"supports_inbound\": false,\n      \"fields\": [\n        {\n          \"source\": \"sku_io_id\",\n          \"label\": \"SKU.io ID\",\n          \"type\": \"text\",\n          \"key\": true\n        },\n        {\n          \"source\": \"product.sku\",\n          \"label\": \"SKU\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"warehouse.name\",\n          \"label\": \"Warehouse\",\n          \"type\": \"text\"\n        },\n        {\n          \"source\": \"inventory_available\",\n          \"label\": \"Available\",\n          \"type\": \"number\"\n        },\n        {\n          \"source\": \"updated_at\",\n          \"label\": \"Updated At\",\n          \"type\": \"datetime\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Airtable Bases","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/bases","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","bases"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"List the Airtable bases the connection can access, with the permission level granted for each base.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/bases","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","bases"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"appXt3kQ9vB2mLpZ1\",\n      \"name\": \"Ops Hub\",\n      \"permissionLevel\": \"create\"\n    },\n    {\n      \"id\": \"appLm5nR8sT1uV4wY\",\n      \"name\": \"Warehouse Tracker\",\n      \"permissionLevel\": \"edit\"\n    }\n  ]\n}"}]},{"name":"List Base Tables","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/bases/{baseId}/tables","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","bases",":baseId","tables"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"baseId","value":"appXt3kQ9vB2mLpZ1","description":"Airtable base id (from List Airtable Bases)."}]},"description":"List the tables in an Airtable base along with each table's fields. Use the field ids to build a mapping's key field and field map.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/bases/{baseId}/tables","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","bases",":baseId","tables"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"baseId","value":"appXt3kQ9vB2mLpZ1","description":"Airtable base id (from List Airtable Bases)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"tbl9aRk2Pq7WnE5cX\",\n      \"name\": \"Products\",\n      \"primaryFieldId\": \"fldName0000000001\",\n      \"fields\": [\n        {\n          \"id\": \"fldName0000000001\",\n          \"name\": \"Name\",\n          \"type\": \"singleLineText\"\n        },\n        {\n          \"id\": \"fldSkuIoIdKey0001\",\n          \"name\": \"SKU.io ID\",\n          \"type\": \"singleLineText\"\n        },\n        {\n          \"id\": \"fldPrice000000001\",\n          \"name\": \"Price\",\n          \"type\": \"currency\"\n        },\n        {\n          \"id\": \"fldBrand000000001\",\n          \"name\": \"Brand\",\n          \"type\": \"singleLineText\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"List the dataset mappings configured on a connection, with their target base and table, sync schedule, last sync result, and error count.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"integration_instance_id\": 7,\n      \"dataset\": \"products\",\n      \"dataset_label\": \"Products\",\n      \"direction\": \"outbound\",\n      \"base_id\": \"appXt3kQ9vB2mLpZ1\",\n      \"table_id\": \"tbl9aRk2Pq7WnE5cX\",\n      \"key_field_id\": \"fldSkuIoIdKey0001\",\n      \"field_map\": [\n        {\n          \"source\": \"name\",\n          \"target_field_id\": \"fldName0000000001\"\n        },\n        {\n          \"source\": \"price\",\n          \"target_field_id\": \"fldPrice000000001\"\n        },\n        {\n          \"source\": \"brand.name\",\n          \"target_field_id\": \"fldBrand000000001\"\n        }\n      ],\n      \"filters\": null,\n      \"delete_mode\": \"flag\",\n      \"schedule\": \"hourly\",\n      \"realtime_enabled\": true,\n      \"apply_mode\": null,\n      \"auto_create\": true,\n      \"webhook_active\": false,\n      \"is_enabled\": true,\n      \"error_count\": 0,\n      \"last_synced_at\": \"2026-07-22T08:00:00+00:00\",\n      \"last_result\": {\n        \"created\": 4,\n        \"updated\": 120,\n        \"deleted\": 0,\n        \"skipped\": 2,\n        \"finished_at\": \"2026-07-22T08:00:07+00:00\"\n      },\n      \"created_at\": \"2026-07-10T12:00:00+00:00\",\n      \"updated_at\": \"2026-07-22T08:00:07+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/airtable/instances/7/mappings?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Create a dataset mapping that syncs a SKU.io dataset to a table in an Airtable base.\n\nBody fields:\n- dataset (string, required): the SKU.io dataset to sync. One of products, inventory_levels, sales_orders, sales_order_lines, purchase_orders, purchase_order_lines, suppliers.\n- direction (string, optional, default outbound): outbound sends SKU.io data to Airtable; inbound reads changes back. Inbound is only supported for the products dataset.\n- base_id (string, required): the target Airtable base id.\n- table_id (string, required): the target table id within the base.\n- key_field_id (string, required): the Airtable field that stores the SKU.io id and is used as the merge key for upserts.\n- field_map (array, required, min 1): each entry maps a SKU.io source field to an Airtable target field. Each item has source (string) and target_field_id (string).\n- filters (object, optional): optional filter conditions restricting which records sync.\n- delete_mode (string, optional, default flag): how records removed in SKU.io are handled in Airtable. One of flag, delete, ignore.\n- schedule (string, optional, default hourly): automatic sync cadence. One of fifteen_minutes, hourly, daily, manual.\n- realtime_enabled (boolean, optional, default false): push changes as they happen.\n- apply_mode (string, optional): for inbound mappings, whether changes are queued for review or applied automatically. One of review, auto.\n- auto_create (boolean, optional, default false): when true, create missing Airtable records during sync instead of only updating existing rows.\n- is_enabled (boolean, optional, default true): whether the mapping is active.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"dataset\": \"products\",\n  \"direction\": \"outbound\",\n  \"base_id\": \"appXt3kQ9vB2mLpZ1\",\n  \"table_id\": \"tbl9aRk2Pq7WnE5cX\",\n  \"key_field_id\": \"fldSkuIoIdKey0001\",\n  \"field_map\": [\n    {\n      \"source\": \"name\",\n      \"target_field_id\": \"fldName0000000001\"\n    },\n    {\n      \"source\": \"price\",\n      \"target_field_id\": \"fldPrice000000001\"\n    },\n    {\n      \"source\": \"brand.name\",\n      \"target_field_id\": \"fldBrand000000001\"\n    }\n  ],\n  \"filters\": null,\n  \"delete_mode\": \"flag\",\n  \"schedule\": \"hourly\",\n  \"realtime_enabled\": true,\n  \"apply_mode\": null,\n  \"auto_create\": true,\n  \"is_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"integration_instance_id\": 7,\n  \"dataset\": \"products\",\n  \"dataset_label\": \"Products\",\n  \"direction\": \"outbound\",\n  \"base_id\": \"appXt3kQ9vB2mLpZ1\",\n  \"table_id\": \"tbl9aRk2Pq7WnE5cX\",\n  \"key_field_id\": \"fldSkuIoIdKey0001\",\n  \"field_map\": [\n    {\n      \"source\": \"name\",\n      \"target_field_id\": \"fldName0000000001\"\n    },\n    {\n      \"source\": \"price\",\n      \"target_field_id\": \"fldPrice000000001\"\n    },\n    {\n      \"source\": \"brand.name\",\n      \"target_field_id\": \"fldBrand000000001\"\n    }\n  ],\n  \"filters\": null,\n  \"delete_mode\": \"flag\",\n  \"schedule\": \"hourly\",\n  \"realtime_enabled\": true,\n  \"apply_mode\": null,\n  \"auto_create\": true,\n  \"webhook_active\": false,\n  \"is_enabled\": true,\n  \"error_count\": 0,\n  \"last_synced_at\": \"2026-07-22T08:00:00+00:00\",\n  \"last_result\": {\n    \"created\": 4,\n    \"updated\": 120,\n    \"deleted\": 0,\n    \"skipped\": 2,\n    \"finished_at\": \"2026-07-22T08:00:07+00:00\"\n  },\n  \"created_at\": \"2026-07-10T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-22T08:00:07+00:00\"\n}"}]},{"name":"Update Mapping","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]},"description":"Update an existing dataset mapping. Send only the fields you want to change; omitted fields keep their current value.\n\nBody fields (all optional): key_field_id (string), field_map (array of source / target_field_id entries), filters (object or null), delete_mode (flag, delete, ignore), schedule (fifteen_minutes, hourly, daily, manual), realtime_enabled (boolean), apply_mode (review, auto, or null), auto_create (boolean), is_enabled (boolean).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"schedule\": \"daily\",\n  \"realtime_enabled\": false,\n  \"auto_create\": false,\n  \"is_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"integration_instance_id\": 7,\n  \"dataset\": \"products\",\n  \"dataset_label\": \"Products\",\n  \"direction\": \"outbound\",\n  \"base_id\": \"appXt3kQ9vB2mLpZ1\",\n  \"table_id\": \"tbl9aRk2Pq7WnE5cX\",\n  \"key_field_id\": \"fldSkuIoIdKey0001\",\n  \"field_map\": [\n    {\n      \"source\": \"name\",\n      \"target_field_id\": \"fldName0000000001\"\n    },\n    {\n      \"source\": \"price\",\n      \"target_field_id\": \"fldPrice000000001\"\n    },\n    {\n      \"source\": \"brand.name\",\n      \"target_field_id\": \"fldBrand000000001\"\n    }\n  ],\n  \"filters\": null,\n  \"delete_mode\": \"flag\",\n  \"schedule\": \"daily\",\n  \"realtime_enabled\": false,\n  \"apply_mode\": null,\n  \"auto_create\": false,\n  \"webhook_active\": false,\n  \"is_enabled\": true,\n  \"error_count\": 0,\n  \"last_synced_at\": \"2026-07-22T08:00:00+00:00\",\n  \"last_result\": {\n    \"created\": 4,\n    \"updated\": 120,\n    \"deleted\": 0,\n    \"skipped\": 2,\n    \"finished_at\": \"2026-07-22T08:00:07+00:00\"\n  },\n  \"created_at\": \"2026-07-10T12:00:00+00:00\",\n  \"updated_at\": \"2026-07-22T08:00:07+00:00\"\n}"}]},{"name":"Delete Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]},"description":"Delete a dataset mapping. This stops future syncs for the mapping; records already written to Airtable are left in place.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Sync Mapping","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}/sync","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping","sync"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]},"description":"Trigger a sync run for a mapping now. The sync runs in the background; the response returns a tracked_job_log_id you can use to follow its progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/mappings/{mapping}/sync","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","mappings",":mapping","sync"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."},{"key":"mapping","value":"42","description":"Dataset mapping id (from List Mappings)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 98765\n  }\n}"}]},{"name":"Provision Template Table","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/provision-template","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","provision-template"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Provision a ready-made Airtable base for the connection. This creates a pre-built base with tables and mappings for common datasets and runs an initial backfill in the background.\n\nBody fields:\n- workspace_id (string, required): the Airtable workspace to create the base in.\n- base_name (string, optional, default \"SKU.io Ops Hub\"): the name for the new base.\n- order_window_days (integer, optional, default 90, range 1–3650): how many days of recent orders to backfill.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"workspace_id\": \"wspYq2Zt6Bn8Kx3Rd\",\n  \"base_name\": \"SKU.io Ops Hub\",\n  \"order_window_days\": 90\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/provision-template","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","provision-template"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 98766\n  }\n}"}]},{"name":"List Inbound Changes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"List the queued inbound changes proposed from Airtable and awaiting review. Each change targets a SKU.io record (product, sales order, or supplier): link_type/link_id identify it, link_reference and link_route present it for navigation, and proposed lists each mapped field's old and new value. Apply or reject them from the review queue.\n\nSupports pagination (page, per_page — default 10), sort (id, status, created_at, updated_at; prefix - for DESC), and filter[status] (pending, applied, rejected, failed, unmatched).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 301,\n      \"mapping_id\": 42,\n      \"airtable_record_id\": \"recQw7Yh2Kp9Lm4Zx\",\n      \"link_type\": \"App\\\\Models\\\\Product\",\n      \"link_id\": 512,\n      \"link_type_label\": \"Product\",\n      \"link_reference\": \"ABC-123\",\n      \"link_route\": \"/products/512\",\n      \"proposed\": {\n        \"barcode\": {\n          \"old\": \"0000000000\",\n          \"new\": 123456789012\n        },\n        \"name\": {\n          \"old\": \"Blue Widget\",\n          \"new\": \"Blue Widget (2026)\"\n        }\n      },\n      \"status\": \"pending\",\n      \"error\": null,\n      \"created_at\": \"2026-07-22T07:45:00+00:00\",\n      \"updated_at\": \"2026-07-22T07:45:00+00:00\"\n    },\n    {\n      \"id\": 302,\n      \"mapping_id\": 43,\n      \"airtable_record_id\": \"recSalesOrderAB12\",\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 88,\n      \"link_type_label\": \"Sales Order\",\n      \"link_reference\": \"SO-1042\",\n      \"link_route\": \"/orders/sales-orders/88\",\n      \"proposed\": {\n        \"customer_company\": {\n          \"old\": \"Acme LLC\",\n          \"new\": \"Acme Inc\"\n        }\n      },\n      \"status\": \"pending\",\n      \"error\": null,\n      \"created_at\": \"2026-07-22T07:50:00+00:00\",\n      \"updated_at\": \"2026-07-22T07:50:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/airtable/instances/7/inbound-changes?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Apply Inbound Changes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes/apply","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes","apply"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Apply queued inbound changes back into SKU.io. Send \"all\": true to apply every pending change for the connection, or \"ids\": [..] to apply specific changes. Changes are applied in the background; the response returns a tracked_job_log_id to follow progress.\n\nBody fields:\n- all (boolean, optional): apply every pending change when true.\n- ids (array of integers, optional): the specific change ids to apply when all is not set.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"all\": false,\n  \"ids\": [\n    301,\n    302\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes/apply","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes","apply"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 98767\n  }\n}"}]},{"name":"Reject Inbound Changes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes/reject","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes","reject"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]},"description":"Reject queued inbound changes so they are not applied. Send \"all\": true to reject every pending change for the connection, or \"ids\": [..] to reject specific changes.\n\nBody fields:\n- all (boolean, optional): reject every pending change when true.\n- ids (array of integers, optional): the specific change ids to reject when all is not set.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"all\": false,\n  \"ids\": [\n    303\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/airtable/instances/{instance}/inbound-changes/reject","host":["{{baseUrl}}"],"path":["api","airtable","instances",":instance","inbound-changes","reject"],"variable":[{"key":"instance","value":"7","description":"Airtable connection id (from List Airtable Connections)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rejected\": 1\n  }\n}"}]}]},{"name":"Products","item":[{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]},"description":"Get a single product by ID with all related data.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 404 if product not found."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"SKU-001\",\n    \"name\": \"Blue Widget\",\n    \"barcode\": 123456789012,\n    \"mpn\": \"BW-001\",\n    \"hts_code\": \"8471.30.0100\",\n    \"type\": \"standard\",\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 180,\n    \"near_expiry_threshold_days\": 60,\n    \"min_remaining_shelf_life_days\": 105,\n    \"expiry_aware_availability\": true,\n    \"image_url\": \"https://cdn.example.com/products/blue-widget.jpg\",\n    \"has_inventory_movements\": true,\n    \"brand\": {\n      \"id\": 3,\n      \"name\": \"Acme Co\"\n    },\n    \"tags\": [\n      \"new\",\n      \"featured\"\n    ],\n    \"is_variation\": false,\n    \"weight\": \"0.5\",\n    \"weight_unit\": \"kg\",\n    \"length\": \"10.0\",\n    \"width\": \"5.0\",\n    \"height\": \"3.0\",\n    \"dimension_unit\": \"cm\",\n    \"case_quantity\": 12,\n    \"case_weight\": \"6.0\",\n    \"case_weight_unit\": \"kg\",\n    \"fba_prep_instructions\": \"Bubble wrap required\",\n    \"price\": {\n      \"Default\": {\n        \"price\": 29.99\n      }\n    },\n    \"average_cost\": {\n      \"value\": 12.5,\n      \"currency\": \"USD\"\n    },\n    \"default_supplier\": {\n      \"id\": 5,\n      \"name\": \"Main Supplier\"\n    },\n    \"default_supplier_sku\": \"MS-BW-001\",\n    \"default_supplier_leadtime\": 14,\n    \"default_supplier_moq\": 100,\n    \"default_supplier_price\": 10,\n    \"min_stock_level\": 50,\n    \"target_stock_days\": 30,\n    \"inventory_total\": 150,\n    \"inventory_available\": 120,\n    \"inventory_available_to_sell\": 115,\n    \"inventory_allocated\": 30,\n    \"inventory_on_hold\": 0,\n    \"inventory_incoming\": 200,\n    \"category_main\": {\n      \"id\": 2,\n      \"name\": \"Widgets\"\n    },\n    \"attributes\": {},\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"default_tax_rate_id\": null,\n    \"is_taxable\": false,\n    \"archived_at\": null,\n    \"stock_uom_id\": 1,\n    \"stock_uom_code\": \"EACH\",\n    \"stock_uom_name\": \"Each\",\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2024-06-01T08:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Product","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]},"description":"Update an existing product by ID. All fields are optional on update.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nProduct type cannot be changed if inventory movements exist (exception: standard -> kit is allowed). Additionally, an inventory-bearing product (standard/kit/blemished/manufactured) cannot be converted to a non-inventory type (bundle/matrix) while it still carries any inventory ledger - a FIFO layer OR an inventory movement of any type (including stock_take, receipt, adjustment, transfer). This prevents orphaning stock layers and movements.\n\nFor update (PUT), additional field available:\n- initial_inventory.warehouses[].id (required with initial_inventory)\n- initial_inventory.warehouses[].quantity (required)\n- initial_inventory.warehouses[0].unit_cost (required)\n- images[].id — required only when images[].operation is delete\n- images[].operation — nullable|in:update_create,delete\n\n**Optional field:** `mpn` (string, max 255, nullable) — manufacturer part number.\n\n**Optional field:** `hts_code` (string, max 255, nullable) — Harmonized Tariff Schedule code.\n\nReturns 422 if product type change is invalid.\n\n**Bundle / Kit components:** When the resulting product type is `bundle` or `kit`, `components[]` must be present and non-empty. This applies whether you are (a) changing the type from `standard` → `bundle|kit`, (b) updating an existing bundle/kit that currently has no components, or (c) sending an empty `components: []` payload (which would otherwise wipe components). Returns a 422 validation error on the `components` field in these cases. Updates that don't touch `components` on a bundle/kit which already has components are unaffected. To convert a `standard` product that has no components yet, supply `components[]` in the same request as the `type` change — the components are saved as part of the same update, satisfying the requirement atomically.\n\n**Note (pricing tiers):** When sending `suppliers[].pricing[]` entries with `operation: updateOrCreate` (or omitted), `price` is **required** and must be a numeric value `>= 0` and `< 100000`. To remove a tier, send `operation: \"delete\"`. Sending `price: null` will return a `422` validation error on `suppliers.{i}.pricing.{j}.price`.\n\n**Lot tracking fields** (optional):\n- `is_lot_tracked` (boolean, nullable) — enable batch/lot tracking for this product.\n- `lot_tracking_method` (string, nullable) — required when `is_lot_tracked` is true. Allowed values: `fifo` (First-In, First-Out), `fefo` (First-Expiry, First-Out).\n\n**Stock unit of measure** (optional):\n- `stock_uom_id` (integer, nullable) — id of a row in `units_of_measure`. When omitted, the product is auto-assigned `EACH` as its stock UoM on create. Pick `KG`, `L`, etc. for bulk weight or volume products so quantities, purchase orders, sales orders, and stock takes use the correct unit from day one.\n\nAlso accepts expiration_offset_months (integer 0-120, nullable) — the product's default FBA-inbound shelf-life estimate in months; blank uses the app default (10). Responses include it too.","body":{"mode":"raw","raw":"{\n  \"sku\": \"SKU-001-UPDATED\",\n  \"name\": \"Updated Blue Widget\",\n  \"type\": \"standard\",\n  \"is_lot_tracked\": true,\n  \"lot_tracking_method\": \"fifo\",\n  \"shelf_life_days\": 180,\n  \"near_expiry_threshold_days\": 60,\n  \"min_remaining_shelf_life_days\": 105,\n  \"expiry_aware_availability\": true,\n  \"barcode\": \"1234567890124\",\n  \"mpn\": \"MPN-12345\",\n  \"hts_code\": \"8471.30.0100\",\n  \"brand_name\": \"Acme Co\",\n  \"weight\": 0.6,\n  \"weight_unit\": \"kg\",\n  \"min_stock_level\": 60,\n  \"target_stock_days\": 45,\n  \"stock_uom_id\": null,\n  \"pricing\": [\n    {\n      \"product_pricing_tier_name\": \"Default\",\n      \"price\": 34.99\n    }\n  ],\n  \"suppliers\": [\n    {\n      \"supplier_id\": 5,\n      \"is_default\": true,\n      \"supplier_sku\": \"MS-BW-001-V2\",\n      \"leadtime\": 10,\n      \"minimum_order_quantity\": 50\n    }\n  ],\n  \"tags\": [\n    \"updated\"\n  ],\n  \"initial_inventory\": {\n    \"warehouses\": [\n      {\n        \"id\": 1,\n        \"quantity\": 100,\n        \"unit_cost\": 12.5\n      }\n    ]\n  },\n  \"shared_children_attributes\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"SKU-001-UPDATED\",\n    \"name\": \"Updated Blue Widget\",\n    \"type\": \"standard\",\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 180,\n    \"near_expiry_threshold_days\": 60,\n    \"min_remaining_shelf_life_days\": 105,\n    \"expiry_aware_availability\": true,\n    \"updated_at\": \"2024-06-15T14:00:00.000000Z\"\n  },\n  \"message\": \"Product SKU-001-UPDATED updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]},"description":"Delete a product by ID. Deletion fails if the product (or, for a matrix parent, any of its variations) is still referenced by a RESTRICT foreign key: sales order lines, bundle sales order lines, purchase order lines, inventory movements, FIFO layers, inventory adjustments, assembly lines, warehouse transfer lines, return receipt lines, RMA lines, sales credit lines, inbound shipment lines, blemished products, or subscription editions.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 Bad Request with reason details if the product is in use."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/products/{id}","host":["{{baseUrl}}"],"path":["api","products",":id"],"variable":[{"key":"id","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product SKU-001 deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Product by SKU","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/by-sku?sku=SKU-001","host":["{{baseUrl}}"],"path":["api","products","by-sku"],"query":[{"key":"sku","value":"SKU-001","description":"Required. Exact SKU to look up.","disabled":true}]},"description":"Get a product by its exact SKU.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 422 if sku parameter is missing. Returns 404 (ModelNotFoundException) if SKU not found."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/by-sku?sku=SKU-001","host":["{{baseUrl}}"],"path":["api","products","by-sku"],"query":[{"key":"sku","value":"SKU-001","description":"Required. Exact SKU to look up.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"SKU-001\",\n    \"name\": \"Blue Widget\",\n    \"type\": \"standard\",\n    \"archived_at\": null\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products?page=1&limit=10&search=&sort=sku&archived=0&included[]=sku&excluded[]=&filter[type]=&filter[brand]=&filter[category]=&filter[tag]=&filter[supplier]=&supplier_id=","host":["{{baseUrl}}"],"path":["api","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"search","value":"","description":"Search by SKU, name, or barcode","disabled":true},{"key":"sort","value":"sku","description":"Sort field. Prefix with - for descending (e.g. -sku). Allowed: sku, name, barcode, type, created_at, updated_at, inventory_total, inventory_available, average_cost","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only, 2 = all","disabled":true},{"key":"included[]","value":"sku","description":"Columns to include in response. Repeat for multiple.","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude. Cannot be used with included[].","disabled":true},{"key":"filter[type]","value":"","description":"Filter by product type: standard, bundle, kit, matrix","disabled":true},{"key":"filter[brand]","value":"","description":"Filter by brand name","disabled":true},{"key":"filter[category]","value":"","description":"Filter by category","disabled":true},{"key":"filter[tag]","value":"","description":"Filter by tag","disabled":true},{"key":"filter[supplier]","value":"","description":"Filter by supplier name or ID","disabled":true},{"key":"supplier_id","value":"","description":"Filter variations shown in the response to those belonging to a specific supplier","disabled":true}]},"description":"List all products. Supports searching, sorting, filtering, pagination, and column selection.\n\nAuthentication: Requires Bearer token.\n\nFilter scopes available on the Product model:\n- filter[type]: standard | bundle | kit | matrix\n- filter[brand]: brand name string\n- filter[category]: category name or path\n- filter[tag]: tag name\n- filter[supplier]: supplier name or ID\n\nSort fields: sku, name, barcode, type, created_at, updated_at, inventory_total, inventory_available, average_cost\n\nInclusion columns: sku, id, name, barcode, type, image, image_url, brand, price, weight, weight_unit, length, width, height, dimension_unit, case_quantity, inventory_total, inventory_available, inventory_allocated, inventory_on_hold, inventory_in_transit, inventory_incoming, average_cost, default_supplier, default_supplier_sku, suppliers, tags, attributes, created_at, updated_at, archived_at\n\n**Stock UoM filters (added 2026-05-30):**\n- `filter[stock_uom_id]` — by uom_id (exact, comma-separated)\n- `filter[stock_uom_code]` — by UoM code (advanced text ops)\n- `filter[stock_uom_name]` — by UoM display name (advanced text ops)\n\nThe `hts_code` (Harmonized Tariff Schedule code) column can be returned via `included[]=hts_code`. Filtering (`filter[hts_code]`) and sorting by `hts_code` are available on the `/api/v2/products` endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products?page=1&limit=10&search=&sort=sku&archived=0&included[]=sku&excluded[]=&filter[type]=&filter[brand]=&filter[category]=&filter[tag]=&filter[supplier]=&supplier_id=","host":["{{baseUrl}}"],"path":["api","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"limit","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"search","value":"","description":"Search by SKU, name, or barcode","disabled":true},{"key":"sort","value":"sku","description":"Sort field. Prefix with - for descending (e.g. -sku). Allowed: sku, name, barcode, type, created_at, updated_at, inventory_total, inventory_available, average_cost","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only, 2 = all","disabled":true},{"key":"included[]","value":"sku","description":"Columns to include in response. Repeat for multiple.","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude. Cannot be used with included[].","disabled":true},{"key":"filter[type]","value":"","description":"Filter by product type: standard, bundle, kit, matrix","disabled":true},{"key":"filter[brand]","value":"","description":"Filter by brand name","disabled":true},{"key":"filter[category]","value":"","description":"Filter by category","disabled":true},{"key":"filter[tag]","value":"","description":"Filter by tag","disabled":true},{"key":"filter[supplier]","value":"","description":"Filter by supplier name or ID","disabled":true},{"key":"supplier_id","value":"","description":"Filter variations shown in the response to those belonging to a specific supplier","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"sku\": \"SKU-001\",\n      \"name\": \"Blue Widget\",\n      \"barcode\": 123456789012,\n      \"hts_code\": \"8471.30.0100\",\n      \"type\": \"standard\",\n      \"image_url\": \"https://cdn.example.com/products/blue-widget.jpg\",\n      \"brand\": {\n        \"id\": 3,\n        \"name\": \"Acme Co\"\n      },\n      \"price\": {\n        \"Default\": {\n          \"price\": 29.99\n        }\n      },\n      \"weight\": \"0.5\",\n      \"weight_unit\": \"kg\",\n      \"inventory_total\": 150,\n      \"inventory_available\": 120,\n      \"inventory_available_to_sell\": 115,\n      \"inventory_allocated\": 30,\n      \"average_cost\": {\n        \"value\": 12.5,\n        \"currency\": \"USD\"\n      },\n      \"inventory_avg_cost\": {\n        \"value\": 11.85,\n        \"currency\": \"USD\"\n      },\n      \"archived_at\": null,\n      \"stock_uom_id\": 1,\n      \"stock_uom_code\": \"EACH\",\n      \"stock_uom_name\": \"Each\",\n      \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n      \"updated_at\": \"2024-06-01T08:00:00.000000Z\"\n    }\n  ],\n  \"table_specifications\": {\n    \"columns\": [\n      {\n        \"data_name\": \"sku\",\n        \"label\": \"SKU\",\n        \"default_visible\": 1,\n        \"sortable\": true\n      }\n    ]\n  },\n  \"links\": {\n    \"first\": \"https://sku2.test/api/products?page=1\",\n    \"last\": \"https://sku2.test/api/products?page=10\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"last_page\": 10,\n    \"per_page\": 10,\n    \"total\": 98\n  }\n}"}]},{"name":"Create Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products","host":["{{baseUrl}}"],"path":["api","products"]},"description":"Create a new product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired fields: sku (unique), type\nProduct types: standard, bundle, kit, matrix\nWeight units: kg, lb, oz, g\nDimension units: cm, in, mm, ft\n\nFor bundle/kit products, `components[]` is **required** and must contain at least one component (each entry has `id` and `quantity`). Saving a bundle or kit with an empty `components` array (or without providing one when creating, or when changing type to bundle/kit) returns a 422 validation error on the `components` field.\nFor matrix products (parent), include variations[] with sku and attributes.\n\n**Optional field:** `mpn` (string, max 255, nullable) — manufacturer part number.\n\n**Optional field:** `hts_code` (string, max 255, nullable) — Harmonized Tariff Schedule code.\n\nReturns 422 validation error if SKU already exists or other validation fails.\n\n**Note (pricing tiers):** When sending `suppliers[].pricing[]` entries with `operation: updateOrCreate` (or omitted), `price` is **required** and must be a numeric value `>= 0` and `< 100000`. To remove a tier, send `operation: \"delete\"`. Sending `price: null` will return a `422` validation error on `suppliers.{i}.pricing.{j}.price`.\n\n**Lot tracking fields** (optional):\n- `is_lot_tracked` (boolean, nullable) — enable batch/lot tracking for this product.\n- `lot_tracking_method` (string, nullable) — required when `is_lot_tracked` is true. Allowed values: `fifo` (First-In, First-Out), `fefo` (First-Expiry, First-Out).\n\n**Stock unit of measure** (optional):\n- `stock_uom_id` (integer, nullable) — id of a row in `units_of_measure`. When omitted, the product is auto-assigned `EACH` as its stock UoM on create. Pick `KG`, `L`, etc. for bulk weight or volume products so quantities, purchase orders, sales orders, and stock takes use the correct unit from day one.\n\n**Requires permission:** `products.create`\n\nAlso accepts expiration_offset_months (integer 0-120, nullable) — the product's default FBA-inbound shelf-life estimate in months; blank uses the app default (10). Responses include it too.","body":{"mode":"raw","raw":"{\n  \"sku\": \"SKU-NEW-001\",\n  \"name\": \"New Product\",\n  \"type\": \"standard\",\n  \"is_lot_tracked\": true,\n  \"lot_tracking_method\": \"fifo\",\n  \"shelf_life_days\": 180,\n  \"near_expiry_threshold_days\": 60,\n  \"min_remaining_shelf_life_days\": 105,\n  \"expiry_aware_availability\": true,\n  \"barcode\": \"1234567890123\",\n  \"mpn\": \"MPN-12345\",\n  \"hts_code\": \"8471.30.0100\",\n  \"brand_name\": \"Acme Co\",\n  \"weight\": 0.5,\n  \"weight_unit\": \"kg\",\n  \"length\": 10,\n  \"width\": 5,\n  \"height\": 3,\n  \"dimension_unit\": \"cm\",\n  \"case_quantity\": 12,\n  \"case_weight\": 6,\n  \"case_weight_unit\": \"kg\",\n  \"case_length\": 30,\n  \"case_width\": 20,\n  \"case_height\": 15,\n  \"case_dimension_unit\": \"cm\",\n  \"fba_prep_instructions\": \"Bubble wrap required\",\n  \"target_stock_days\": 30,\n  \"min_stock_level\": 50,\n  \"proforma_landed_cost_percentage\": 5,\n  \"proforma_shipping_cost\": 2.5,\n  \"stock_uom_id\": null,\n  \"sales_nominal_code_id\": null,\n  \"cogs_nominal_code_id\": null,\n  \"default_tax_rate_id\": null,\n  \"is_dropshippable\": false,\n  \"is_decoration_consumable\": false,\n  \"parent_id\": null,\n  \"tags\": [\n    \"new\",\n    \"featured\"\n  ],\n  \"tags_operation\": \"set\",\n  \"pricing\": [\n    {\n      \"product_pricing_tier_name\": \"Default\",\n      \"price\": 29.99\n    }\n  ],\n  \"suppliers\": [\n    {\n      \"supplier_id\": 5,\n      \"is_default\": true,\n      \"supplier_sku\": \"MS-BW-001\",\n      \"leadtime\": 14,\n      \"minimum_order_quantity\": 100,\n      \"pricing\": [\n        {\n          \"supplier_pricing_tier_name\": \"Default\",\n          \"price\": 10\n        }\n      ]\n    }\n  ],\n  \"categories\": [\n    {\n      \"category_id\": 2,\n      \"is_primary\": true\n    }\n  ],\n  \"attributes\": [\n    {\n      \"name\": \"Color\",\n      \"value\": \"Blue\"\n    }\n  ],\n  \"images\": [\n    {\n      \"url\": \"https://example.com/images/blue-widget.jpg\",\n      \"name\": \"Main Image\",\n      \"is_primary\": true,\n      \"download\": false\n    }\n  ],\n  \"components\": [],\n  \"variations\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products","host":["{{baseUrl}}"],"path":["api","products"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"sku\": \"SKU-NEW-001\",\n    \"name\": \"New Product\",\n    \"type\": \"standard\",\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 180,\n    \"near_expiry_threshold_days\": 60,\n    \"min_remaining_shelf_life_days\": 105,\n    \"expiry_aware_availability\": true,\n    \"barcode\": \"1234567890123\",\n    \"hts_code\": \"8471.30.0100\",\n    \"archived_at\": null,\n    \"created_at\": \"2024-06-15T12:00:00.000000Z\",\n    \"updated_at\": \"2024-06-15T12:00:00.000000Z\"\n  },\n  \"message\": \"Product created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Products","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/products","host":["{{baseUrl}}"],"path":["api","products"]},"description":"Bulk delete multiple products. For large datasets, deletion is processed in the background via a queue.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields (one required):\n- ids (array): specific product IDs to delete\n- filters (object): filter criteria to select products for deletion\n\n**Requires permission:** `products.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/products","host":["{{baseUrl}}"],"path":["api","products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Duplicate Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{product}/duplicate","host":["{{baseUrl}}"],"path":["api","products",":product","duplicate"],"variable":[{"key":"product","value":"42","description":"ID of the product to duplicate"}]},"description":"Duplicate an existing product into a brand-new one with its own SKU.\n\nThe new product copies the source's identity-adjacent configuration - name, brand, type, dimensions, unit cost, financial line type, flags, attributes, categories, pricing tiers, suppliers (and their pricing), units of measure, tags, images, and kit/bundle components - but starts with zero inventory: no stock movements, FIFO layers, inventory cache, or channel listings. The barcode and inventory/velocity-derived figures (average cost, quantities sold, ABC/XYZ classification) are reset.\n\nA new unique `sku` is required. When `name` is omitted it defaults to the source name suffixed with \" (copy)\".\n\nMatrix (variation) products and variation children cannot be duplicated and return 422.\n\nRequires a Bearer token with the `products.create` permission.","body":{"mode":"raw","raw":"{\n  \"sku\": \"SKU-NEW-001-COPY\",\n  \"name\": \"New Product (copy)\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/{product}/duplicate","host":["{{baseUrl}}"],"path":["api","products",":product","duplicate"],"variable":[{"key":"product","value":"42","description":"ID of the product to duplicate"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 108,\n    \"sku\": \"SKU-NEW-001-COPY\",\n    \"name\": \"New Product (copy)\",\n    \"type\": \"standard\",\n    \"barcode\": null,\n    \"brand_name\": \"Acme Co\",\n    \"weight\": 0.5,\n    \"weight_unit\": \"kg\",\n    \"average_cost\": null,\n    \"archived_at\": null,\n    \"created_at\": \"2024-06-15T12:00:00.000000Z\",\n    \"updated_at\": \"2024-06-15T12:00:00.000000Z\"\n  },\n  \"message\": \"The product 'SKU-NEW-001-COPY' was duplicated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Constants","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/constants","host":["{{baseUrl}}"],"path":["api","products","constants"]},"description":"Returns enumeration constants used in product forms: product types, weight units, dimension units, attribute types, warehouse types, and inventory movement types.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/constants","host":["{{baseUrl}}"],"path":["api","products","constants"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_types\": [\n      \"standard\",\n      \"bundle\",\n      \"kit\",\n      \"matrix\"\n    ],\n    \"weight_units\": [\n      \"kg\",\n      \"lb\",\n      \"oz\",\n      \"g\"\n    ],\n    \"dimension_units\": [\n      \"cm\",\n      \"in\",\n      \"mm\",\n      \"ft\"\n    ],\n    \"attribute_types\": [\n      \"text\",\n      \"number\",\n      \"date\",\n      \"boolean\"\n    ],\n    \"warehouse_types\": [\n      \"standard\",\n      \"amazon_fba\",\n      \"supplier\"\n    ],\n    \"inventory_movement_type\": [\n      \"purchase\",\n      \"sale\",\n      \"adjustment\",\n      \"transfer\"\n    ],\n    \"inventory_movement_status\": [\n      \"available\",\n      \"allocated\",\n      \"on_hold\",\n      \"in_transit\"\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Create Product Form","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/create","host":["{{baseUrl}}"],"path":["api","products","create"]},"description":"Returns the data needed to pre-populate the create product form.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/create","host":["{{baseUrl}}"],"path":["api","products","create"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {},\n  \"status\": \"success\"\n}"}]},{"name":"Get Edit Product Form","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/edit","host":["{{baseUrl}}"],"path":["api","products",":product","edit"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Returns the product data pre-populated for the edit form.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/edit","host":["{{baseUrl}}"],"path":["api","products",":product","edit"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"SKU-001\",\n    \"name\": \"Blue Widget\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Search Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/search?q=blue","host":["{{baseUrl}}"],"path":["api","products","search"],"query":[{"key":"q","value":"blue","description":"Required. Search term (min 2 chars). Searches SKU, name, and barcode with fuzzy matching.","disabled":true}]},"description":"Search products by SKU, name, or barcode. Results are ranked by a 9-tier relevance scheme so typing a full SKU surfaces the exact product first:\n  1. Exact SKU match\n  2. Exact barcode match\n  3. Exact name match\n  4. SKU starts with the query\n  5. Barcode starts with the query\n  6. Name starts with the query\n  7. SKU contains the query (anywhere)\n  8. Name contains the query (anywhere)\n  9. Anything else (barcode contains, etc.)\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOnly active (non-archived) products are returned.\n\nAuthentication: Requires Bearer token.\n\nMinimum query length: 2 characters.\n\nOptional `with` parameter (allowlist): pass `with=inventory` to include warehouse-aggregate inventory totals (`inventory_available`, `inventory_allocated`, `inventory_on_hold`) in each result.\n\nOptional `simple_assembleable=1` filter: restricts results to products that can actually be assembled or disassembled via Manufacturing Simple Mode (have an active default BOM with component lines, or legacy kit components). Anything else would fail at submit, so the picker blocks it.\n\n**Stock UoM fields:** When the product's `stockProductUom.unitOfMeasure` relation is eager-loaded (this endpoint always loads it), each item additionally exposes `stock_uom_id`, `stock_uom_code` (e.g. `KG`), and `stock_uom_name`. The legacy nested `stock_uom` object is still emitted via `?with=stock_uom`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/search?q=blue","host":["{{baseUrl}}"],"path":["api","products","search"],"query":[{"key":"q","value":"blue","description":"Required. Search term (min 2 chars). Searches SKU, name, and barcode with fuzzy matching.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"sku\": \"SKU-001\",\n      \"name\": \"Blue Widget\",\n      \"barcode\": 123456789012,\n      \"type\": \"standard\",\n      \"stock_uom_id\": 1,\n      \"stock_uom_code\": \"EACH\",\n      \"stock_uom_name\": \"Each\",\n      \"inventory_available\": 42,\n      \"inventory_allocated\": 8,\n      \"inventory_on_hold\": 2\n    },\n    {\n      \"id\": 2,\n      \"sku\": \"SKU-002\",\n      \"name\": \"Blue Widget Pro\",\n      \"barcode\": 123456789013,\n      \"type\": \"standard\",\n      \"stock_uom_id\": 1,\n      \"stock_uom_code\": \"EACH\",\n      \"stock_uom_name\": \"Each\",\n      \"inventory_available\": 15,\n      \"inventory_allocated\": 0,\n      \"inventory_on_hold\": 0\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Barcode Lookup","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/barcode-lookup?code=123456789012","host":["{{baseUrl}}"],"path":["api","products","barcode-lookup"],"query":[{"key":"code","value":"123456789012","description":"Required. Barcode or SKU to look up (exact match only, no fuzzy matching).","disabled":true}]},"description":"Exact-match barcode or SKU lookup for barcode scanning. Prioritises barcode match first, then falls back to SKU match. Only active products are returned. Returns null in data if no match found.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/barcode-lookup?code=123456789012","host":["{{baseUrl}}"],"path":["api","products","barcode-lookup"],"query":[{"key":"code","value":"123456789012","description":"Required. Barcode or SKU to look up (exact match only, no fuzzy matching).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"SKU-001\",\n    \"name\": \"Blue Widget\",\n    \"barcode\": 123456789012\n  }\n}"}]},{"name":"Check Product Deletability","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/is-deletable","host":["{{baseUrl}}"],"path":["api","products","is-deletable"]},"description":"Check whether one or more products can be safely deleted. Returns deletability status with reasons and usage record samples for each product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): array of product IDs (integers, must exist in DB)\n\nFor each product, returns:\n- deletable: true if safe to delete\n- reason: human-readable reason if not deletable\n- usages: array of blocking usage types, each with: relation, label, count, message, and sample records\n\nUsage relations include: salesOrderLines, bundleSalesOrderLines, purchaseOrderLines, inventoryMovements, fifoLayers, inventoryAdjustments, inventoryAssemblyLines, warehouseTransferLines, returnReceiptLines, rmaLines, salesCreditLines, blemishedProducts, inboundShipmentLines, and subscriptionEditions (each is a RESTRICT foreign key, so any referencing row blocks deletion; product variations are checked too, so a matrix parent is reported not deletable when any of its variants is referenced). bundleSalesOrderLines appears when the product was sold as a bundle parent (referenced via sales_order_lines.bundle_id, a RESTRICT foreign key); such bundles are reported as not deletable so they can be archived instead.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/is-deletable","host":["{{baseUrl}}"],"path":["api","products","is-deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Blue Widget\",\n      \"sku\": \"SKU-001\",\n      \"deletable\": false,\n      \"reason\": \"There are 5 sales order lines associated with this product(SKU-001).\",\n      \"usages\": [\n        {\n          \"relation\": \"salesOrderLines\",\n          \"label\": \"Sales Order Lines\",\n          \"count\": 5,\n          \"message\": \"There are 5 sales order lines associated with this product(SKU-001).\",\n          \"records\": [\n            {\n              \"label\": \"SO-1001\",\n              \"detail\": \"Qty: 2\"\n            },\n            {\n              \"label\": \"SO-1002\",\n              \"detail\": \"Qty: 1\"\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Starter Bundle Kit\",\n      \"sku\": \"BNDL-100\",\n      \"deletable\": false,\n      \"reason\": \"There are 4 bundle sales order lines associated with this product(BNDL-100).\",\n      \"usages\": [\n        {\n          \"relation\": \"bundleSalesOrderLines\",\n          \"label\": \"Bundle Sales Order Lines\",\n          \"count\": 4,\n          \"message\": \"There are 4 bundle sales order lines associated with this product(BNDL-100).\",\n          \"records\": [\n            {\n              \"label\": \"SO-2001\",\n              \"detail\": \"Qty: 1\"\n            },\n            {\n              \"label\": \"SO-2002\",\n              \"detail\": \"Qty: 3\"\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Red Widget\",\n      \"sku\": \"SKU-002\",\n      \"deletable\": true,\n      \"reason\": null,\n      \"usages\": []\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Archive Product","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/products/{id}/archive","host":["{{baseUrl}}"],"path":["api","products",":id","archive"],"variable":[{"key":"id","value":"1","description":"Product ID"}]},"description":"Archive a product by ID. Sets archived_at timestamp.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns a warning if the product is already archived.\n\n**Requires permission:** `products.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{id}/archive","host":["{{baseUrl}}"],"path":["api","products",":id","archive"],"variable":[{"key":"id","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product SKU-001 archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Product","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/products/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","products",":id","unarchived"],"variable":[{"key":"id","value":"1","description":"Product ID"}]},"description":"Unarchive a product by ID. Clears the archived_at timestamp.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `products.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","products",":id","unarchived"],"variable":[{"key":"id","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product SKU-001 unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/archive","host":["{{baseUrl}}"],"path":["api","products","archive"]},"description":"Bulk archive multiple products.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array): specific product IDs to archive\n- apply_to_all (boolean): if true, applies to all products matching the current filters instead of ids\n- filters (object): filter criteria used when apply_to_all is true\n\n**Requires permission:** `products.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/archive","host":["{{baseUrl}}"],"path":["api","products","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/unarchive","host":["{{baseUrl}}"],"path":["api","products","unarchive"]},"description":"Bulk unarchive multiple products.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array): specific product IDs to unarchive\n- apply_to_all (boolean): if true, applies to all matching products\n- filters (object): filter criteria used when apply_to_all is true\n\n**Requires permission:** `products.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/unarchive","host":["{{baseUrl}}"],"path":["api","products","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory?no_fba=false&no_suppliers=false&legacy_mode=false&include_mcf=false","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory"],"query":[{"key":"no_fba","value":"false","description":"Exclude FBA warehouses from response (boolean)","disabled":true},{"key":"no_suppliers","value":"false","description":"Exclude supplier warehouses from response (boolean)","disabled":true},{"key":"legacy_mode","value":"false","description":"Use legacy inventory mode without Pan-EU FBA rollup (boolean)","disabled":true},{"key":"include_mcf","value":"false","description":"Include MCF inventory (boolean)","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get detailed inventory breakdown for a product across all warehouses. Includes FBA real-time data, Pan-EU rollup, supplier drop-ship inventory, and purchase order inbound quantities.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\nEach warehouse row and the totals include `non_sellable` — physically-present stock in non-sellable bins (excluded from `available` but included in on-hand)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory?no_fba=false&no_suppliers=false&legacy_mode=false&include_mcf=false","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory"],"query":[{"key":"no_fba","value":"false","description":"Exclude FBA warehouses from response (boolean)","disabled":true},{"key":"no_suppliers","value":"false","description":"Exclude supplier warehouses from response (boolean)","disabled":true},{"key":"legacy_mode","value":"false","description":"Use legacy inventory mode without Pan-EU FBA rollup (boolean)","disabled":true},{"key":"include_mcf","value":"false","description":"Include MCF inventory (boolean)","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": {\n      \"inbound\": false,\n      \"stock\": false,\n      \"allocated\": false,\n      \"backorder_planned\": false,\n      \"backorder_awaiting_receipt\": false,\n      \"backorder\": false,\n      \"on_hold\": false,\n      \"available\": false,\n      \"available_to_sell\": false,\n      \"in_transit\": false,\n      \"backordered\": false,\n      \"consigned\": false,\n      \"non_sellable\": 15\n    },\n    \"unit_cost\": 12.5,\n    \"warehouses\": {\n      \"Main Warehouse\": {\n        \"inbound\": false,\n        \"stock\": false,\n        \"allocated\": false,\n        \"backorder_planned\": false,\n        \"backorder_awaiting_receipt\": false,\n        \"backorder\": false,\n        \"on_hold\": false,\n        \"available\": false,\n        \"available_to_sell\": false,\n        \"in_transit\": false,\n        \"warehouse_id\": false,\n        \"warehouse_name\": false,\n        \"warehouse_type\": false,\n        \"initial_inventory\": false,\n        \"supplier\": false,\n        \"listing_count\": false,\n        \"country_code\": false,\n        \"consigned\": false,\n        \"non_sellable\": 15\n      }\n    },\n    \"bundle_data\": [],\n    \"cache_updated_at\": \"2024-06-15T12:00:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Available Lots (FEFO)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/available-lots?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","products",":productId","available-lots"],"query":[{"key":"warehouse_id","value":"1","description":"REQUIRED. Warehouse to list available lots for (integer, must exist in warehouses). The endpoint returns 422 if omitted.","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Active FIFO layers available to CONSUME for a product in a given warehouse — only layers with remaining (unfulfilled) quantity are returned.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nLayers are ordered by the product's removal strategy: FEFO products list soonest-expiry first with undated lots last; FIFO products list by layer date. This drives the lot-override picker (LotConsumptionPanel) and its FEFO pre-fill on negative inventory events (fulfillment, transfer ship, decrease adjustment).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- productId: Product ID\n\nQuery params:\n- warehouse_id (REQUIRED, integer, exists:warehouses,id): warehouse to scope available lots to. Returns 422 if missing.\n\nResponse (wrapped in {data}) — array of lots:\n- fifo_layer_id (int): FIFO layer ID to reference in a lot_allocation override\n- batch_number (string|null): lot/batch number\n- expiry_date (date|null, YYYY-MM-DD): lot expiry date\n- manufacture_date (date|null, YYYY-MM-DD): lot manufacture date\n- available_quantity (float): remaining quantity available to consume from this layer\n- fifo_layer_date (date|null, YYYY-MM-DD): the layer's FIFO date\n- days_to_expiry (int|null): whole days until expiry (negative if already expired); null when undated\n- is_expired (bool): whether the lot's expiry date is before today\n- avg_cost (float): average unit cost of the layer"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/available-lots?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","products",":productId","available-lots"],"query":[{"key":"warehouse_id","value":"1","description":"REQUIRED. Warehouse to list available lots for (integer, must exist in warehouses). The endpoint returns 422 if omitted.","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fifo_layer_id\": 5012,\n      \"batch_number\": \"LOT-A\",\n      \"expiry_date\": \"2030-01-31\",\n      \"manufacture_date\": \"2026-01-01\",\n      \"available_quantity\": 40,\n      \"fifo_layer_date\": \"2026-01-10\",\n      \"days_to_expiry\": 1321,\n      \"is_expired\": false,\n      \"avg_cost\": 12.5\n    },\n    {\n      \"fifo_layer_id\": 5040,\n      \"batch_number\": null,\n      \"expiry_date\": null,\n      \"manufacture_date\": null,\n      \"available_quantity\": 15,\n      \"fifo_layer_date\": \"2026-02-02\",\n      \"days_to_expiry\": null,\n      \"is_expired\": false,\n      \"avg_cost\": 11.75\n    }\n  ]\n}"}]},{"name":"Get FBA Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{warehouseId}/{productId}/inventory-fba","host":["{{baseUrl}}"],"path":["api","products",":warehouseId",":productId","inventory-fba"],"variable":[{"key":"warehouseId","value":"2","description":"Warehouse ID (must be Amazon FBA type)"},{"key":"productId","value":"1","description":"Product ID"}]},"description":"Returns the Amazon FBA inventory listings for a product at a specific warehouse. Each row is an FBA-enabled product listing on the warehouse's sales channel, with its real-time FBA inventory snapshot (available, reserved, in transit, total, inbound) and Amazon **condition** (e.g. `NewItem`, `UsedLikeNew`). Rows are sorted by available quantity descending. Listings are scoped to the warehouse's marketplace (the warehouse `country_code`): a US FBA warehouse returns only US listings, never another marketplace's listing (e.g. a Canadian one), mirroring how Amazon MCF fulfils from the destination's marketplace.\n\nNote: Amazon MCF only fulfills New-condition inventory — listings with a non-New `condition` cannot be fulfilled via createFulfillmentOrder even when `available` is greater than 0.\n\nAuthentication: Requires Bearer token. Rows come from two sources: (1) Amazon listings mapped to this product via product_listings, and (2) the FNSKU mapper — the seller SKU (MSKU) behind each SELLABLE FNSKU mapped to this product in the warehouse marketplace, with its FBA report stock. Source 2 lets a product whose marketplace listing is mapped to a different SKU.io product (a per-market \"-CA-O\" shadow listing) still surface its shippable seller SKU, so Amazon MCF submission resolves correctly. Mirrors ResolveFbaSellerSku.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{warehouseId}/{productId}/inventory-fba","host":["{{baseUrl}}"],"path":["api","products",":warehouseId",":productId","inventory-fba"],"variable":[{"key":"warehouseId","value":"2","description":"Warehouse ID (must be Amazon FBA type)"},{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 2,\n      \"product_listing_id\": 9380,\n      \"seller_sku\": \"BTS-AA-FBA-USED\",\n      \"asin\": \"B07XYZ1234\",\n      \"condition\": \"UsedLikeNew\",\n      \"available\": 1,\n      \"reserved\": 0,\n      \"in_transit\": 0,\n      \"total\": 1,\n      \"inbound\": 0\n    },\n    {\n      \"integration_instance_id\": 2,\n      \"product_listing_id\": 9381,\n      \"seller_sku\": \"2291988-FBA-1\",\n      \"asin\": \"B07ABC5678\",\n      \"condition\": \"NewItem\",\n      \"available\": 13,\n      \"reserved\": 2,\n      \"in_transit\": 0,\n      \"total\": 15,\n      \"inbound\": 5\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Refresh Inventory Cache","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory/refresh","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory","refresh"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Synchronously refreshes the inventory cache for a specific product. This forces a recalculation of inventory totals and average cost.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 500 if the refresh fails."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory/refresh","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory","refresh"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory cache refreshed successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Sales Channel Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/get-sales-channel-inventory","host":["{{baseUrl}}"],"path":["api","products",":product","get-sales-channel-inventory"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Get inventory broken down by sales channel for a specific product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/get-sales-channel-inventory","host":["{{baseUrl}}"],"path":["api","products",":product","get-sales-channel-inventory"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_channel\": \"Shopify Store\",\n      \"available\": 80,\n      \"allocated\": 20\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Last Purchase Price","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/last-purchase-price","host":["{{baseUrl}}"],"path":["api","products",":product","last-purchase-price"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Get the most recent purchase price for a product from non-draft purchase orders.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns null in data if no purchase order lines exist with a positive amount."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/last-purchase-price","host":["{{baseUrl}}"],"path":["api","products",":product","last-purchase-price"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"amount\": 10,\n    \"purchase_order_id\": 55,\n    \"purchase_order_date\": \"2024-05-15\"\n  }\n}"}]},{"name":"Get Product Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory-movements?page=1&limit=10&sort=-created_at&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix - for descending.","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get paginated inventory movements for a specific product.\n\nAuthentication: Requires Bearer token.\n\nResponse includes movements with type, quantity, warehouse, FIFO layer, and reference data."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/inventory-movements?page=1&limit=10&sort=-created_at&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","products",":productId","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix - for descending.","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"inventory_movement_date\": \"2024-06-01\",\n      \"product_id\": 1,\n      \"sku\": \"SKU-001\",\n      \"type\": {\n        \"name\": \"purchase\",\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n        \"link_id\": 55,\n        \"parent_link_id\": 10,\n        \"detail_link_id\": null,\n        \"manufacturing_order\": null\n      },\n      \"inventory_status\": \"available\",\n      \"quantity\": 100,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"layer\": {\n        \"fifo_layer_id\": 3,\n        \"name\": \"Layer 2024-06-01\"\n      },\n      \"reference\": \"PO-1001\",\n      \"created_at\": \"2024-06-01T10:00:00.000000Z\"\n    }\n  ],\n  \"table_specifications\": {},\n  \"meta\": {\n    \"current_page\": 1,\n    \"last_page\": 5,\n    \"per_page\": 10,\n    \"total\": 48\n  }\n}"}]},{"name":"Get Product FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/fifo-layers","host":["{{baseUrl}}"],"path":["api","products",":productId","fifo-layers"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get FIFO cost layers for a specific product.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/fifo-layers","host":["{{baseUrl}}"],"path":["api","products",":productId","fifo-layers"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"product_id\": 1,\n      \"quantity\": 100,\n      \"unit_cost\": 12.5,\n      \"created_at\": \"2024-06-01T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Consignment Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/consignment/inventory","host":["{{baseUrl}}"],"path":["api","consignment","inventory"]},"description":"Consigned (supplier-owned) stock on hand that hasn't sold yet, one row per cost layer, with unit cost, total value, and days-on-consignment aging, plus the supplier and purchase order it came from. Drives the return-unsold workflow.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/consignment/inventory","host":["{{baseUrl}}"],"path":["api","consignment","inventory"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 40122,\n      \"sku\": \"WIDGET-1\",\n      \"product_id\": 881,\n      \"product_name\": \"Blue Widget\",\n      \"supplier_id\": 44,\n      \"supplier_name\": \"Acme Wholesale\",\n      \"warehouse_id\": 12,\n      \"warehouse_name\": \"Acme Consignment\",\n      \"purchase_order_id\": 10432,\n      \"purchase_order_number\": \"PO-10432\",\n      \"on_hand_quantity\": 40,\n      \"unit_cost\": 4,\n      \"total_value\": 160,\n      \"days_on_consignment\": 52\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Consignment Valuation Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/consignment/valuation-summary","host":["{{baseUrl}}"],"path":["api","consignment","valuation-summary"]},"description":"Off-balance-sheet valuation memo for consigned (supplier-owned) stock on hand. It reports the total value of consigned inventory you hold and the equal received-not-billed obligation that would arise if it were grossed up onto the balance sheet, broken down by supplier. Because the asset and obligation always offset, the net balance-sheet impact is zero. This is a disclosure only — it is never posted to the general ledger and is not synced to any accounting integration.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/consignment/valuation-summary","host":["{{baseUrl}}"],"path":["api","consignment","valuation-summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"consigned_inventory_value\": 12480,\n    \"received_not_billed_obligation\": 12480,\n    \"net_balance_sheet_impact\": 0,\n    \"total_on_hand_quantity\": 3120,\n    \"supplier_count\": 2,\n    \"suppliers\": [\n      {\n        \"supplier_id\": 44,\n        \"supplier_name\": \"Acme Wholesale\",\n        \"on_hand_quantity\": 2000,\n        \"total_value\": 8000\n      },\n      {\n        \"supplier_id\": 51,\n        \"supplier_name\": \"Globex Supply Co.\",\n        \"on_hand_quantity\": 1120,\n        \"total_value\": 4480\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Attributes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get all available attributes for a product, including direct attributes and those inherited from category attribute groups.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"Color\": {\n      \"id\": 1,\n      \"attribute_id\": 5,\n      \"name\": \"Color\",\n      \"value\": \"Blue\",\n      \"type\": \"text\",\n      \"attribute_group\": {\n        \"id\": 2,\n        \"name\": \"Product Details\"\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Product Attributes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Add or update attributes on a product. Syncs without detaching other existing attributes.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields in attributes[]:\n- id (required without name): attribute ID\n- name (required without id): attribute name (max 255)\n- value (nullable): attribute value\n\n**Requires permission:** `products.manage_variants`","body":{"mode":"raw","raw":"{\n  \"attributes\": [\n    {\n      \"id\": 5,\n      \"value\": \"Red\"\n    },\n    {\n      \"name\": \"Material\",\n      \"value\": \"Plastic\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product attributes updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Product Attributes","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Remove specific attributes from a product by attribute IDs.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- attributes (required, array, min 1): array of attribute IDs to remove (must exist in attributes table)\n\n**Requires permission:** `products.manage_variants`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product attributes 5,7,12 deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Attributes Grouped","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes-grouped","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes-grouped"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get product attributes organised into grouped (by attribute group) and direct (ungrouped) sections.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/attributes-grouped","host":["{{baseUrl}}"],"path":["api","products",":productId","attributes-grouped"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"direct\": [\n      {\n        \"id\": 1,\n        \"name\": \"Description\",\n        \"value\": \"A blue widget\"\n      }\n    ],\n    \"groups\": {\n      \"2\": {\n        \"id\": 2,\n        \"name\": \"Product Details\",\n        \"attributes\": [\n          {\n            \"id\": 2,\n            \"name\": \"Color\",\n            \"value\": \"Blue\"\n          }\n        ]\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Assign Attribute Groups","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{productId}/assign-attribute-groups","host":["{{baseUrl}}"],"path":["api","products",":productId","assign-attribute-groups"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Sync attribute groups assigned to a product. This replaces all current attribute group assignments.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- attribute_groups_ids (required, array): array of attribute group IDs (must exist in attribute_groups table)","body":{"mode":"raw","raw":"{\n  \"attribute_groups_ids\": [\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{productId}/assign-attribute-groups","host":["{{baseUrl}}"],"path":["api","products",":productId","assign-attribute-groups"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Attribute groups assigned successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get All Attributes for Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/attributes?product_ids=[1,2,3]","host":["{{baseUrl}}"],"path":["api","products","attributes"],"query":[{"key":"product_ids","value":"[1,2,3]","description":"Required. JSON-encoded array of product IDs","disabled":true}]},"description":"Get unique variant attributes across multiple products. Used by mapping modals.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns a deduplicated list of variant attributes across all provided product IDs."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/attributes?product_ids=[1,2,3]","host":["{{baseUrl}}"],"path":["api","products","attributes"],"query":[{"key":"product_ids","value":"[1,2,3]","description":"Required. JSON-encoded array of product IDs","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"attribute_id\": 5,\n      \"name\": \"Color\",\n      \"value\": \"Blue\"\n    },\n    {\n      \"id\": 2,\n      \"attribute_id\": 6,\n      \"name\": \"Size\",\n      \"value\": \"M\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/suppliers","host":["{{baseUrl}}"],"path":["api","products",":productId","suppliers"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get all supplier relationships for a product, including pricing tiers per supplier.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/suppliers","host":["{{baseUrl}}"],"path":["api","products",":productId","suppliers"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"product_id\": 1,\n      \"supplier_id\": 5,\n      \"supplier_sku\": \"MS-BW-001\",\n      \"leadtime\": 14,\n      \"minimum_order_quantity\": 100,\n      \"is_default\": true,\n      \"supplier\": {\n        \"id\": 5,\n        \"name\": \"Main Supplier\"\n      },\n      \"supplier_pricing_tiers\": [\n        {\n          \"name\": \"Default\",\n          \"price\": 10,\n          \"currency_code\": \"USD\"\n        }\n      ]\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Set Default Supplier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/set-default-supplier/{supplierId}","host":["{{baseUrl}}"],"path":["api","products",":productId","set-default-supplier",":supplierId"],"variable":[{"key":"productId","value":"1","description":"Product ID"},{"key":"supplierId","value":"5","description":"Supplier ID"}]},"description":"Mark a supplier as the default supplier for a product. Clears the is_default flag from all other suppliers for this product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBoth product_id and supplier_id must exist in the database."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/products/{productId}/set-default-supplier/{supplierId}","host":["{{baseUrl}}"],"path":["api","products",":productId","set-default-supplier",":supplierId"],"variable":[{"key":"productId","value":"1","description":"Product ID"},{"key":"supplierId","value":"5","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Supplier 5 set as default for product 1\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Components","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/components","host":["{{baseUrl}}"],"path":["api","products",":productId","components"],"variable":[{"key":"productId","value":"1","description":"Product ID (must be bundle or kit type)"}]},"description":"Get all component products for a bundle or kit product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/components","host":["{{baseUrl}}"],"path":["api","products",":productId","components"],"variable":[{"key":"productId","value":"1","description":"Product ID (must be bundle or kit type)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 3,\n    \"sku\": \"COMP-001\",\n    \"name\": \"Component A\",\n    \"quantity\": 2\n  }\n]"}]},{"name":"Get Product Bundles","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/bundles","host":["{{baseUrl}}"],"path":["api","products",":productId","bundles"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]},"description":"Get all bundles that this product is a component of.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/bundles","host":["{{baseUrl}}"],"path":["api","products",":productId","bundles"],"variable":[{"key":"productId","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 8,\n    \"sku\": \"BUNDLE-001\",\n    \"name\": \"Starter Bundle\",\n    \"type\": \"bundle\"\n  }\n]"}]},{"name":"Get Potential Bundles","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{productId}/potential-bundles","host":["{{baseUrl}}"],"path":["api","products",":productId","potential-bundles"],"variable":[{"key":"productId","value":"1","description":"Product ID (must be kit type)"}]},"description":"Calculate potential bundle quantities for a kit product based on current stock of its components per warehouse and inventory status.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly valid for kit-type products. Throws 500 if product is not a kit."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{productId}/potential-bundles","host":["{{baseUrl}}"],"path":["api","products",":productId","potential-bundles"],"variable":[{"key":"productId","value":"1","description":"Product ID (must be kit type)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"sku\": \"COMP-001\",\n      \"name\": \"Component A\",\n      \"bundle_data\": [\n        {\n          \"warehouse_id\": 1,\n          \"inventory_available\": {\n            \"quantity\": 200,\n            \"max_bundle_quantity\": 100\n          },\n          \"inventory_allocated\": {\n            \"quantity\": 30,\n            \"max_bundle_quantity\": 15\n          },\n          \"inventory_on_hold\": {\n            \"quantity\": 10,\n            \"max_bundle_quantity\": 5\n          },\n          \"inventory_in_transit\": {\n            \"quantity\": 0,\n            \"max_bundle_quantity\": 0\n          }\n        }\n      ]\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Product Drop-ship Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/dropship-status","host":["{{baseUrl}}"],"path":["api","products",":product","dropship-status"],"variable":[{"key":"product","value":"123","description":"Product ID"}]},"description":"Return the drop-ship eligibility checklist for a product — whether a sales order line for this product will auto-route to a supplier's drop-ship warehouse, and which gate conditions are currently met or failing.\n\nOptionally scope the check to a specific supplier with the `supplier_id` query parameter; omit it to evaluate against the product's default supplier.\n\nA line auto-routes to a supplier's drop-ship warehouse when the product is drop-shippable, drop-shipping is enabled, the supplier has a drop-ship warehouse ranked in the warehouse priority list, and its live stock covers the line — there is no per-supplier-product opt-in. The `gates` object reports each eligibility condition, and `missing` lists the labels of the gates that are not yet satisfied.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/dropship-status","host":["{{baseUrl}}"],"path":["api","products",":product","dropship-status"],"variable":[{"key":"product","value":"123","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"product_id\": 123,\n  \"supplier_id\": 45,\n  \"supplier_name\": \"Acme Supply\",\n  \"eligible\": false,\n  \"auto_routing_enabled\": true,\n  \"gates\": {\n    \"supplier_product_link\": true,\n    \"product_is_dropshippable\": true,\n    \"supplier_warehouse_enabled\": true,\n    \"supplier_feed_healthy\": false\n  },\n  \"missing\": [\n    \"Supplier feed healthy\"\n  ]\n}"}]},{"name":"Get Product Variations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/variations","host":["{{baseUrl}}"],"path":["api","products",":product","variations"],"variable":[{"key":"product","value":"1","description":"Product ID (must be matrix type)"}]},"description":"Get all variation products for a matrix (parent) product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if the product is not a matrix type."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/variations","host":["{{baseUrl}}"],"path":["api","products",":product","variations"],"variable":[{"key":"product","value":"1","description":"Product ID (must be matrix type)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"sku\": \"SKU-001-RED-S\",\n      \"name\": \"Blue Widget - Red - Small\",\n      \"type\": \"standard\",\n      \"is_variation\": true\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Variation Attributes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/variations/attributes","host":["{{baseUrl}}"],"path":["api","products",":product","variations","attributes"],"variable":[{"key":"product","value":"1","description":"Product ID (must be matrix type)"}]},"description":"Get unique variant attributes used across all variations of a matrix product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if product is not a matrix type."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/variations/attributes","host":["{{baseUrl}}"],"path":["api","products",":product","variations","attributes"],"variable":[{"key":"product","value":"1","description":"Product ID (must be matrix type)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"attribute_id\": 5,\n      \"name\": \"Color\"\n    },\n    {\n      \"id\": 2,\n      \"attribute_id\": 6,\n      \"name\": \"Size\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List Product Images","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/images","host":["{{baseUrl}}"],"path":["api","products",":product","images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Get all images for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/images","host":["{{baseUrl}}"],"path":["api","products",":product","images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"url\": \"https://cdn.example.com/products/blue-widget.jpg\",\n      \"name\": \"Main Image\",\n      \"sort_order\": 1,\n      \"is_primary\": true,\n      \"resolvable\": true\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Add Product Image","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{product}/images","host":["{{baseUrl}}"],"path":["api","products",":product","images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Add a new image to a product. The `image` field accepts EITHER an uploaded file (multipart/form-data) OR a URL / base64 string (application/json).\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Mode 1 — File upload (multipart/form-data):**\n- image (required, file): image file uploaded from the device. Allowed types: jpg, jpeg, png, gif, webp. Max size: 10 MB (10240 KB).\n\n**Mode 2 — URL or base64 string (application/json):**\n- image (required, string): image URL or base64 encoded data URI.\n\n**Common optional fields (both modes):**\n- name (optional, max 255): image display name\n- sort_order (optional, integer): display order\n- is_primary (optional, boolean): set as the primary product image\n- download (optional, boolean): URL mode only — if true, downloads and stores the image from the URL\n- swatch_variant_attribute (optional, max 255): marks this image as the variant swatch for the named variant attribute (e.g. \"color\"). Sales channels that support swatches render it as the variant's swatch image. Omit or send null for a normal gallery image.","body":{"mode":"raw","raw":"{\n  \"image\": \"https://example.com/images/widget-red.jpg\",\n  \"name\": \"Red Variant Image\",\n  \"sort_order\": 2,\n  \"is_primary\": false,\n  \"swatch_variant_attribute\": \"color\",\n  \"download\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/{product}/images","host":["{{baseUrl}}"],"path":["api","products",":product","images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"url\": \"https://cdn.example.com/products/widget-red.jpg\",\n    \"name\": \"Red Variant Image\",\n    \"sort_order\": 2,\n    \"is_primary\": false,\n    \"resolvable\": true\n  },\n  \"message\": \"Product image created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Update/Create Product Images","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{product}/bulk-images","host":["{{baseUrl}}"],"path":["api","products",":product","bulk-images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Bulk update or create multiple images for a product at once.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"images\": [\n    {\n      \"url\": \"https://example.com/images/main.jpg\",\n      \"name\": \"Main Image\",\n      \"is_primary\": true,\n      \"download\": false\n    },\n    {\n      \"url\": \"https://example.com/images/angle2.jpg\",\n      \"name\": \"Side View\",\n      \"is_primary\": false,\n      \"download\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/{product}/bulk-images","host":["{{baseUrl}}"],"path":["api","products",":product","bulk-images"],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"url\": \"https://cdn.example.com/products/main.jpg\",\n      \"is_primary\": true\n    },\n    {\n      \"id\": 2,\n      \"url\": \"https://cdn.example.com/products/angle2.jpg\",\n      \"is_primary\": false\n    }\n  ],\n  \"message\": \"Product images updated\",\n  \"status\": \"success\"\n}"}]},{"name":"List Broken Product Images","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-images/broken","host":["{{baseUrl}}"],"path":["api","product-images","broken"]},"description":"List product images the on-demand image health check confirmed broken — rows where `image_checked_at` is set AND `resolvable` is false. Newest-checked first, with primary images surfaced to the top. Each row is a single image with its parent product for cross-linking.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `page` — page number (default 1)\n- `per_page` — items per page (default 25)\n\nBacks the Broken Product Images report, where each image is re-loaded live in the browser; images that load are self-healed via `POST /api/product-images/mark-resolvable`, and genuinely dead ones are removed via `POST /api/product-images/bulk-delete`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-images/broken","host":["{{baseUrl}}"],"path":["api","product-images","broken"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"url\": \"https://images.example.com/widgets/blue-widget.jpg\",\n      \"is_primary\": true,\n      \"is_external\": true,\n      \"image_checked_at\": \"2026-06-09T18:30:00+00:00\",\n      \"product\": {\n        \"id\": 1,\n        \"sku\": \"SKU-001\",\n        \"name\": \"Blue Widget\",\n        \"reference\": \"SKU-001\"\n      },\n      \"product_link\": \"/products/1\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 25,\n  \"total\": 56,\n  \"from\": 1,\n  \"to\": 25,\n  \"path\": \"{{protocol}}{{domain}}/api/product-images/broken\"\n}"}]},{"name":"Bulk Delete Product Images","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-images/bulk-delete","host":["{{baseUrl}}"],"path":["api","product-images","bulk-delete"]},"description":"Delete the selected product images. Deletion runs through the model so its side effects fire: if a deleted image was a product's primary image, that product is left without a primary image, and affected packing slips are re-queued.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `image_ids` (`array<int>`, required) — 1–500 existing product_image ids.\n\nReturns 422 if `image_ids` is empty, exceeds 500, or contains an id that does not exist.","body":{"mode":"raw","raw":"{\n  \"image_ids\": [\n    4821,\n    4822,\n    4830\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-images/bulk-delete","host":["{{baseUrl}}"],"path":["api","product-images","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": 3\n  },\n  \"message\": \"Deleted 3 images.\"\n}"}]},{"name":"Mark Product Images Resolvable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-images/mark-resolvable","host":["{{baseUrl}}"],"path":["api","product-images","mark-resolvable"]},"description":"Clear the broken flag on the selected images — the report's in-browser load proved they resolve, so the server's false positive is healed. Uses a mass update, so ProductImage save side effects (primary reset, packing-slip re-queue) do NOT fire and `image_checked_at` is preserved.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `image_ids` (`array<int>`, required) — 1–500 existing product_image ids.\n\nReturns 422 if `image_ids` is empty, exceeds 500, or contains an id that does not exist.","body":{"mode":"raw","raw":"{\n  \"image_ids\": [\n    4821,\n    4822,\n    4830\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-images/mark-resolvable","host":["{{baseUrl}}"],"path":["api","product-images","mark-resolvable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3\n  },\n  \"message\": \"Marked 3 images as OK.\"\n}"}]},{"name":"Update Product Image","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-images/{productImage}","host":["{{baseUrl}}"],"path":["api","product-images",":productImage"],"variable":[{"key":"productImage","value":"315","description":"Product image ID"}]},"description":"Updates a product image's metadata and optionally replaces the image itself.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional on update):\n- image (string) — a new image as an external URL or a base64 data URI (data:image/...;base64,...). Omit to keep the current image and only update metadata.\n- name (string, max 255) — display name for the image\n- sort_order (integer) — position within the product's image list\n- is_primary (boolean) — mark as the product's primary image\n- download (boolean) — when true and image is an external URL, the file is downloaded and stored on SKU.io storage instead of hot-linking the URL\n\nIf an external image URL cannot be resolved, the update still succeeds but the response includes a warning and the image is stored with resolvable: false.\n\nAuthentication: Requires Bearer token.\n- swatch_variant_attribute (optional, max 255): marks this image as the variant swatch for the named variant attribute (e.g. \"color\"). Sales channels that support swatches render it as the variant's swatch image. Omit or send null for a normal gallery image.","body":{"mode":"raw","raw":"{\n  \"image\": \"https://cdn.example.com/images/widget-blue-front.jpg\",\n  \"name\": \"Front view\",\n  \"sort_order\": 1,\n  \"is_primary\": true,\n  \"swatch_variant_attribute\": \"color\",\n  \"download\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-images/{productImage}","host":["{{baseUrl}}"],"path":["api","product-images",":productImage"],"variable":[{"key":"productImage","value":"315","description":"Product image ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The product image '315' updated successfully\",\n  \"data\": {\n    \"id\": 315,\n    \"product_id\": 42,\n    \"url\": \"https://example.sku.io/storage/images/widget-blue-front.jpg\",\n    \"name\": \"Front view\",\n    \"sort_order\": 1,\n    \"is_primary\": true,\n    \"resolvable\": true,\n    \"image_checked_at\": \"2026-07-01T08:30:00.000000Z\",\n    \"created_at\": \"2025-11-02T09:14:33.000000Z\",\n    \"updated_at\": \"2026-07-06T10:05:12.000000Z\"\n  }\n}"}]},{"name":"Delete Product Image","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/product-images/{productImage}","host":["{{baseUrl}}"],"path":["api","product-images",":productImage"],"variable":[{"key":"productImage","value":"315","description":"Product image ID"}]},"description":"Deletes a product image. Destructive: if the image file is hosted on SKU.io storage, the stored file (and its thumbnail) is removed from the server as well; externally hosted URLs are simply detached from the product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/product-images/{productImage}","host":["{{baseUrl}}"],"path":["api","product-images",":productImage"],"variable":[{"key":"productImage","value":"315","description":"Product image ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The product image 315 deleted successfully\"\n}"}]},{"name":"Upload Image","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/store-image","host":["{{baseUrl}}"],"path":["api","store-image"]},"description":"Uploads an image to SKU.io storage and returns its hosted URL. Use the returned URL anywhere an image URL is accepted — for example when creating or updating product images, or for store branding assets.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe image field accepts three input forms:\n- a multipart file upload (shown here)\n- an external image URL (the file is downloaded and stored)\n- a base64 data URI string (data:image/png;base64,...)\n\nReturns 400 when the image cannot be resolved (e.g. an unreachable URL or invalid data).\n\nAuthentication: Requires Bearer token.","body":{"mode":"formdata","formdata":[{"key":"image","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/store-image","host":["{{baseUrl}}"],"path":["api","store-image"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The image uploaded successfully on the server\",\n  \"data\": {\n    \"url\": \"https://example.sku.io/storage/tenant-assets/images/9f2c1a7b3d.jpg\"\n  }\n}"}]},{"name":"Delete Uploaded Image","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/delete-image","host":["{{baseUrl}}"],"path":["api","delete-image"]},"description":"Removes a previously uploaded image (and its thumbnail) from SKU.io storage.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- url (required, string) — the hosted URL (or storage path) returned by Upload Image\n\nDestructive: the stored file is permanently deleted. Returns 400 when the file cannot be found at the given path.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/delete-image","host":["{{baseUrl}}"],"path":["api","delete-image"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The image removed successfully from the server\"\n}"}]},{"name":"Create Blemished Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/blemished","host":["{{baseUrl}}"],"path":["api","products","blemished"]},"description":"Create a blemished (damaged/used) product derived from an existing standard product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- blemished_sku (required, unique): SKU for the new blemished product\n- derived_from_product_id (required): ID of the original standard product\n- condition (optional): condition description (e.g. 'Grade B - Minor scratches')\n- reference (optional): reference number or note\n- adjust_inventory (optional, boolean, default false): create an inventory adjustment\n- adjust_inventory_for_original_product (optional, boolean): also adjust the original product\n- adjustment_type (optional, default 'increase'): increase or decrease\n- adjustment_data (optional): adjustment details when adjust_inventory is true","body":{"mode":"raw","raw":"{\n  \"blemished_sku\": \"SKU-001-B\",\n  \"derived_from_product_id\": 1,\n  \"condition\": \"Grade B - Minor scratches\",\n  \"reference\": \"REF-2024-001\",\n  \"adjust_inventory\": true,\n  \"adjust_inventory_for_original_product\": false,\n  \"adjustment_type\": \"increase\",\n  \"adjustment_data\": {\n    \"warehouse_id\": 1,\n    \"quantity\": 10\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/blemished","host":["{{baseUrl}}"],"path":["api","products","blemished"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 50,\n    \"sku\": \"SKU-001-B\",\n    \"name\": \"Blue Widget (Blemished)\",\n    \"type\": \"standard\",\n    \"blemished\": {\n      \"derived_product\": {\n        \"id\": 1,\n        \"name\": \"Blue Widget\",\n        \"sku\": \"SKU-001\"\n      },\n      \"condition\": \"Grade B - Minor scratches\",\n      \"reference\": \"REF-2024-001\"\n    }\n  },\n  \"message\": \"Product created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Generate Blemished SKU Pattern","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/generate-sku-pattern/{product}","host":["{{baseUrl}}"],"path":["api","products","generate-sku-pattern",":product"],"variable":[{"key":"product","value":"1","description":"Product ID to generate blemished SKU pattern for"}]},"description":"Generate a blemished SKU based on the tenant's blemished SKU pattern settings and the original product's SKU.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/generate-sku-pattern/{product}","host":["{{baseUrl}}"],"path":["api","products","generate-sku-pattern",":product"],"variable":[{"key":"product","value":"1","description":"Product ID to generate blemished SKU pattern for"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sku\": \"SKU-001-BLEM\",\n    \"pattern\": \"{sku}-BLEM\",\n    \"pattern_enabled\": true\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Import Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/import","host":["{{baseUrl}}"],"path":["api","products","import"]},"description":"Execute the product import — creates products from the validated data. Should be called after validate.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- products (required, array, min 1): array of validated product objects to import\n\nReturns 422 if the import fails.\n\n**Requires permission:** `products.import`","body":{"mode":"raw","raw":"{\n  \"products\": [\n    {\n      \"sku\": \"SKU-NEW-001\",\n      \"name\": \"New Product\",\n      \"type\": \"standard\",\n      \"barcode\": \"1234567890123\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/import","host":["{{baseUrl}}"],"path":["api","products","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"imported\": 1,\n  \"failed\": 0,\n  \"errors\": []\n}"}]},{"name":"Preview Import (Legacy CSV)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/import/preview","host":["{{baseUrl}}"],"path":["api","products","import","preview"]},"description":"Legacy endpoint for CSV import preview (delegates to ImportsData trait).\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `products.import`","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/import/preview","host":["{{baseUrl}}"],"path":["api","products","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {},\n  \"status\": \"success\"\n}"}]},{"name":"Get Import Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/import/fields","host":["{{baseUrl}}"],"path":["api","products","import","fields"]},"description":"Returns dynamic import fields including custom attributes for the column mapping UI.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/import/fields","host":["{{baseUrl}}"],"path":["api","products","import","fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"attributes\": [\n      {\n        \"key\": \"attribute_5\",\n        \"label\": \"Attr: Color\"\n      },\n      {\n        \"key\": \"attribute_6\",\n        \"label\": \"Attr: Size\"\n      }\n    ]\n  }\n}"}]},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/import/template","host":["{{baseUrl}}"],"path":["api","products","import","template"]},"description":"Download an XLSX import template with headers, sample data, field guide, and reference data from the tenant's account.\n\nAuthentication: Requires Bearer token.\n\nResponse: XLSX file download (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/import/template","host":["{{baseUrl}}"],"path":["api","products","import","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file)"}]},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/import/validate","host":["{{baseUrl}}"],"path":["api","products","import","validate"]},"description":"Validate mapped import data and return a preview. No data is created — safe to call repeatedly for client-side validation before executing the actual import.\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- rows (required, array, min 1): array of product row objects to validate","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"sku\": \"SKU-NEW-001\",\n      \"name\": \"New Product\",\n      \"type\": \"standard\",\n      \"barcode\": \"1234567890123\",\n      \"brand\": \"Acme Co\",\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/import/validate","host":["{{baseUrl}}"],"path":["api","products","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"valid\": [\n    {\n      \"row\": 1,\n      \"sku\": \"SKU-NEW-001\",\n      \"status\": \"valid\"\n    }\n  ],\n  \"invalid\": [],\n  \"total\": 1,\n  \"valid_count\": 1,\n  \"invalid_count\": 0\n}"}]},{"name":"Download Merge Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/merge/template","host":["{{baseUrl}}"],"path":["api","products","merge","template"]},"description":"Download a CSV template for bulk product merging. Contains columns: old_sku, destination_sku.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: CSV file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/merge/template","host":["{{baseUrl}}"],"path":["api","products","merge","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"old_sku,destination_sku\nEXAMPLE-OLD-SKU,EXAMPLE-NEW-SKU"}]},{"name":"Upload Merge CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/products/merge/upload","host":["{{baseUrl}}"],"path":["api","products","merge","upload"]},"description":"Upload a CSV file with product merge pairs. Validates the SKU pairs and creates a session (cached for 2 hours) for preview and execution.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\nBody fields:\n- file (required): CSV or TXT file with columns old_sku and destination_sku","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/merge/upload","host":["{{baseUrl}}"],"path":["api","products","merge","upload"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"session_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"pairs_count\": 5\n}"}]},{"name":"Create Merge Session (Single Pair)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/merge/create-session","host":["{{baseUrl}}"],"path":["api","products","merge","create-session"]},"description":"Create a merge session for a single SKU pair without uploading a CSV. Validates that both SKUs exist and are compatible.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- old_sku (required, string): source SKU to merge from\n- destination_sku (required, string): destination SKU to merge into\n\nReturns 422 if SKUs are the same, either SKU doesn't exist, or types are incompatible.","body":{"mode":"raw","raw":"{\n  \"old_sku\": \"SKU-OLD-001\",\n  \"destination_sku\": \"SKU-NEW-001\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/merge/create-session","host":["{{baseUrl}}"],"path":["api","products","merge","create-session"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"session_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"pairs_count\": 1\n}"}]},{"name":"Get Merge Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/merge/{session_id}/preview","host":["{{baseUrl}}"],"path":["api","products","merge",":session_id","preview"],"variable":[{"key":"session_id","value":"550e8400-e29b-41d4-a716-446655440000","description":"Session ID from upload or create-session"}]},"description":"Get a preview of what will happen when the merge is executed. Shows data changes for each SKU pair.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSessions expire after 2 hours. Returns 404 if the session is not found or expired."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/merge/{session_id}/preview","host":["{{baseUrl}}"],"path":["api","products","merge",":session_id","preview"],"variable":[{"key":"session_id","value":"550e8400-e29b-41d4-a716-446655440000","description":"Session ID from upload or create-session"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"previews\": [\n    {\n      \"old_sku\": \"SKU-OLD-001\",\n      \"destination_sku\": \"SKU-NEW-001\",\n      \"changes\": {\n        \"sales_order_lines\": 3,\n        \"purchase_order_lines\": 1\n      }\n    }\n  ]\n}"}]},{"name":"Execute Merge","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/merge/{session_id}/execute","host":["{{baseUrl}}"],"path":["api","products","merge",":session_id","execute"],"variable":[{"key":"session_id","value":"550e8400-e29b-41d4-a716-446655440000","description":"Session ID from upload or create-session"}]},"description":"Execute the product merge for all pairs in the session. Merges sales order lines, purchase order lines, and other references from the old SKU to the destination SKU. Clears the session cache after execution.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSessions expire after 2 hours. Returns 404 if session is not found or expired.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/products/merge/{session_id}/execute","host":["{{baseUrl}}"],"path":["api","products","merge",":session_id","execute"],"variable":[{"key":"session_id","value":"550e8400-e29b-41d4-a716-446655440000","description":"Session ID from upload or create-session"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"merged_count\": 5,\n  \"errors\": []\n}"}]},{"name":"List Product Listings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/products/{product}/listings?page=1&limit=10&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","products",":product","listings"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page","disabled":true},{"key":"archived","value":"0","description":"0 = active, 1 = archived, 2 = all","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"product","value":"1","description":"Product ID"}]},"description":"Get paginated product listings (channel listings) for a specific product. Refreshes inventory cache for all listings before returning.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/products/{product}/listings?page=1&limit=10&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","products",":product","listings"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page","disabled":true},{"key":"archived","value":"0","description":"0 = active, 1 = archived, 2 = all","disabled":true},{"key":"included[]","value":"","description":"Columns to include","disabled":true},{"key":"excluded[]","value":"","description":"Columns to exclude","disabled":true}],"variable":[{"key":"product","value":"1","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 20,\n      \"product_id\": 1,\n      \"sales_channel_listing_id\": \"amazon-asin-B001\",\n      \"sales_channel\": {\n        \"id\": 3,\n        \"name\": \"Amazon US\"\n      },\n      \"master_of_price\": true,\n      \"is_fba\": false\n    }\n  ],\n  \"meta\": {\n    \"current_page\": 1,\n    \"per_page\": 10,\n    \"total\": 3\n  }\n}"}]},{"name":"Update Product Default Financial Line Type","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/products/{product}/default-financial-line-type","host":["{{baseUrl}}"],"path":["api","products",":product","default-financial-line-type"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Sets or clears the default financial line type used when this product is added to financial documents.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- default_financial_line_type_id (nullable integer) — ID of an existing financial line type. It must have a revenue classification; non-revenue types are rejected with a 422. Pass null to clear the default.\n\nReturns the updated product including the resolved default_financial_line_type object (id, name, classification).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"default_financial_line_type_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/products/{product}/default-financial-line-type","host":["{{baseUrl}}"],"path":["api","products",":product","default-financial-line-type"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product WIDGET-BLUE updated successfully\",\n  \"data\": {\n    \"id\": 42,\n    \"sku\": \"WIDGET-BLUE\",\n    \"name\": \"Blue Widget\",\n    \"type\": \"standard\",\n    \"barcode\": 123456789012,\n    \"default_financial_line_type_id\": 12,\n    \"default_financial_line_type\": {\n      \"id\": 12,\n      \"name\": \"Product Sales\",\n      \"classification\": \"revenue\"\n    },\n    \"sales_nominal_code_id\": 5,\n    \"is_taxable\": true,\n    \"archived_at\": null,\n    \"created_at\": \"2025-11-02T09:14:33.000000Z\",\n    \"updated_at\": \"2026-07-06T10:05:12.000000Z\"\n  }\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products?page=1&per_page=10&sort=-created_at&filter[search]=widget&filter[type]=standard&filter[archived]=0&filter[brand_id]=1&filter[default_supplier_id]=2&filter[stock_status]=in_stock&filter[has_backorder]=false&filter[has_fba]=false&filter[ids]=1,2,3","host":["{{baseUrl}}"],"path":["api","v2","products"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Allowed: id, sku, name, type, barcode, mpn, hts_code, unit_cost, average_cost, supplier_price, weight, length, width, height, case_quantity, case_weight, daily_average_consumption, daily_average_consumption_net_returns, min_stock_level, total_quantity_sold, total_orders, archived_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"widget","description":"Full-text search across ID (exact), SKU, name, barcode, MPN, and brand name","disabled":true},{"key":"filter[type]","value":"standard","description":"Exact product type: standard, bundle, kit, blemished, matrix","disabled":true},{"key":"filter[archived]","value":"0","description":"Archived state: 0 or omit for active only, 'only' for archived only, 'all' for all","disabled":true},{"key":"filter[brand_id]","value":"1","description":"Filter by brand ID(s), comma-separated","disabled":true},{"key":"filter[default_supplier_id]","value":"2","description":"Filter by default supplier ID(s), comma-separated","disabled":true},{"key":"filter[stock_status]","value":"in_stock","description":"Stock status: in_stock, out_of_stock","disabled":true},{"key":"filter[has_backorder]","value":"false","description":"Filter by backorder presence: true or false","disabled":true},{"key":"filter[has_fba]","value":"false","description":"Filter by FBA listing presence: true or false","disabled":true},{"key":"filter[ids]","value":"1,2,3","description":"Comma-separated list of product IDs to include","disabled":true}]},"description":"Get a paginated list of products using Spatie QueryBuilder.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSupports both simple query filters (filter[field]=value) and advanced grouped filters (filter_groups tree). Default: shows non-archived products sorted by -created_at.\n\nAllowed sorts: id, sku, name, type, barcode, mpn, hts_code, unit_cost, average_cost, supplier_price, weight, length, width, height, case_quantity, case_weight, daily_average_consumption, daily_average_consumption_net_returns, min_stock_level, total_quantity_sold, total_orders, archived_at, created_at, updated_at\n\nDefault pagination: 10 per page.\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals.\n\n**Stock UoM filters (added 2026-05-30):**\n- `filter[stock_uom_id]` — by uom_id (exact, comma-separated)\n- `filter[stock_uom_code]` — by UoM code (advanced text ops)\n- `filter[stock_uom_name]` — by UoM display name (advanced text ops)\n\nThe response includes `inventory_non_sellable` — physically-present stock in non-sellable bins. It is excluded from `inventory_available` but is part of On Hand (On Hand = Available + Allocated + On Hold + Non-Sellable).\n\nAlso supports `hts_code` (Harmonized Tariff Schedule code) for filtering (`filter[hts_code]`) and sorting."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products?page=1&per_page=10&sort=-created_at&filter[search]=widget&filter[type]=standard&filter[archived]=0&filter[brand_id]=1&filter[default_supplier_id]=2&filter[stock_status]=in_stock&filter[has_backorder]=false&filter[has_fba]=false&filter[ids]=1,2,3","host":["{{baseUrl}}"],"path":["api","v2","products"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Allowed: id, sku, name, type, barcode, mpn, hts_code, unit_cost, average_cost, supplier_price, weight, length, width, height, case_quantity, case_weight, daily_average_consumption, daily_average_consumption_net_returns, min_stock_level, total_quantity_sold, total_orders, archived_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"widget","description":"Full-text search across ID (exact), SKU, name, barcode, MPN, and brand name","disabled":true},{"key":"filter[type]","value":"standard","description":"Exact product type: standard, bundle, kit, blemished, matrix","disabled":true},{"key":"filter[archived]","value":"0","description":"Archived state: 0 or omit for active only, 'only' for archived only, 'all' for all","disabled":true},{"key":"filter[brand_id]","value":"1","description":"Filter by brand ID(s), comma-separated","disabled":true},{"key":"filter[default_supplier_id]","value":"2","description":"Filter by default supplier ID(s), comma-separated","disabled":true},{"key":"filter[stock_status]","value":"in_stock","description":"Stock status: in_stock, out_of_stock","disabled":true},{"key":"filter[has_backorder]","value":"false","description":"Filter by backorder presence: true or false","disabled":true},{"key":"filter[has_fba]","value":"false","description":"Filter by FBA listing presence: true or false","disabled":true},{"key":"filter[ids]","value":"1,2,3","description":"Comma-separated list of product IDs to include","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WDG-001\",\n      \"name\": \"Blue Widget\",\n      \"type\": \"standard\",\n      \"barcode\": 123456789012,\n      \"mpn\": \"BW-001\",\n      \"hts_code\": \"8471.30.0100\",\n      \"unit_cost\": 5.5,\n      \"average_cost\": 5.75,\n      \"is_variation\": false,\n      \"is_dropshippable\": false,\n      \"is_lot_tracked\": false,\n      \"lot_tracking_method\": null,\n      \"shelf_life_days\": null,\n      \"near_expiry_threshold_days\": null,\n      \"min_remaining_shelf_life_days\": null,\n      \"expiry_aware_availability\": false,\n      \"archived_at\": null,\n      \"stock_uom_id\": 1,\n      \"stock_uom_code\": \"EACH\",\n      \"stock_uom_name\": \"Each\",\n      \"image_url\": \"https://example.com/images/widget.jpg\",\n      \"brand_id\": 1,\n      \"brand_name\": \"Acme\",\n      \"default_supplier_id\": 3,\n      \"default_supplier_name\": \"Global Supplies Ltd\",\n      \"default_supplier_sku\": \"GS-WDG-001\",\n      \"supplier_count\": 2,\n      \"inventory_total\": 500,\n      \"inventory_available\": 450,\n      \"inventory_available_to_sell\": 450,\n      \"inventory_allocated\": 50,\n      \"inventory_backorder\": 0,\n      \"inventory_on_hold\": 0,\n      \"inventory_non_sellable\": 0,\n      \"inventory_in_transit\": 100,\n      \"inventory_consigned\": 50,\n      \"inventory_incoming\": 200,\n      \"inventory_stock_value\": 2875,\n      \"inventory_avg_cost\": 5.75,\n      \"daily_average_consumption\": 5.2,\n      \"min_stock_level\": 100,\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n      \"updated_at\": \"2024-06-01T14:20:00.000000Z\",\n      \"total_quantity_sold\": 1280,\n      \"total_orders\": 312\n    }\n  ],\n  \"first_page_url\": \"https://sku2.test/api/v2/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 50,\n  \"last_page_url\": \"https://sku2.test/api/v2/products?page=50\",\n  \"next_page_url\": \"https://sku2.test/api/v2/products?page=2\",\n  \"path\": \"https://sku2.test/api/v2/products\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 498,\n  \"unfiltered_total\": 1843\n}"}]},{"name":"Search Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products","host":["{{baseUrl}}"],"path":["api","v2","products"]},"description":"Returns the same paginated product catalog list as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL (for example, filtering by a long list of SKUs or ids). The response includes an `unfiltered_total` alongside the standard paginator totals so clients can show both the filtered and total record counts.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against id, SKU, name, barcode, MPN, and brand.\n\nText columns (`sku`, `name`, `barcode`, `mpn`, `hts_code`, `brand_name`, `supplier_name`, `supplier_sku`, `tag`, `category`, `stock_uom_code`, `stock_uom_name`, `component_skus`, `parent_product`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric columns (`id`, `unit_cost`, `average_cost`, `supplier_price`, `default_supplier_leadtime`, `default_supplier_moq`, `default_supplier_target_stock_days`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. Additional filters include `type`, `archived`, `brand_id`, `default_supplier_id`, `stock_uom_id`, `stock_status` (in_stock / out_of_stock), `has_backorder`, and `ids`.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, sku, name, type, barcode, mpn, hts_code, unit_cost, average_cost, supplier_price, weight, case_quantity, daily_average_consumption, min_stock_level, archived_at, created_at, updated_at, plus inventory snapshot sorts (inventory_available, inventory_available_to_sell, inventory_allocated, inventory_on_hold, inventory_in_transit, inventory_total, inventory_backorder, inventory_stock_value, inventory_incoming, total_quantity_sold, total_orders). Results default to `-created_at`.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-created_at\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"stock_status\",\n          \"operator\": \"is\",\n          \"value\": \"in_stock\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"brand_name\",\n                \"operator\": \"is\",\n                \"value\": \"Acme\"\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"sku\",\n                \"operator\": \"starts_with\",\n                \"value\": \"WIDGET\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products","host":["{{baseUrl}}"],"path":["api","v2","products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"WIDGET-BLUE-01\",\n      \"id\": 3312,\n      \"unit_cost\": 13.75,\n      \"image_url\": \"https://cdn.example.com/products/3312.jpg\",\n      \"name\": \"Blue Widget\",\n      \"brand\": {\n        \"id\": 5,\n        \"name\": \"Acme\"\n      },\n      \"barcode\": \"8801234567890\",\n      \"mpn\": \"ACM-WB-01\",\n      \"hts_code\": \"8471.30.0100\",\n      \"tags\": [\n        \"bestseller\"\n      ],\n      \"type\": \"standard\",\n      \"is_lot_tracked\": false,\n      \"has_fba\": true,\n      \"is_variation\": false,\n      \"inventory\": {\n        \"inventory_available\": 240,\n        \"inventory_allocated\": 12,\n        \"inventory_total\": 252,\n        \"inventory_stock_value\": 3465\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 58,\n  \"total\": 1442,\n  \"unfiltered_total\": 3901,\n  \"next_page_url\": \"https://api.example.com/api/v2/products?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}?with=brand,images,tags,supplierProducts.supplier,components,variations,productPricingTiers","host":["{{baseUrl}}"],"path":["api","v2","products",":product"],"query":[{"key":"with","value":"brand,images,tags,supplierProducts.supplier,components,variations,productPricingTiers","description":"Comma-separated additional relations to load. Allowed: brand, images, tags, primaryCategory, otherCategories, supplierProducts.supplier, components, variations, productPricingTiers, salesNominalCode, cogsNominalCode, inventoryNominalCode, inventoryInTransitNominalCode, accruedPurchasesNominalCode, discountNominalCode, warehousesInventory.warehouse, productBlemished.originalProduct, productAttributeValues.attribute.attributeGroup, notes.user, parent, defaultSupplierProduct.supplier, totalInventory, purchaseOrderLines","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get a single product with default relations loaded (brand, primaryImage, primaryCategory, tags, defaultSupplierProduct.supplier, totalInventory).\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUse the `with` query parameter to load additional relations."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}?with=brand,images,tags,supplierProducts.supplier,components,variations,productPricingTiers","host":["{{baseUrl}}"],"path":["api","v2","products",":product"],"query":[{"key":"with","value":"brand,images,tags,supplierProducts.supplier,components,variations,productPricingTiers","description":"Comma-separated additional relations to load. Allowed: brand, images, tags, primaryCategory, otherCategories, supplierProducts.supplier, components, variations, productPricingTiers, salesNominalCode, cogsNominalCode, inventoryNominalCode, inventoryInTransitNominalCode, accruedPurchasesNominalCode, discountNominalCode, warehousesInventory.warehouse, productBlemished.originalProduct, productAttributeValues.attribute.attributeGroup, notes.user, parent, defaultSupplierProduct.supplier, totalInventory, purchaseOrderLines","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"sku\": \"WDG-001\",\n    \"name\": \"Blue Widget\",\n    \"type\": \"standard\",\n    \"barcode\": 123456789012,\n    \"mpn\": \"BW-001\",\n    \"hts_code\": \"8471.30.0100\",\n    \"unit_cost\": 5.5,\n    \"average_cost\": 5.75,\n    \"is_variation\": false,\n    \"is_dropshippable\": false,\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 365,\n    \"near_expiry_threshold_days\": 45,\n    \"min_remaining_shelf_life_days\": 30,\n    \"expiry_aware_availability\": true,\n    \"archived_at\": null,\n    \"stock_uom_id\": 1,\n    \"stock_uom_code\": \"EACH\",\n    \"stock_uom_name\": \"Each\",\n    \"image_url\": \"https://example.com/images/widget.jpg\",\n    \"brand_id\": 1,\n    \"brand_name\": \"Acme\",\n    \"default_supplier_id\": 3,\n    \"default_supplier_name\": \"Global Supplies Ltd\",\n    \"default_supplier_sku\": \"GS-WDG-001\",\n    \"default_supplier_leadtime\": 14,\n    \"default_supplier_moq\": 50,\n    \"supplier_count\": 2,\n    \"inventory_total\": 500,\n    \"inventory_available\": 450,\n    \"inventory_available_to_sell\": 450,\n    \"inventory_allocated\": 50,\n    \"inventory_on_hold\": 0,\n    \"inventory_in_transit\": 100,\n    \"inventory_consigned\": 50,\n    \"inventory_stock_value\": 2875,\n    \"inventory_avg_cost\": 5.75,\n    \"daily_average_consumption\": 5.2,\n    \"min_stock_level\": 100,\n    \"weight\": 0.5,\n    \"weight_unit\": \"kg\",\n    \"length\": 10,\n    \"width\": 5,\n    \"height\": 3,\n    \"dimension_unit\": \"cm\",\n    \"is_taxable\": true,\n    \"default_tax_rate_id\": 1,\n    \"sales_nominal_code_id\": 10,\n    \"cogs_nominal_code_id\": 11,\n    \"parent_id\": null,\n    \"has_fba\": false,\n    \"last_rebuilt_cogs_at\": \"2024-05-20T08:00:00.000000Z\",\n    \"tags\": [\n      \"blue\",\n      \"widget\"\n    ],\n    \"images\": [\n      {\n        \"id\": 5,\n        \"url\": \"https://example.com/images/widget.jpg\",\n        \"is_primary\": true,\n        \"sort_order\": 0\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2024-06-01T14:20:00.000000Z\"\n  }\n}"}]},{"name":"Get Product Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get inventory breakdown by warehouse for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIncludes FBA/AWD real-time data, Pan-European rollup, listing counts, inbound quantities, and backorder coverage (`backorder_planned` = unfulfilled demand without stock; `backorder_awaiting_receipt` = backordered demand covered by inbound POs). FBA/AWD warehouses show real-time data; standard warehouses use cached ProductInventory.\nEach warehouse row and the totals include `non_sellable` — physically-present stock in non-sellable bins (excluded from `available` but included in on-hand)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouses\": [\n      {\n        \"warehouse_id\": false,\n        \"warehouse_name\": false,\n        \"warehouse_type\": false,\n        \"total\": false,\n        \"available\": false,\n        \"allocated\": false,\n        \"on_hold\": false,\n        \"in_transit\": false,\n        \"inbound\": false,\n        \"backorder_planned\": false,\n        \"backorder_awaiting_receipt\": false,\n        \"consigned\": false,\n        \"non_sellable\": 15,\n        \"listing_count\": false,\n        \"country_code\": false,\n        \"fba_warehouse_id\": false\n      },\n      {\n        \"warehouse_id\": false,\n        \"warehouse_name\": false,\n        \"warehouse_type\": false,\n        \"total\": false,\n        \"available\": false,\n        \"allocated\": false,\n        \"on_hold\": false,\n        \"in_transit\": false,\n        \"inbound\": false,\n        \"backorder_planned\": false,\n        \"backorder_awaiting_receipt\": false,\n        \"consigned\": false,\n        \"non_sellable\": 0,\n        \"listing_count\": false,\n        \"country_code\": false,\n        \"fba_warehouse_id\": false\n      }\n    ],\n    \"totals\": {\n      \"total\": false,\n      \"available\": false,\n      \"allocated\": false,\n      \"on_hold\": false,\n      \"in_transit\": false,\n      \"inbound\": false,\n      \"backorder_planned\": false,\n      \"backorder_awaiting_receipt\": false,\n      \"consigned\": false,\n      \"non_sellable\": 15,\n      \"incoming\": false,\n      \"stock_value\": false,\n      \"cache_updated_at\": false\n    }\n  }\n}"}]},{"name":"Get Product Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/suppliers","host":["{{baseUrl}}"],"path":["api","v2","products",":product","suppliers"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get supplier products for a product, including pricing tiers and supplier inventory.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/suppliers","host":["{{baseUrl}}"],"path":["api","v2","products",":product","suppliers"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"supplier_id\": 3,\n      \"supplier_name\": \"Global Supplies Ltd\",\n      \"default_pricing_tier_id\": 1,\n      \"supplier_sku\": \"GS-WDG-001\",\n      \"lead_time\": 14,\n      \"minimum_order_quantity\": 50,\n      \"target_stock_days\": 30,\n      \"is_default\": true,\n      \"pricing\": [\n        {\n          \"tier_id\": 1,\n          \"tier_name\": \"Standard\",\n          \"price\": 4.5,\n          \"currency_code\": \"USD\"\n        }\n      ],\n      \"inventories\": [\n        {\n          \"id\": 7,\n          \"warehouse_id\": 10,\n          \"warehouse_name\": \"Supplier Warehouse A\",\n          \"quantity\": 2000,\n          \"in_stock\": true,\n          \"discontinued\": false,\n          \"eta\": null,\n          \"source\": \"manual\",\n          \"updated_at\": \"2024-05-15T09:00:00.000000Z\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Product Pricing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/pricing","host":["{{baseUrl}}"],"path":["api","v2","products",":product","pricing"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get product pricing tiers.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/pricing","host":["{{baseUrl}}"],"path":["api","v2","products",":product","pricing"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"tier_id\": 1,\n      \"tier_name\": \"Retail\",\n      \"price\": 12.99,\n      \"currency_code\": \"USD\",\n      \"is_default\": true\n    },\n    {\n      \"tier_id\": 2,\n      \"tier_name\": \"Wholesale\",\n      \"price\": 8.99,\n      \"currency_code\": \"USD\",\n      \"is_default\": false\n    }\n  ]\n}"}]},{"name":"Upsert Product Pricing","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/pricing","host":["{{baseUrl}}"],"path":["api","v2","products",":product","pricing"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Idempotently upsert a single pricing tier price for a product.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUsed to save a pricing tier's master price without navigating to the product edit page. Returns the resolved tier row.","body":{"mode":"raw","raw":"{\n  \"tier_id\": 1,\n  \"price\": 12.99\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/pricing","host":["{{baseUrl}}"],"path":["api","v2","products",":product","pricing"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tier_id\": 1,\n    \"tier_name\": \"Retail\",\n    \"price\": 12.99,\n    \"currency_code\": \"USD\",\n    \"is_default\": true\n  }\n}"}]},{"name":"Get Product Components","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products",":product","components"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get components for a bundle or kit product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products",":product","components"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"sku\": \"COMP-A\",\n      \"name\": \"Component A\",\n      \"quantity\": 2,\n      \"type\": \"standard\"\n    },\n    {\n      \"id\": 11,\n      \"sku\": \"COMP-B\",\n      \"name\": \"Component B\",\n      \"quantity\": 1,\n      \"type\": \"standard\"\n    }\n  ]\n}"}]},{"name":"Get Parent Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/parent-products","host":["{{baseUrl}}"],"path":["api","v2","products",":product","parent-products"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get parent bundle/kit products that include this product as a component.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/parent-products","host":["{{baseUrl}}"],"path":["api","v2","products",":product","parent-products"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"sku\": \"BUNDLE-001\",\n      \"name\": \"Widget Bundle\",\n      \"type\": \"bundle\",\n      \"image_url\": null,\n      \"quantity\": 2\n    }\n  ]\n}"}]},{"name":"Get Bundle Potential","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/bundle-potential","host":["{{baseUrl}}"],"path":["api","v2","products",":product","bundle-potential"],"variable":[{"key":"product","value":"5","description":"Product ID (must be bundle or kit type)"}]},"description":"Get bundle assembly potential — how many units can be assembled from current component inventory.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns per-warehouse breakdown and bottleneck identification. Returns empty result for non-bundle/kit products."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/bundle-potential","host":["{{baseUrl}}"],"path":["api","v2","products",":product","bundle-potential"],"variable":[{"key":"product","value":"5","description":"Product ID (must be bundle or kit type)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"components\": [\n      {\n        \"product_id\": 10,\n        \"sku\": \"COMP-A\",\n        \"name\": \"Component A\",\n        \"required_quantity\": 2,\n        \"available_inventory\": 450,\n        \"max_assemblable\": 225,\n        \"is_bottleneck\": false\n      },\n      {\n        \"product_id\": 11,\n        \"sku\": \"COMP-B\",\n        \"name\": \"Component B\",\n        \"required_quantity\": 1,\n        \"available_inventory\": 100,\n        \"max_assemblable\": 100,\n        \"is_bottleneck\": true\n      }\n    ],\n    \"max_assemblable\": 100,\n    \"warehouses\": [\n      {\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"max_assemblable\": 100,\n        \"components\": []\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Variations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/variations","host":["{{baseUrl}}"],"path":["api","v2","products",":product","variations"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get variations of a matrix product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/variations","host":["{{baseUrl}}"],"path":["api","v2","products",":product","variations"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 43,\n      \"sku\": \"WDG-001-RED\",\n      \"name\": \"Blue Widget - Red\",\n      \"image_url\": null,\n      \"attributes\": [\n        {\n          \"name\": \"Color\",\n          \"value\": \"Red\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Product Images","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/images","host":["{{baseUrl}}"],"path":["api","v2","products",":product","images"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get all images for a product, sorted by sort_order.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEach image may carry `swatch_variant_attribute` (string, nullable): when set, the image is the variant swatch for the named attribute (e.g. \"Color\") on matrix variant children. Channels that support swatches (Walmart) emit it as that child's swatch image."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/images","host":["{{baseUrl}}"],"path":["api","v2","products",":product","images"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"url\": \"https://example.com/images/widget.jpg\",\n      \"is_primary\": true,\n      \"sort_order\": 0,\n      \"swatch_variant_attribute\": \"Color\",\n      \"created_at\": \"2024-01-15T10:30:00Z\",\n      \"updated_at\": \"2024-01-15T10:30:00Z\"\n    },\n    {\n      \"id\": 6,\n      \"url\": \"https://example.com/images/widget-alt.jpg\",\n      \"is_primary\": false,\n      \"sort_order\": 1,\n      \"swatch_variant_attribute\": null,\n      \"created_at\": \"2024-01-15T10:31:00Z\",\n      \"updated_at\": \"2024-01-15T10:31:00Z\"\n    }\n  ]\n}"}]},{"name":"Get Product Listings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/listings?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","products",":product","listings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get paginated sales channel listings for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/listings?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","products",":product","listings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 100,\n      \"listing_sku\": \"WDG-001\",\n      \"is_fba\": false,\n      \"sales_channel_id\": 1,\n      \"sales_channel_name\": \"Shopify US\"\n    }\n  ],\n  \"total\": 3,\n  \"per_page\": 10\n}"}]},{"name":"Get Product Listings Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/listings/summary","host":["{{baseUrl}}"],"path":["api","v2","products",":product","listings","summary"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get listing counts grouped by integration for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/listings/summary","host":["{{baseUrl}}"],"path":["api","v2","products",":product","listings","summary"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 5,\n    \"integrations\": [\n      {\n        \"integration_name\": \"Shopify\",\n        \"integration_id\": 1,\n        \"count\": 3\n      },\n      {\n        \"integration_name\": \"Amazon\",\n        \"integration_id\": 2,\n        \"count\": 2\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get paginated inventory movements for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"type\": \"sale\",\n      \"inventory_status\": \"active\",\n      \"quantity\": -2,\n      \"reference\": \"SO-0042\",\n      \"link_type\": \"App\\\\Models\\\\SalesOrderLine\",\n      \"link_id\": 55,\n      \"parent_link_id\": 22,\n      \"detail_link_id\": null,\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 5.75,\n      \"unit_cost_provisional\": false,\n      \"layer\": {\n        \"fifo_layer_id\": 10,\n        \"name\": \"fifo\"\n      },\n      \"inventory_movement_date\": \"2024-06-01\",\n      \"created_at\": \"2024-06-01T14:20:00Z\"\n    }\n  ],\n  \"total\": 150,\n  \"per_page\": 15\n}"}]},{"name":"List Product Sales","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/sales","host":["{{baseUrl}}"],"path":["api","v2","products",":product","sales"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"List sales order lines for a product — one row per line with parent-order context (order number, date, sales channel, customer, order and fulfillment status) and per-line financials (unit price, line revenue, profit). Draft orders are excluded. Results are live order data.\n\nAuthentication: Requires Bearer token.\n\nFilters:\n- filter[search] — searches order number and customer name\n- filter[sales_channel_id] — exact sales channel ID\n- filter[warehouse_id] — exact warehouse ID (line-level)\n- filter[order_status] / filter[fulfillment_status] / filter[order_number] / filter[customer_name] — text filters; bare param matches exactly, or suffix an operator, e.g. filter[order_status.is_one_of]=open,closed, filter[order_number.contains]=1234. Operators: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty\n- filter[`order_date.<operator>`] — date filters. Operators: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, past_week, past_month, past_year\n- filter[`quantity.<operator>`] / filter[`unit_price.<operator>`] — numeric filters. Operators: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty\n- filter_groups — base64-encoded JSON tree for grouped AND/OR filter conditions, e.g. {\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"quantity\",\"operator\":\"greater_than\",\"value\":1}}]}\n\nAllowed sorts: id, order_date, order_number, order_status, fulfillment_status, customer_name, quantity, unit_price. Prefix with - for descending. Default: -order_date.\n\nPagination: page, per_page (default 15)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/sales","host":["{{baseUrl}}"],"path":["api","v2","products",":product","sales"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 59881,\n      \"sales_order_id\": 295069,\n      \"order_number\": \"SO-10412\",\n      \"order_date\": \"2026-07-02T16:58:28.000000Z\",\n      \"sales_channel_id\": 30,\n      \"sales_channel_name\": \"TikTok Shop\",\n      \"customer_id\": 818699,\n      \"customer_name\": \"Jane Cooper\",\n      \"order_status\": \"closed\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"quantity\": 1,\n      \"unit_price\": 149.99,\n      \"line_revenue\": 149.99,\n      \"profit\": 48.89,\n      \"warehouse_id\": 4,\n      \"warehouse_name\": \"Main Warehouse\"\n    }\n  ],\n  \"total\": 6,\n  \"per_page\": 15,\n  \"last_page\": 1,\n  \"from\": 1,\n  \"to\": 6\n}"}]},{"name":"Get Product FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/fifo-layers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products",":product","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get paginated FIFO cost layers for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/fifo-layers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products",":product","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10,\n      \"fifo_layer_date\": \"2024-05-01\",\n      \"quantity\": 200,\n      \"fulfilled_quantity\": 50,\n      \"available_quantity\": 150,\n      \"unit_cost\": 5.5,\n      \"total_cost\": 1100,\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"source_type\": \"Purchase Order\",\n      \"source_reference\": \"PO-0015\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n      \"link_id\": 88,\n      \"parent_link_id\": 40,\n      \"detail_link_id\": null,\n      \"condition\": \"new\",\n      \"is_consignment\": false,\n      \"created_at\": \"2024-05-01T09:00:00Z\"\n    }\n  ],\n  \"total\": 8,\n  \"per_page\": 15\n}"}]},{"name":"Get Product Lots & Expiry","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/lots-expiry","host":["{{baseUrl}}"],"path":["api","v2","products",":product","lots-expiry"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Paginated lot/expiry breakdown scoped to a single product (the product detail \"Lots & Expiry\" tab).\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReuses the cross-warehouse expiry pipeline (internal FIFO layers + Amazon FBA layers), enriched with each lot's review/disposition state. Each row is one batch/expiry FIFO layer with quantities, valuation, days-to-expiry, shelf-life remaining percentage, and review status.\n\nAuthentication: Requires Bearer token.\n\nPagination: page (default 1), per_page (default 25). Returns the standard Laravel paginator envelope (current_page, last_page, per_page, total, data)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/lots-expiry","host":["{{baseUrl}}"],"path":["api","v2","products",":product","lots-expiry"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"fifo_layer_id\": 9012,\n      \"product_id\": 42,\n      \"sku\": \"WDG-001\",\n      \"product_name\": \"Blue Widget\",\n      \"brand_name\": \"Acme\",\n      \"supplier_name\": \"Global Supplies Ltd\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"bucket\": \"0-30\",\n      \"days_to_expiry\": 18,\n      \"expiry_date\": \"2026-07-04T00:00:00.000000Z\",\n      \"manufacture_date\": \"2026-01-04T00:00:00.000000Z\",\n      \"batch_number\": \"LOT-2026-0042\",\n      \"shelf_life_remaining_pct\": 30.5,\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n      \"link_type_name\": \"Purchase Order Line\",\n      \"link_id\": 88,\n      \"quantity\": 150,\n      \"avg_unit_cost\": 5.5,\n      \"total_value\": 825,\n      \"valuation_source\": \"internal\",\n      \"is_fba\": false,\n      \"review_status\": \"open\",\n      \"review_status_label\": \"Open\",\n      \"review_notes\": null,\n      \"reviewed_at\": null,\n      \"reviewed_by_name\": null,\n      \"inventory_hold_id\": null\n    },\n    {\n      \"fifo_layer_id\": null,\n      \"product_id\": 42,\n      \"sku\": \"WDG-001\",\n      \"product_name\": \"Blue Widget\",\n      \"brand_name\": \"Acme\",\n      \"supplier_name\": null,\n      \"warehouse_id\": 87,\n      \"warehouse_name\": \"Amazon FBA (US)\",\n      \"bucket\": \"61-90\",\n      \"days_to_expiry\": 74,\n      \"expiry_date\": \"2026-08-29T00:00:00.000000Z\",\n      \"manufacture_date\": null,\n      \"batch_number\": \"FBA-LOT-7781\",\n      \"shelf_life_remaining_pct\": null,\n      \"link_type\": null,\n      \"link_type_name\": \"\",\n      \"link_id\": null,\n      \"quantity\": 60,\n      \"avg_unit_cost\": 5.75,\n      \"total_value\": 345,\n      \"valuation_source\": \"amazon\",\n      \"is_fba\": true,\n      \"review_status\": null,\n      \"review_status_label\": null,\n      \"review_notes\": null,\n      \"reviewed_at\": null,\n      \"reviewed_by_name\": null,\n      \"inventory_hold_id\": null\n    }\n  ],\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Product Lot Genealogy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/lots/{fifoLayer}/genealogy","host":["{{baseUrl}}"],"path":["api","v2","products",":product","lots",":fifoLayer","genealogy"],"variable":[{"key":"product","value":"42","description":"Product ID"},{"key":"fifoLayer","value":"9012","description":"FIFO layer ID (the lot) to trace. Must belong to the product, otherwise 404."}]},"description":"Read-only lot genealogy / traceability tree for a single FIFO layer (lot) of this product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns two trees:\n- forward: downstream consumers (where the lot went — sales orders, manufacturing orders, transfers that consumed it).\n- backward: upstream ingredients (what was consumed to produce this lot, for manufactured lots). Purchased lots have an empty backward tree.\n\nEach node carries entity_type ('manufacturing_order' | 'purchase_order' | 'sales_order' | 'warehouse_transfer' | 'fifo_layer'), reference, product info, batch_number, quantity, consumed_quantity (qty travelling along the parent->node edge), date, fifo_layer_id, and recursive children.\n\nReturns 404 if the FIFO layer does not belong to the product.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/lots/{fifoLayer}/genealogy","host":["{{baseUrl}}"],"path":["api","v2","products",":product","lots",":fifoLayer","genealogy"],"variable":[{"key":"product","value":"42","description":"Product ID"},{"key":"fifoLayer","value":"9012","description":"FIFO layer ID (the lot) to trace. Must belong to the product, otherwise 404."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"forward\": {\n      \"id\": \"fifo-9012\",\n      \"entity_type\": \"purchase_order\",\n      \"reference\": \"PO-1234\",\n      \"product_id\": 42,\n      \"product_name\": \"Blue Widget\",\n      \"batch_number\": \"LOT-2026-0042\",\n      \"quantity\": 200,\n      \"consumed_quantity\": null,\n      \"date\": \"2026-01-04\",\n      \"fifo_layer_id\": 9012,\n      \"manufacturing_order_id\": null,\n      \"purchase_order_id\": 1234,\n      \"children\": [\n        {\n          \"id\": \"terminal-App-Models-SalesOrderLine-55347\",\n          \"entity_type\": \"sales_order\",\n          \"reference\": \"SO-8842\",\n          \"product_id\": null,\n          \"product_name\": null,\n          \"batch_number\": null,\n          \"quantity\": null,\n          \"consumed_quantity\": 50,\n          \"date\": \"2026-02-12\",\n          \"fifo_layer_id\": null,\n          \"manufacturing_order_id\": null,\n          \"purchase_order_id\": null,\n          \"children\": []\n        }\n      ]\n    },\n    \"backward\": {\n      \"id\": \"fifo-9012\",\n      \"entity_type\": \"purchase_order\",\n      \"reference\": \"PO-1234\",\n      \"product_id\": 42,\n      \"product_name\": \"Blue Widget\",\n      \"batch_number\": \"LOT-2026-0042\",\n      \"quantity\": 200,\n      \"consumed_quantity\": null,\n      \"date\": \"2026-01-04\",\n      \"fifo_layer_id\": 9012,\n      \"manufacturing_order_id\": null,\n      \"purchase_order_id\": 1234,\n      \"children\": []\n    }\n  }\n}"}]},{"name":"Get Product Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/activity-log?page=1&per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","v2","products",":product","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search across causer name, properties, event, and subject type","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get paginated activity log for a product (covers Product and SupplierProductPricing events).\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/activity-log?page=1&per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","v2","products",":product","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search across causer name, properties, event, and subject type","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 501,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Product\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"attributes\": {\n          \"unit_cost\": 5.5\n        },\n        \"old\": {\n          \"unit_cost\": 5\n        }\n      },\n      \"causer_name\": \"John Smith\",\n      \"created_at\": \"2024-06-01T14:20:00Z\"\n    }\n  ],\n  \"total\": 45,\n  \"per_page\": 15\n}"}]},{"name":"Get Product Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/notes","host":["{{baseUrl}}"],"path":["api","v2","products",":product","notes"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get notes for a product, sorted by most recent first.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/notes","host":["{{baseUrl}}"],"path":["api","v2","products",":product","notes"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"note\": \"Check with supplier for Q3 pricing update\",\n      \"created_at\": \"2024-05-20T11:00:00Z\",\n      \"user\": {\n        \"id\": 2,\n        \"name\": \"Jane Doe\"\n      }\n    }\n  ]\n}"}]},{"name":"Get Product Purchase Order Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/purchase-order-lines?status=inbound","host":["{{baseUrl}}"],"path":["api","v2","products",":product","purchase-order-lines"],"query":[{"key":"status","value":"inbound","description":"Filter: 'inbound' (unreceived_quantity > 0, default) or 'received' (received_quantity > 0)","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get purchase order lines for a product, filtered by status.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nExcludes draft POs."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/purchase-order-lines?status=inbound","host":["{{baseUrl}}"],"path":["api","v2","products",":product","purchase-order-lines"],"query":[{"key":"status","value":"inbound","description":"Filter: 'inbound' (unreceived_quantity > 0, default) or 'received' (received_quantity > 0)","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"po_id\": 88,\n      \"po_date\": \"2024-05-10\",\n      \"po_number\": \"PO-0088\",\n      \"supplier_name\": \"Global Supplies Ltd\",\n      \"quantity\": 200,\n      \"received_quantity\": 0,\n      \"unreceived_quantity\": 200\n    }\n  ]\n}"}]},{"name":"Get Product Inventory Tally","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory-tally?warehouse_id=1&inventory_status=active","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory-tally"],"query":[{"key":"warehouse_id","value":"1","description":"Required. Warehouse ID to tally","disabled":true},{"key":"inventory_status","value":"active","description":"Optional. Inventory status: active (default) or in_transit","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get enriched inventory tally data for a product at a specific warehouse.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/inventory-tally?warehouse_id=1&inventory_status=active","host":["{{baseUrl}}"],"path":["api","v2","products",":product","inventory-tally"],"query":[{"key":"warehouse_id","value":"1","description":"Required. Warehouse ID to tally","disabled":true},{"key":"inventory_status","value":"active","description":"Optional. Inventory status: active (default) or in_transit","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 300,\n    \"available\": 280,\n    \"allocated\": 20,\n    \"movements\": []\n  }\n}"}]},{"name":"Get Product Warehouse Transfer Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/warehouse-transfer-lines?status=in_transit","host":["{{baseUrl}}"],"path":["api","v2","products",":product","warehouse-transfer-lines"],"query":[{"key":"status","value":"in_transit","description":"Filter: 'in_transit' (default) or 'received'","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get warehouse transfer lines for a product, showing in-transit or received quantities.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFor FBA/AWD destinations, quantity_received is derived from Amazon pending inbound data."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/warehouse-transfer-lines?status=in_transit","host":["{{baseUrl}}"],"path":["api","v2","products",":product","warehouse-transfer-lines"],"query":[{"key":"status","value":"in_transit","description":"Filter: 'in_transit' (default) or 'received'","disabled":true}],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"transfer_id\": 20,\n      \"transfer_date\": \"2024-05-28\",\n      \"warehouse_transfer_number\": \"WT-0020\",\n      \"from_warehouse\": \"Main Warehouse\",\n      \"to_warehouse\": \"FBA US\",\n      \"quantity\": 100,\n      \"quantity_received\": 0,\n      \"quantity_unreceived\": 100\n    }\n  ]\n}"}]},{"name":"Get Product Holds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/holds","host":["{{baseUrl}}"],"path":["api","v2","products",":product","holds"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get inventory holds for a product.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/holds","host":["{{baseUrl}}"],"path":["api","v2","products",":product","holds"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"quantity\": 5,\n      \"reason\": \"Quality check\",\n      \"warehouse_id\": 1,\n      \"created_at\": \"2024-05-30T08:00:00Z\"\n    }\n  ]\n}"}]},{"name":"Get Product Reservation Integrity","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/reservation-integrity","host":["{{baseUrl}}"],"path":["api","v2","products",":product","reservation-integrity"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get reservation integrity issues for a product.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/reservation-integrity","host":["{{baseUrl}}"],"path":["api","v2","products",":product","reservation-integrity"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"issues\": [],\n    \"total_issues\": 0\n  }\n}"}]},{"name":"Get Product Active Reservations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/active-reservations","host":["{{baseUrl}}"],"path":["api","v2","products",":product","active-reservations"],"variable":[{"key":"product","value":"42","description":"Product ID"}]},"description":"Get active (outstanding) inventory reservations for a product.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/active-reservations","host":["{{baseUrl}}"],"path":["api","v2","products",":product","active-reservations"],"variable":[{"key":"product","value":"42","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"type\": \"sales_order\",\n      \"quantity\": 10,\n      \"reference\": \"SO-0042\",\n      \"warehouse_id\": 1\n    }\n  ]\n}"}]},{"name":"Get Bulk Edit Metadata","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-metadata","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-metadata"]},"description":"Get dynamic field metadata for the bulk edit UI: attributes (with options), pricing tiers, supplier pricing tiers, and suppliers.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-metadata","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-metadata"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"attributes\": [\n      {\n        \"id\": 1,\n        \"name\": \"Color\",\n        \"type\": \"text\",\n        \"has_options\": true,\n        \"options\": [\n          \"Red\",\n          \"Blue\",\n          \"Green\"\n        ],\n        \"group_name\": \"Physical\"\n      }\n    ],\n    \"pricing_tiers\": [\n      {\n        \"id\": 1,\n        \"name\": \"Retail\",\n        \"is_default\": true\n      }\n    ],\n    \"supplier_pricing_tiers\": [\n      {\n        \"id\": 1,\n        \"name\": \"Default\",\n        \"is_default\": true,\n        \"currency_code\": \"USD\"\n      }\n    ],\n    \"suppliers\": [\n      {\n        \"id\": 3,\n        \"name\": \"Global Supplies Ltd\"\n      }\n    ]\n  }\n}"}]},{"name":"Fetch Products for Bulk Edit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-fetch?ids=42,43,44","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-fetch"],"query":[{"key":"ids","value":"42,43,44","description":"Required. Comma-separated product IDs to fetch for editing","disabled":true}]},"description":"Fetch products with all editable fields loaded for the bulk edit page.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIncludes basic info, shipping dimensions, costing, accounting nominal codes, tax, attributes, pricing, suppliers, and supplier pricing (per supplier × tier)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-fetch?ids=42,43,44","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-fetch"],"query":[{"key":"ids","value":"42,43,44","description":"Required. Comma-separated product IDs to fetch for editing","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WDG-001\",\n      \"name\": \"Blue Widget\",\n      \"type\": \"standard\",\n      \"barcode\": 123456789012,\n      \"mpn\": \"BW-001\",\n      \"hts_code\": \"8471.30.0100\",\n      \"unit_cost\": 5.5,\n      \"is_dropshippable\": false,\n      \"brand_id\": 1,\n      \"brand_name\": \"Acme\",\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"attributes\": [\n        {\n          \"attribute_id\": 1,\n          \"attribute_name\": \"Color\",\n          \"value\": \"Blue\"\n        }\n      ],\n      \"pricing\": [\n        {\n          \"tier_id\": 1,\n          \"tier_name\": \"Retail\",\n          \"price\": 12.99\n        }\n      ],\n      \"suppliers\": [\n        {\n          \"supplier_id\": 3,\n          \"supplier_name\": \"Global Supplies Ltd\",\n          \"is_default\": true\n        }\n      ],\n      \"supplier_pricing\": [\n        {\n          \"supplier_product_id\": 11,\n          \"supplier_id\": 3,\n          \"supplier_name\": \"Global Supplies Ltd\",\n          \"tier_id\": 1,\n          \"tier_name\": \"Default\",\n          \"price\": 4.5,\n          \"currency_code\": \"USD\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Bulk Edit Products (Apply to All)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit"]},"description":"Apply the same set of changes to all selected products.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- product_ids (required, array, max 500): Product IDs to update\n- changes (required, array): List of changes, each with:\n  - field (required, string): Field name to change. Supports scalar product fields (e.g. weight, weight_unit, unit_cost, brand_id), 'pricing' (customer pricing tiers), 'supplier_pricing' (per-supplier pricing tiers — applies to ALL suppliers of each product), 'attribute' (custom attributes), and 'supplier' (link suppliers).\n  - operation (required, string): Operation type. Scalars use 'set' / 'clear'. Numeric/pricing/supplier_pricing also accept 'increase_by_amount', 'decrease_by_amount', 'increase_by_percent', 'decrease_by_percent'.\n  - value (nullable): New value\n  - tier_id (nullable, integer): Required for 'pricing' (references product_pricing_tiers) and 'supplier_pricing' (references supplier_pricing_tiers). Validation routes to the correct table based on the sibling 'field' value.\n  - attribute_id (nullable, integer): Required for attribute field changes\n  - supplier_id (nullable, integer): Required for supplier field changes\n\n**Requires permission:** `products.update`","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    42,\n    43,\n    44\n  ],\n  \"changes\": [\n    {\n      \"field\": \"weight\",\n      \"operation\": \"set\",\n      \"value\": 0.6\n    },\n    {\n      \"field\": \"weight_unit\",\n      \"operation\": \"set\",\n      \"value\": \"kg\"\n    },\n    {\n      \"field\": \"pricing\",\n      \"operation\": \"set\",\n      \"tier_id\": 1,\n      \"value\": 14.99\n    },\n    {\n      \"field\": \"supplier_pricing\",\n      \"operation\": \"increase_by_percent\",\n      \"tier_id\": 1,\n      \"value\": 5\n    },\n    {\n      \"field\": \"attribute\",\n      \"operation\": \"set\",\n      \"attribute_id\": 1,\n      \"value\": \"Blue\"\n    },\n    {\n      \"field\": \"supplier\",\n      \"operation\": \"add\",\n      \"supplier_id\": 7\n    },\n    {\n      \"field\": \"supplier_sku\",\n      \"operation\": \"set\",\n      \"supplier_id\": 7,\n      \"value\": \"VENDOR-PART-123\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3,\n    \"failed\": 0\n  }\n}"}]},{"name":"Bulk Edit Products (Individual)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-individual","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-individual"]},"description":"Apply individual per-product changes.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nMax 100 products per request. Each product's changes object supports:\n- Basic: name, brand_id, is_dropshippable, barcode, mpn, hts_code\n- Shipping: weight, weight_unit, length, width, height, dimension_unit, case_quantity, case_weight, case_weight_unit, case_length, case_width, case_height, case_dimension_unit, fba_prep_instructions\n- Costing: unit_cost, proforma_shipping_cost, proforma_landed_cost_percentage, proforma_marketplace_cost_percentage\n- Accounting: sales_nominal_code_id, cogs_nominal_code_id, inventory_nominal_code_id, inventory_in_transit_nominal_code_id, accrued_purchases_nominal_code_id, discount_nominal_code_id\n- Tax: is_taxable, default_tax_rate_id\n- Taxonomy: primary_category_id, tags_add (array), tags_remove (array)\n- Inventory: min_stock_level\n- Pricing: pricing[].tier_id + pricing[].price\n- Attributes: attributes[].attribute_id + attributes[].value","body":{"mode":"raw","raw":"{\n  \"products\": [\n    {\n      \"id\": 42,\n      \"changes\": {\n        \"name\": \"Blue Widget Pro\",\n        \"weight\": 0.6,\n        \"weight_unit\": \"kg\",\n        \"unit_cost\": 5.75,\n        \"is_dropshippable\": false,\n        \"min_stock_level\": 100,\n        \"pricing\": [\n          {\n            \"tier_id\": 1,\n            \"price\": 13.99\n          }\n        ],\n        \"attributes\": [\n          {\n            \"attribute_id\": 1,\n            \"value\": \"Blue\"\n          }\n        ],\n        \"supplier_skus\": [\n          {\n            \"supplier_id\": 7,\n            \"supplier_sku\": \"VENDOR-PART-123\"\n          }\n        ],\n        \"tags_add\": [\n          \"new-tag\"\n        ],\n        \"tags_remove\": [\n          \"old-tag\"\n        ]\n      }\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-individual","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-individual"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 1,\n    \"failed\": 0\n  }\n}"}]},{"name":"Preview Bulk Edit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-preview","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-preview"]},"description":"Preview bulk edit changes without applying them (dry run). Safe to call repeatedly.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFor mode='apply_to_all': requires product_ids and changes.\nFor mode='individual': requires products[].id and products[].changes.","body":{"mode":"raw","raw":"{\n  \"mode\": \"apply_to_all\",\n  \"product_ids\": [\n    42,\n    43\n  ],\n  \"changes\": [\n    {\n      \"field\": \"weight\",\n      \"operation\": \"set\",\n      \"value\": 0.6\n    },\n    {\n      \"field\": \"supplier_pricing\",\n      \"operation\": \"set\",\n      \"tier_id\": 1,\n      \"value\": 4.75\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bulk-edit-preview","host":["{{baseUrl}}"],"path":["api","v2","products","bulk-edit-preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 42,\n      \"sku\": \"WDG-001\",\n      \"changes\": [\n        {\n          \"field\": \"weight\",\n          \"field_label\": \"Weight\",\n          \"old_value\": 0.5,\n          \"new_value\": 0.6\n        },\n        {\n          \"field\": \"supplier_pricing.1.3\",\n          \"field_label\": \"Supplier Price: Global Supplies Ltd — Default\",\n          \"old_value\": 4.5,\n          \"new_value\": 4.75\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Bundle Workshop Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"List all bundle/kit products with component counts and configuration status.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5,\n      \"sku\": \"BUNDLE-001\",\n      \"name\": \"Widget Bundle\",\n      \"type\": \"bundle\",\n      \"image_url\": null,\n      \"components_count\": 2,\n      \"is_configured\": true\n    }\n  ],\n  \"total\": 12,\n  \"per_page\": 10\n}"}]},{"name":"Auto-Detect Bundle Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/auto-detect?filter[confidence]=high&filter[mode]=suggestions&page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","auto-detect"],"query":[{"key":"filter[confidence]","value":"high","description":"Confidence filter: all, high, medium, low","disabled":true},{"key":"filter[mode]","value":"suggestions","description":"Mode: suggestions (pattern-matched only) or all (all standard products)","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}]},"description":"Auto-detect standard products that may be bundles/kits based on naming patterns.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns products with detected_pattern, suggested_type, confidence, has_inventory_movements, and components_count (number of components already configured on the product — used by the conversion queue to know whether component configuration is required before converting to bundle/kit)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/auto-detect?filter[confidence]=high&filter[mode]=suggestions&page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","auto-detect"],"query":[{"key":"filter[confidence]","value":"high","description":"Confidence filter: all, high, medium, low","disabled":true},{"key":"filter[mode]","value":"suggestions","description":"Mode: suggestions (pattern-matched only) or all (all standard products)","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 100,\n      \"sku\": \"BUNDLE-KIT-001\",\n      \"name\": \"Widget Bundle Kit\",\n      \"type\": \"standard\",\n      \"image_url\": null,\n      \"detected_pattern\": \"bundle_suffix\",\n      \"suggested_type\": \"bundle\",\n      \"confidence\": \"high\",\n      \"has_inventory_movements\": false,\n      \"components_count\": 0\n    }\n  ],\n  \"total\": 8,\n  \"per_page\": 20\n}"}]},{"name":"Batch Convert Products to Bundle/Kit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/batch-convert","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","batch-convert"]},"description":"Batch convert standard products to bundle/kit types.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- products (required, array, min 1): Products to convert\n  - id (required, integer): Product ID\n  - type (required, string): Target type — bundle, kit, or standard\n  - components (optional, array): Components to save on the product BEFORE converting. Only applies when type is bundle or kit. Allows converting a product that currently has zero components in a single atomic call.\n    - id (required, integer, must exist in products): Component product ID. Components must be standard or kit products (a bundle cannot be a component).\n    - quantity (required, numeric, min 1): Quantity of this component per parent unit.\n\n**Component handling:** When `components` is provided for a bundle/kit target, they are saved first (via the bundle/kit component setter for the target type), then the type conversion proceeds. If the component save fails (e.g. a component is itself a bundle, a kit component references itself, or a circular kit reference is detected), the item is skipped with the validation message as `reason` and the product type is left unchanged.\n\n**Skip rules — returned in `data.skipped[]`:**\n- Converting to `bundle` when the source product has prior sale/assembly inventory movements (cannot become a bundle once it has movement history).\n- Converting to `bundle` or `kit` when the source product has zero components AND no `components` were provided in the request (you must add components before promoting it).\n- Provided `components` failed validation (invalid component type, self/circular reference) — the validation message is returned as the skip reason.\n\nThe response payload includes `data.converted_count` for successful conversions and `data.skipped[]` for entries that were skipped, each with `id`, `sku`, and a human-readable `reason`.","body":{"mode":"raw","raw":"{\n  \"products\": [\n    {\n      \"id\": 100,\n      \"type\": \"bundle\",\n      \"components\": [\n        {\n          \"id\": 200,\n          \"quantity\": 2\n        },\n        {\n          \"id\": 201,\n          \"quantity\": 1\n        }\n      ]\n    },\n    {\n      \"id\": 101,\n      \"type\": \"kit\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/batch-convert","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","batch-convert"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"converted_count\": 2,\n    \"skipped\": [\n      {\n        \"id\": 102,\n        \"sku\": \"WIDGET-PACK\",\n        \"reason\": \"No components — add components before converting to bundle\"\n      }\n    ]\n  }\n}"}]},{"name":"Check Bundle Restrictions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/check-restrictions","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","check-restrictions"]},"description":"Check which products have sale/assembly inventory movements that would restrict type changes.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/check-restrictions","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop","check-restrictions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"42\": {\n      \"has_restriction\": false,\n      \"movement_count\": 0\n    },\n    \"43\": {\n      \"has_restriction\": true,\n      \"movement_count\": 5\n    }\n  }\n}"}]},{"name":"Get Bundle Components","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","components"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]},"description":"Get components for a specific bundle/kit product in the Bundle Workshop.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","components"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"sku\": \"COMP-A\",\n      \"name\": \"Component A\",\n      \"quantity\": 2\n    }\n  ]\n}"}]},{"name":"Save Bundle Components","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","components"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]},"description":"Save/sync components for a bundle/kit. Replaces all existing components.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- components (required, array, **min 1 entry**): Component list. Empty arrays are rejected — a bundle/kit must always have at least one component.\n  - id (required, integer): Component product ID\n  - quantity (required, numeric, min 1): Quantity of this component in the bundle\n\nReturns a 422 validation error if `components` is empty or missing.","body":{"mode":"raw","raw":"{\n  \"components\": [\n    {\n      \"id\": 10,\n      \"quantity\": 2\n    },\n    {\n      \"id\": 11,\n      \"quantity\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/components","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","components"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"components_count\": 2\n  }\n}"}]},{"name":"Get Restricting Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/restricting-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","restricting-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"product","value":"5","description":"Product ID"}]},"description":"Get paginated sale/assembly inventory movements that restrict type changes for a product.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/restricting-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","restricting-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"product","value":"5","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 2001,\n      \"type\": \"assembly\",\n      \"quantity\": -2,\n      \"reference\": \"ASM-0015\",\n      \"warehouse_name\": \"Main Warehouse\",\n      \"inventory_movement_date\": \"2024-04-10\"\n    }\n  ],\n  \"total\": 5,\n  \"per_page\": 15\n}"}]},{"name":"Update Bundle Type","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/type","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","type"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]},"description":"Update the type of an existing bundle/kit product (bundle ↔ kit ↔ standard).\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly bundle or kit products can have their type changed via this endpoint.\n\n**Component requirement:** Converting to `bundle` or `kit` requires the product to already have at least one component. Returns a 422 with `Cannot convert to a bundle or kit without at least one component. Add components first.` when the source product has zero components.","body":{"mode":"raw","raw":"{\n  \"type\": \"kit\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/products/bundle-workshop/{product}/type","host":["{{baseUrl}}"],"path":["api","v2","products","bundle-workshop",":product","type"],"variable":[{"key":"product","value":"5","description":"Bundle/Kit Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"type\": \"kit\"\n  }\n}"}]},{"name":"Download Supplier Link Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links/template","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links","template"]},"description":"Download the supplier link import template XLSX.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: XLSX file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links/template","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file)"}]},{"name":"Validate Supplier Link Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links/validate","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links","validate"]},"description":"Validate supplier link import data and return a preview.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- rows (required, array, min 1): Rows to validate\n  - product_sku (present): Product SKU\n  - supplier_name (present): Supplier name","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"product_sku\": \"WDG-001\",\n      \"supplier_name\": \"Global Supplies Ltd\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links/validate","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"valid\": 1,\n  \"invalid\": 0,\n  \"rows\": [\n    {\n      \"product_sku\": \"WDG-001\",\n      \"supplier_name\": \"Global Supplies Ltd\",\n      \"valid\": true\n    }\n  ]\n}"}]},{"name":"Import Supplier Links","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links"]},"description":"Imports run as a tracked job — a bulk import can exceed a ~100s edge-proxy limit (Cloudflare 524), so the rows are processed off the request cycle. Returns a tracked_job_log_id; progress and the created/updated/failed counts surface via the tracked job log endpoints.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"links\": [\n    {\n      \"product_id\": 42,\n      \"supplier_id\": 3,\n      \"supplier_product_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/import-supplier-links","host":["{{baseUrl}}"],"path":["api","v2","products","import-supplier-links"]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5123\n  },\n  \"message\": \"Import queued — track progress in the job tray.\"\n}"}]},{"name":"Export Product List","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/list/export?format=xlsx&scope=filtered&content_mode=summary&columns=id,sku,name,type,inventory_total","host":["{{baseUrl}}"],"path":["api","v2","products","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default, uses active filters), all, current_page, selected","disabled":true},{"key":"content_mode","value":"summary","description":"Content mode: summary (default, one row per product) or suppliers (one row per product-supplier link; emits the per-link supplier columns and omits the duplicate product-level Default Supplier columns)","disabled":true},{"key":"columns","value":"id,sku,name,type,inventory_total","description":"Comma-separated column keys to include. Omit for all columns. Available columns now include: stock_uom_code, stock_uom_name.","disabled":true}]},"description":"Export products as XLSX or CSV.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nScope options:\n- filtered: Uses current filter parameters (same as the products list)\n- all: All products (ignores filters)\n- current_page: First page of current filter results\n- selected: Specific product IDs (requires ids param)\n\nContent modes:\n- summary: One row per product (includes the product-level Default Supplier columns when requested)\n- suppliers: One row per product-supplier link. Emits the per-link supplier columns (Supplier Name, Supplier SKU, MOQ, Leadtime, Target Stock Days, Is Default, pricing tiers) and omits the duplicate product-level Default Supplier columns, so the file round-trips 1:1 with the supplier-links import template.\n\nResponse (dual mode):\n- Small exports (≤ 1000 records, or scope=current_page): Returns the file directly as a binary download (XLSX or CSV).\n- Large exports (> 1000 records): Returns 200 application/json with `{ data: { tracked_job_log_id, queued: true }, message }`. The export is dispatched as a background job; track it via the tracked job log endpoints. Once complete, download via `GET /api/v2/products/list/export/download?file=<filename>` (the job's `results.file` value).\n\n**Requires permission:** `products.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/list/export?format=xlsx&scope=filtered&content_mode=summary&columns=id,sku,name,type,inventory_total","host":["{{baseUrl}}"],"path":["api","v2","products","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default, uses active filters), all, current_page, selected","disabled":true},{"key":"content_mode","value":"summary","description":"Content mode: summary (default, one row per product) or suppliers (one row per product-supplier link; emits the per-link supplier columns and omits the duplicate product-level Default Supplier columns)","disabled":true},{"key":"columns","value":"id,sku,name,type,inventory_total","description":"Comma-separated column keys to include. Omit for all columns. Available columns now include: stock_uom_code, stock_uom_name.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file)"}]},{"name":"Download Export File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/list/export/download?file=products-export-2026-05-12-153045.xlsx","host":["{{baseUrl}}"],"path":["api","v2","products","list","export","download"],"query":[{"key":"file","value":"products-export-2026-05-12-153045.xlsx","description":"Filename returned by the queued export tracked job (`results.file`). Only basename is used server-side.","disabled":true}]},"description":"Download a completed products export file produced by a queued export tracked job.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUse this after `GET /api/v2/products/list/export` returned a queued JSON response. Poll the tracked job log endpoints for completion, then fetch the `results.file` value from the TrackedJobLog and pass it as the `file` query parameter.\n\nResponse: File download (XLSX or CSV). Returns 404 if the file does not exist on the `model-exports` disk.\n\n**Requires permission:** `products.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/list/export/download?file=products-export-2026-05-12-153045.xlsx","host":["{{baseUrl}}"],"path":["api","v2","products","list","export","download"],"query":[{"key":"file","value":"products-export-2026-05-12-153045.xlsx","description":"Filename returned by the queued export tracked job (`results.file`). Only basename is used server-side.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file)"}]},{"name":"Lookup Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/lookup","host":["{{baseUrl}}"],"path":["api","v2","products","lookup"]},"description":"Lightweight paginated product lookup that returns only core identifying fields (id, sku, name, barcode, type, unit_cost, price, image_url) — much faster than the full List Products endpoint when you only need to resolve products by SKU, name, barcode, or id.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWhen a search term is given, results are ranked exact-SKU match first, SKU prefix match second, then everything else; within each rank results are ordered by SKU. A fully-numeric term additionally matches the product id directly. Without a search term, all products are returned ordered by SKU.\n\nArchived products are excluded unless include_archived=true. Pass sellable_only=true to exclude non-sellable products (e.g. internal consumables).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/lookup","host":["{{baseUrl}}"],"path":["api","v2","products","lookup"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WIDGET-BLUE\",\n      \"name\": \"Blue Widget\",\n      \"barcode\": 123456789012,\n      \"type\": \"standard\",\n      \"unit_cost\": 4.5,\n      \"price\": 4.5,\n      \"image_url\": \"https://example.sku.io/storage/images/widget-blue.jpg\"\n    },\n    {\n      \"id\": 87,\n      \"sku\": \"WIDGET-BLUE-2PK\",\n      \"name\": \"Blue Widget - 2 Pack\",\n      \"barcode\": 123456789029,\n      \"type\": \"bundle\",\n      \"unit_cost\": 9,\n      \"price\": 9,\n      \"image_url\": null\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/v2/products/lookup?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/v2/products/lookup?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.sku.io/api/v2/products/lookup?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/v2/products/lookup\",\n  \"per_page\": 20,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Paginated list of Magento 2 products scoped to one integration instance.\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer) — Magento 2 IntegrationInstance ID.\n\n**Pagination:** default `per_page=25`. Default sort: `-id`.\n\n**Quick filters (exact):** `type_id`, `status`, `visibility`, `magento_parent_id`, `attribute_set_id`, `integration_instance_id`.\n\n**Special filters:**\n- `filter[search]` — LIKE across sku + name; numeric values also match magento_entity_id.\n- `filter[sku_product_id]` — `mapped` / `unmapped` / `all`, or a numeric SKU.io product id.\n- `filter[archived]` — `true` (archived only), `false` (active only — default behavior), `all`.\n- `filter[integration_instance_ids]` — accepted as a no-op for channel-layout parity.\n\n**Advanced filters (AdvancedFilterBuilder, operator-aware):**\n- Text columns (operators: equals, not_equals, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty): `sku`, `name`, `type_id`, `status`, `visibility`.\n- Numeric columns (operators: equals, not_equals, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty): `price`, `cost`, `weight`.\n- Datetime columns (operators: equals, not_equals, greater_than, less_than, is_within, is_empty, is_not_empty): `magento_created_at`, `magento_updated_at`, `created_at`, `updated_at`.\n\n**Sorts:** id, magento_entity_id, sku, name, type_id, status, visibility, price, cost, weight, attribute_set_id, magento_parent_id, magento_created_at, magento_updated_at, created_at, updated_at.\n\n**Eager-loads:** `integrationInstance`, `parent` (the configurable parent for simple variants)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 312,\n      \"integration_instance_id\": 42,\n      \"magento_id\": 1024,\n      \"magento_entity_id\": 1024,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Acme Widget\",\n      \"type_id\": \"simple\",\n      \"status\": 1,\n      \"visibility\": 4,\n      \"price\": 19.99,\n      \"cost\": 7.5,\n      \"weight\": 0.45,\n      \"attribute_set_id\": 4,\n      \"qty\": 128,\n      \"store_id\": 1,\n      \"store_view_code\": \"default\",\n      \"url_key\": \"acme-widget\",\n      \"image_url\": \"https://shop.example.com/pub/media/catalog/product/a/c/acme-widget.jpg\",\n      \"magento_parent_id\": null,\n      \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n      \"magento_updated_at\": \"2026-06-15T11:22:18+00:00\",\n      \"created_at\": \"2026-02-12T18:30:00+00:00\",\n      \"updated_at\": \"2026-06-15T11:30:00+00:00\",\n      \"archived_at\": null,\n      \"last_sync_at\": \"2026-06-15T11:30:00+00:00\",\n      \"sku_product_id\": 8821,\n      \"sku_product_listing_id\": null,\n      \"sku_product_sku\": \"WIDGET-001\",\n      \"sku_product_name\": \"Acme Widget\",\n      \"is_mapped\": true,\n      \"mapped_at\": \"2026-06-15T11:30:00+00:00\",\n      \"magento_admin_url\": \"https://shop.example.com/admin/catalog/product/edit/id/1024\",\n      \"inventory_caches\": [],\n      \"raw_payload\": null\n    },\n    {\n      \"id\": 313,\n      \"integration_instance_id\": 42,\n      \"magento_id\": 1025,\n      \"magento_entity_id\": 1025,\n      \"sku\": \"WIDGET-002\",\n      \"name\": \"Acme Widget Pro\",\n      \"type_id\": \"simple\",\n      \"status\": 1,\n      \"visibility\": 4,\n      \"price\": 29.99,\n      \"cost\": 11.25,\n      \"weight\": 0.6,\n      \"attribute_set_id\": 4,\n      \"qty\": 42,\n      \"store_id\": 1,\n      \"store_view_code\": \"default\",\n      \"url_key\": \"acme-widget-pro\",\n      \"image_url\": null,\n      \"magento_parent_id\": null,\n      \"magento_created_at\": \"2026-02-12T18:02:01+00:00\",\n      \"magento_updated_at\": \"2026-06-15T11:22:18+00:00\",\n      \"created_at\": \"2026-02-12T18:30:00+00:00\",\n      \"updated_at\": \"2026-06-15T11:30:00+00:00\",\n      \"archived_at\": null,\n      \"last_sync_at\": \"2026-06-15T11:30:00+00:00\",\n      \"sku_product_id\": null,\n      \"sku_product_listing_id\": null,\n      \"sku_product_sku\": null,\n      \"sku_product_name\": null,\n      \"is_mapped\": false,\n      \"mapped_at\": null,\n      \"magento_admin_url\": \"https://shop.example.com/admin/catalog/product/edit/id/1025\",\n      \"inventory_caches\": [],\n      \"raw_payload\": null\n    }\n  ],\n  \"first_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/products?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-io-test/api/magento2/integration-instances/42/products\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Products Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","latest-sync-info"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Returns a summary of the most recent product sync: the latest product title and `magento_updated_at`, total / mapped / unmapped product counts, and the `last_synced_at` timestamp (the local `updated_at` of the most recently fetched product)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","latest-sync-info"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Acme Widget Pro\",\n    \"latest_product_date\": \"2026-06-15T11:22:18+00:00\",\n    \"total_products\": 412,\n    \"mapped_count\": 318,\n    \"unmapped_count\": 94,\n    \"last_synced_at\": \"2026-06-15T11:30:00+00:00\"\n  }\n}"}]},{"name":"Get Products Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Aggregated dropdown options for the products filter panel — `attribute_sets` (distinct `attribute_set_id` values surfaced as `{id, name}` pairs) and `categories` (distinct Magento category ids derived from each product's raw_payload category links, surfaced as `{id, name}` pairs labelled `Category #{id}` until category-name sync lands). Drawn live from the locally synced product rows; empty / never-synced instances surface empty lists."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"attribute_sets\": [\n      {\n        \"id\": 4,\n        \"name\": \"Attribute Set #4\"\n      },\n      {\n        \"id\": 9,\n        \"name\": \"Attribute Set #9\"\n      }\n    ],\n    \"categories\": [\n      {\n        \"id\": 3,\n        \"name\": \"Category #3\"\n      },\n      {\n        \"id\": 5,\n        \"name\": \"Category #5\"\n      }\n    ]\n  }\n}"}]},{"name":"Search Products (Magento live)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Searches the upstream Magento catalog directly, rather than products already synced to SKU.io. Currently returns an empty `data` array — live catalog search is not yet available. Use the product list endpoint with `filter[search]=…` to search synced products."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/field-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","field-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Returns the Magento attribute → SKU.io Product field mappings used by `FieldMappingSettingsModal`. Both arrays come from the integration instance's `integration_settings` JSON column (`product_field_mappings` and `magento_attributes`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/field-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","field-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"magento_field\": \"sku\",\n        \"sku_field\": \"sku\"\n      },\n      {\n        \"magento_field\": \"name\",\n        \"sku_field\": \"name\"\n      },\n      {\n        \"magento_field\": \"price\",\n        \"sku_field\": \"price\"\n      }\n    ],\n    \"magento_attributes\": [\n      {\n        \"attribute_code\": \"sku\",\n        \"frontend_label\": \"SKU\"\n      },\n      {\n        \"attribute_code\": \"name\",\n        \"frontend_label\": \"Name\"\n      },\n      {\n        \"attribute_code\": \"price\",\n        \"frontend_label\": \"Price\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/field-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","field-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Replace the stored `product_field_mappings` array. The modal always sends the full list, so the server overwrites (rather than merges).\n\n**Body:** `{ mappings: [{ magento_field, sku_field }] }` — both fields required strings per entry; `mappings` itself is required (may be an empty array to clear all mappings).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"magento_field\": \"sku\",\n      \"sku_field\": \"sku\"\n    },\n    {\n      \"magento_field\": \"name\",\n      \"sku_field\": \"name\"\n    },\n    {\n      \"magento_field\": \"price\",\n      \"sku_field\": \"price\"\n    },\n    {\n      \"magento_field\": \"weight\",\n      \"sku_field\": \"weight\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/field-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","field-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Field mappings saved.\"\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Dispatch the tracked job that refreshes Magento 2 products. Returns the `tracked_job_log_id` so the frontend can pivot the global JobProgressTray to it. Job name prefix is `Refresh Magento 2 Products: ` — the page's `lastCompletedJob` watcher matches on this prefix.\n\n**Body params (all optional):**\n- `mode` — one of `since_latest` (default), `full_catalog`, `from_start_date`, `date_range`. Drives the cursor the job resolves.\n- `updated_at` — ISO datetime string used when `mode=since_latest` to override the auto-detected high-water mark.\n- `date_from` / `date_to` — ISO datetime strings used when `mode=from_start_date` (uses `date_from` only) or `mode=date_range` (uses both).","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"updated_at\": \"2026-06-15 12:00:00\",\n  \"date_from\": null,\n  \"date_to\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 92041\n  },\n  \"message\": \"Product sync queued.\"\n}"}]},{"name":"Bulk Map Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-map","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-map"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Bulk-map Magento products to SKU.io Products by SKU / SKU-contains / name. **Synchronous** (no tracked job) and **caps at 500 products per call** to keep the request bounded.\n\n**Body:**\n- `selection.type` — `selected` (use `ids`) or `filtered` (apply across the currently filtered set; the unmapped-only constraint always applies).\n- `selection.ids` — array of `magento2_products.id` (required when `type=selected`).\n- `selection.filters` — filter object (used when `type=filtered`).\n- `options.match_by` — `sku` (exact Magento SKU == SKU.io Product SKU), `sku_contains` (SKU.io Product SKU `LIKE %magento_sku%`), or `name` (SKU.io Product name == Magento name).\n- `options.create_if_no_match` — when true, create a new SKU.io Product for any Magento product that doesn't match (uses the Magento sku + name).\n\nReturns counts: `mapped`, `skipped`, `total`. `tracked_job_log_id` is always `null` (kept in the response shape for frontend symmetry with the other bulk ops).","body":{"mode":"raw","raw":"{\n  \"selection\": {\n    \"type\": \"selected\",\n    \"ids\": [\n      312,\n      313,\n      314\n    ]\n  },\n  \"options\": {\n    \"match_by\": \"sku\",\n    \"create_if_no_match\": false\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-map","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-map"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": null,\n    \"mapped\": 2,\n    \"skipped\": 1,\n    \"total\": 3\n  },\n  \"message\": \"Mapped 2 of 3 products (1 skipped).\"\n}"}]},{"name":"Bulk Unmap Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-unmap","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-unmap"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Clear `sku_product_id` + `sku_product_listing_id` on the selected products. Synchronous.\n\n**Body:**\n- `select_all` — when true, applies across every product in the instance (ignores `ids`).\n- `ids` — array of `magento2_products.id` to unmap (used when `select_all` is false / omitted).","body":{"mode":"raw","raw":"{\n  \"select_all\": false,\n  \"ids\": [\n    312,\n    313\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-unmap","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-unmap"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product(s) unmapped.\"\n}"}]},{"name":"Bulk Archive Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-archive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-archive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Sets `archived_at = now()` on the selected products. Synchronous. Same body shape as `Bulk Unmap Products` (`select_all` + `ids`).","body":{"mode":"raw","raw":"{\n  \"select_all\": false,\n  \"ids\": [\n    312,\n    313\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-archive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-archive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product(s) archived.\"\n}"}]},{"name":"Bulk Unarchive Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-unarchive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Clears `archived_at` on the selected products. Synchronous. Same body shape as `Bulk Unmap Products` (`select_all` + `ids`).","body":{"mode":"raw","raw":"{\n  \"select_all\": false,\n  \"ids\": [\n    312,\n    313\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-unarchive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product(s) unarchived.\"\n}"}]},{"name":"Bulk Delete Magento Records","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-delete-magento-records","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-delete-magento-records"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Delete the local Magento product records for the selected ids (does NOT delete anything in Magento itself — only the locally synced rows). Synchronous. Same body shape as the other bulk ops (`select_all` + `ids`).\n\nResponse keeps `tracked_job_log_id` in the data envelope (always `null`) for frontend symmetry with the other bulk handlers.","body":{"mode":"raw","raw":"{\n  \"select_all\": false,\n  \"ids\": [\n    312,\n    313\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/bulk-delete-magento-records","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products","bulk-delete-magento-records"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": null\n  },\n  \"message\": \"2 product(s) deleted.\"\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Single product detail. Eager-loads `integrationInstance`, `parent`, and `children` (the children collection populates only for configurable products).\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer).\n- `product` (required, integer) — Internal `magento2_products.id`.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance.\n- `401` — caller is not authenticated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"integration_instance_id\": 42,\n    \"magento_id\": 1024,\n    \"magento_entity_id\": 1024,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Acme Widget\",\n    \"type_id\": \"simple\",\n    \"status\": 1,\n    \"visibility\": 4,\n    \"price\": 19.99,\n    \"cost\": 7.5,\n    \"weight\": 0.45,\n    \"attribute_set_id\": 4,\n    \"qty\": 128,\n    \"store_id\": 1,\n    \"store_view_code\": \"default\",\n    \"url_key\": \"acme-widget\",\n    \"image_url\": \"https://shop.example.com/pub/media/catalog/product/a/c/acme-widget.jpg\",\n    \"magento_parent_id\": null,\n    \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n    \"magento_updated_at\": \"2026-06-15T11:22:18+00:00\",\n    \"created_at\": \"2026-02-12T18:30:00+00:00\",\n    \"updated_at\": \"2026-06-15T11:30:00+00:00\",\n    \"archived_at\": null,\n    \"last_sync_at\": \"2026-06-15T11:30:00+00:00\",\n    \"sku_product_id\": 8821,\n    \"sku_product_listing_id\": null,\n    \"sku_product_sku\": \"WIDGET-001\",\n    \"sku_product_name\": \"Acme Widget\",\n    \"is_mapped\": true,\n    \"mapped_at\": \"2026-06-15T11:30:00+00:00\",\n    \"magento_admin_url\": \"https://shop.example.com/admin/catalog/product/edit/id/1024\",\n    \"inventory_caches\": [],\n    \"parent\": null,\n    \"children\": [],\n    \"raw_payload\": null\n  }\n}"}]},{"name":"Delete Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Delete the local Magento product row (does NOT delete anything in Magento itself). No body.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product deleted.\"\n}"}]},{"name":"Get Orders For Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","orders"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Paginated list of Magento 2 orders that contain this product. The match is `lineItems.magento_product_id = product.magento_entity_id` OR (when the product has a SKU) `lineItems.sku = product.sku`. Ordered by `magento_created_at DESC`. Eager-loads `integrationInstance` + `lineItems`.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","orders"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 7821,\n      \"integration_instance_id\": 42,\n      \"magento_id\": 50012,\n      \"magento_entity_id\": 50012,\n      \"increment_id\": \"000050012\",\n      \"status\": \"complete\",\n      \"customer_email\": \"buyer@example.com\",\n      \"grand_total\": 39.98,\n      \"magento_created_at\": \"2026-06-12T14:18:09+00:00\",\n      \"magento_updated_at\": \"2026-06-12T15:02:33+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/products/312/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-io-test/api/magento2/integration-instances/42/products/312/orders?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-io-test/api/magento2/integration-instances/42/products/312/orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Raw Product Payload","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","raw"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Returns the stored `raw_payload` JSON (the exact Magento REST product shape we last upserted). Intended for debugging the mapping pipeline; the frontend exposes it in the detail drawer's Raw tab. Returns `{}` when no payload has been stored."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","raw"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 1024,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Acme Widget\",\n      \"price\": 19.99,\n      \"status\": 1,\n      \"visibility\": 4,\n      \"type_id\": \"simple\",\n      \"attribute_set_id\": 4,\n      \"created_at\": \"2026-02-12 18:01:33\",\n      \"updated_at\": \"2026-06-15 11:22:18\",\n      \"weight\": 0.45,\n      \"extension_attributes\": {\n        \"stock_item\": {\n          \"qty\": 128,\n          \"is_in_stock\": true\n        }\n      },\n      \"custom_attributes\": [\n        {\n          \"attribute_code\": \"cost\",\n          \"value\": \"7.50\"\n        },\n        {\n          \"attribute_code\": \"url_key\",\n          \"value\": \"acme-widget\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Map Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","map"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Map a single Magento product to a SKU.io Product.\n\n**Body:**\n- `sku_product_id` (integer | null) — the SKU.io `products.id` to link to. Pass `null` to clear the mapping (equivalent to `Unmap Product`).\n\nReturns the refreshed `Magento2ProductResource` so the frontend can swap the row.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance.","body":{"mode":"raw","raw":"{\n  \"sku_product_id\": 8821\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","map"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"integration_instance_id\": 42,\n    \"magento_id\": 1024,\n    \"magento_entity_id\": 1024,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Acme Widget\",\n    \"type_id\": \"simple\",\n    \"status\": 1,\n    \"visibility\": 4,\n    \"price\": 19.99,\n    \"cost\": 7.5,\n    \"weight\": 0.45,\n    \"attribute_set_id\": 4,\n    \"sku_product_id\": 8821,\n    \"sku_product_listing_id\": null,\n    \"sku_product_sku\": \"WIDGET-001\",\n    \"sku_product_name\": \"Acme Widget\",\n    \"is_mapped\": true,\n    \"mapped_at\": \"2026-06-21T12:00:00+00:00\",\n    \"updated_at\": \"2026-06-21T12:00:00+00:00\"\n  }\n}"}]},{"name":"Unmap Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/unmap","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","unmap"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Clears `sku_product_id` and `sku_product_listing_id` on a single Magento product (no body). Returns the refreshed `Magento2ProductResource`.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/unmap","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","unmap"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"integration_instance_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Acme Widget\",\n    \"sku_product_id\": null,\n    \"sku_product_listing_id\": null,\n    \"sku_product_sku\": null,\n    \"sku_product_name\": null,\n    \"is_mapped\": false,\n    \"mapped_at\": null,\n    \"updated_at\": \"2026-06-21T12:01:00+00:00\"\n  }\n}"}]},{"name":"Smart Match SKU Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","smart-match"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Suggest SKU.io products that could be mapped to this Magento 2 product. Returns three buckets:\n\n- `exact_match` — the SKU.io product whose `sku` is identical to the Magento product's SKU (or `null` if no match).\n- `barcode_match` — the SKU.io product whose barcode matches the Magento product's barcode (or `null`).\n- `similar_matches` — fuzzy name/SKU matches, capped by `limit`.\n\n**Body (optional):**\n- `query` (string, max 255) — free-text search term. When omitted, the manager seeds the search with the Magento product's `name` (falling back to `sku`).\n- `limit` (integer, 1–50) — max similar matches to return. Defaults to 10.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance.\n- `422` — validation failed on `query` or `limit`.","body":{"mode":"raw","raw":"{\n  \"query\": \"widget\",\n  \"limit\": 10\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","smart-match"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 8821,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Acme Widget\",\n      \"image_url\": \"https://cdn.sku.io/products/widget-001.jpg\",\n      \"match_type\": \"sku\",\n      \"match_score\": 1\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 8835,\n        \"sku\": \"WIDGET-002\",\n        \"name\": \"Acme Widget Pro\",\n        \"image_url\": null,\n        \"match_type\": \"fuzzy\",\n        \"match_score\": 0.74\n      },\n      {\n        \"id\": 9112,\n        \"sku\": \"WGT-RED-01\",\n        \"name\": \"Red Widget\",\n        \"image_url\": null,\n        \"match_type\": \"fuzzy\",\n        \"match_score\": 0.52\n      }\n    ]\n  }\n}"}]},{"name":"Create SKU Product From Magento","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","create-sku-product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Create a brand-new SKU.io product seeded from this Magento 2 product (with optional user overrides + a field-mapping override list), then map the Magento row to the newly created SKU product. The whole operation runs inside a single DB transaction.\n\n**Idempotency:** if a SKU.io product with the supplied `sku` already exists, the manager links to that existing product instead of creating a new one. The response then sets `linked_existing: true` and the message becomes `\"Linked to existing SKU product.\"`.\n\n**Pre-condition:** the Magento product MUST be unmapped. Mapped products return `422` and must be unmapped first.\n\n**Body (all fields optional; modal pre-fills from Magento):**\n- `sku` (string, max 255)\n- `name` (string, max 255)\n- `description` (string)\n- `image_url` (string, max 1024)\n- `barcode` (string, max 255)\n- `cost` (number ≥ 0)\n- `price` (number ≥ 0)\n- `weight` (number ≥ 0)\n- `field_mappings[]` — array of `{ magento_field, sku_field }` pairs the manager applies to the Magento payload before persisting. Same shape `GET .../products/field-mappings` returns.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance.\n- `422` — product is already mapped, or validation failed.","body":{"mode":"raw","raw":"{\n  \"sku\": \"WIDGET-001\",\n  \"name\": \"Acme Widget\",\n  \"description\": \"Imported from Magento on 2026-06-30.\",\n  \"image_url\": \"https://cdn.example-magento.com/media/catalog/product/w/i/widget.jpg\",\n  \"barcode\": 12345678905,\n  \"cost\": 7.5,\n  \"price\": 19.99,\n  \"weight\": 0.45,\n  \"field_mappings\": [\n    {\n      \"magento_field\": \"sku\",\n      \"sku_field\": \"sku\"\n    },\n    {\n      \"magento_field\": \"name\",\n      \"sku_field\": \"name\"\n    },\n    {\n      \"magento_field\": \"description\",\n      \"sku_field\": \"description\"\n    },\n    {\n      \"magento_field\": \"weight\",\n      \"sku_field\": \"weight\"\n    },\n    {\n      \"magento_field\": \"barcode\",\n      \"sku_field\": \"barcode\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","create-sku-product"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"integration_instance_id\": 42,\n    \"magento_id\": 1024,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Acme Widget\",\n    \"sku_product_id\": 8821,\n    \"sku_product_sku\": \"WIDGET-001\",\n    \"sku_product_name\": \"Acme Widget\",\n    \"is_mapped\": true,\n    \"mapped_at\": \"2026-06-30T12:00:00+00:00\",\n    \"updated_at\": \"2026-06-30T12:00:00+00:00\"\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped.\"\n}"}]},{"name":"Refresh Single Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/refresh-single","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","refresh-single"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"**Synchronous** single-product resync. Looks up the product in Magento by its SKU, upserts the local row, and returns the refreshed `Magento2ProductResource` so the frontend can swap the row in place. No `tracked_job_log_id` is returned (unlike the bulk `Refresh Products` endpoint).\n\n**No request body.**\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance.\n- `422` — local product row has no SKU (cannot resolve it against Magento).\n- `502` (or the upstream status, when 4xx) — the Magento API call failed."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/refresh-single","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","refresh-single"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"integration_instance_id\": 42,\n    \"magento_id\": 1024,\n    \"magento_entity_id\": 1024,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Acme Widget\",\n    \"type_id\": \"simple\",\n    \"status\": 1,\n    \"visibility\": 4,\n    \"price\": 19.99,\n    \"cost\": 7.5,\n    \"weight\": 0.45,\n    \"attribute_set_id\": 4,\n    \"qty\": 128,\n    \"store_id\": 1,\n    \"store_view_code\": \"default\",\n    \"url_key\": \"acme-widget\",\n    \"image_url\": \"https://shop.example.com/pub/media/catalog/product/a/c/acme-widget.jpg\",\n    \"magento_parent_id\": null,\n    \"magento_created_at\": \"2026-02-12T18:01:33+00:00\",\n    \"magento_updated_at\": \"2026-06-21T12:05:00+00:00\",\n    \"created_at\": \"2026-02-12T18:30:00+00:00\",\n    \"updated_at\": \"2026-06-21T12:05:00+00:00\",\n    \"archived_at\": null,\n    \"last_sync_at\": \"2026-06-21T12:05:00+00:00\",\n    \"sku_product_id\": 8821,\n    \"sku_product_listing_id\": null,\n    \"sku_product_sku\": \"WIDGET-001\",\n    \"sku_product_name\": \"Acme Widget\",\n    \"is_mapped\": true,\n    \"mapped_at\": \"2026-06-21T12:05:00+00:00\",\n    \"magento_admin_url\": \"https://shop.example.com/admin/catalog/product/edit/id/1024\",\n    \"inventory_caches\": [],\n    \"raw_payload\": null\n  },\n  \"message\": \"Product refreshed.\"\n}"}]},{"name":"Archive Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","archive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Archive a single product (sets `archived_at = now()`). No body.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","archive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product archived.\"\n}"}]},{"name":"Unarchive Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","unarchive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]},"description":"Unarchive a single product (clears `archived_at`). No body.\n\n**Error responses:**\n- `404` — product does not exist OR belongs to a different instance."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","products",":product","unarchive"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"product","value":"312","description":"Internal magento2_products.id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product unarchived.\"\n}"}]}]},{"name":"Product Import","item":[{"name":"Get Import Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/import/fields","host":["{{baseUrl}}"],"path":["api","v2","products","import","fields"]},"description":"Returns dynamic import fields (currently account-specific attributes) used by the column mapping UI.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRoute: v2.products.import.fields\n\nResponse shape: { data: { attributes: [{ key, label }] } }\n\n**Stock UoM (added 2026-05-30):** `stock_uom_code` is now a supported field. Provide a value matching an existing UoM code (e.g. EACH, KG, BOX). On create, it sets the product's initial stock UoM; on update, it flips the stock UoM to the matching uom_id."}},{"name":"Download Import Template (XLSX)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/import/template","host":["{{baseUrl}}"],"path":["api","v2","products","import","template"]},"description":"Downloads the multi-sheet XLSX import template, prefilled with sample rows and tenant reference data (brands, categories).\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRoute: v2.products.import.template\n\nupdate: the data sheet now includes nine new purple-headed image URL columns:\n- image_url_1 — Primary Image URL\n- image_url_2 .. image_url_9 — Additional gallery image URLs\n\nThe guide sheet documents these columns. Sample rows include picsum.photos placeholder URLs for image_url_1, image_url_2, and image_url_3.\n\nResponse: binary XLSX file (Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet).\n\n**Stock UoM (added 2026-05-30):** `stock_uom_code` is now a supported field. Provide a value matching an existing UoM code (e.g. EACH, KG, BOX). On create, it sets the product's initial stock UoM; on update, it flips the stock UoM to the matching uom_id."}},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/import/validate","host":["{{baseUrl}}"],"path":["api","v2","products","import","validate"]},"description":"Validates mapped import rows and returns a structured preview. No side effects — safe to call repeatedly.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRoute: v2.products.import.validate\n\nRequired body field:\n- rows: array (min 1) of row objects with mapped column keys.\n\nadded image URL fields to the accepted row shape:\n- rows[].image_url_1 (string) — Primary image URL (http/https only, max 2048 chars)\n- rows[].image_url_2 .. rows[].image_url_9 (string) — Additional gallery image URLs\n\nValidation rules for each image_url_N:\n- Must start with http:// or https://\n- Must pass FILTER_VALIDATE_URL\n- Must be <= 2048 characters\n- Duplicate URLs (case-insensitive) are skipped with a warning\n- If all image_url_* columns are blank/unmapped, existing product images are left unchanged\n\nResponse shape: { products: [...], summary: {...} }\n\nEach product entry includes a new field:\n- _image_urls: array of { url, is_primary, sort_order, download } | null\n  - null = no image_url_* columns mapped, OR all blank (existing images preserved)\n  - Otherwise: ordered by image_url_1..9 position; image_url_1 becomes is_primary=true; download=true triggers async download/storage on import.\n\nThe summary reports: total_products, total_new, total_updates, total_errors, total_warnings.\n\n**Stock UoM (added 2026-05-30):** `stock_uom_code` is now a supported field. Provide a value matching an existing UoM code (e.g. EACH, KG, BOX). On create, it sets the product's initial stock UoM; on update, it flips the stock UoM to the matching uom_id.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"sku\": \"SAMPLE-SKU-001\",\n      \"name\": \"Sample Product One\",\n      \"type\": \"standard\",\n      \"barcode\": 12345678901,\n      \"mpn\": \"MFG-001\",\n      \"hts_code\": \"8471.30.0100\",\n      \"brand\": \"Acme Co\",\n      \"category\": \"Widgets\",\n      \"unit_cost\": 9.99,\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"length\": 10,\n      \"width\": 5,\n      \"height\": 3,\n      \"dimension_unit\": \"cm\",\n      \"tags\": \"sample, import\",\n      \"image_url_1\": \"https://picsum.photos/seed/sku-001-front/600/600\",\n      \"image_url_2\": \"https://picsum.photos/seed/sku-001-back/600/600\",\n      \"image_url_3\": \"https://picsum.photos/seed/sku-001-side/600/600\",\n      \"image_url_4\": \"\",\n      \"image_url_5\": \"\",\n      \"image_url_6\": \"\",\n      \"image_url_7\": \"\",\n      \"image_url_8\": \"\",\n      \"image_url_9\": \"\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Execute Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/products/import","host":["{{baseUrl}}"],"path":["api","v2","products","import"]},"description":"Imports run as a tracked job — a bulk import can exceed a ~100s edge-proxy limit (Cloudflare 524), so the rows are processed off the request cycle. Returns a tracked_job_log_id; progress and the created/updated/failed counts surface via the tracked job log endpoints. The request body is the validated rows from the import preview.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"products\": [\n    {\n      \"sku\": \"SAMPLE-SKU-001\",\n      \"name\": \"Sample Product One\",\n      \"type\": \"standard\",\n      \"barcode\": 12345678901,\n      \"mpn\": \"MFG-001\",\n      \"hts_code\": \"8471.30.0100\",\n      \"brand_id\": 12,\n      \"category_id\": 7,\n      \"unit_cost\": 9.99,\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"length\": 10,\n      \"width\": 5,\n      \"height\": 3,\n      \"dimension_unit\": \"cm\",\n      \"tags\": \"sample, import\",\n      \"_image_urls\": [\n        {\n          \"url\": \"https://picsum.photos/seed/sku-001-front/600/600\",\n          \"is_primary\": true,\n          \"sort_order\": 0,\n          \"download\": true\n        },\n        {\n          \"url\": \"https://picsum.photos/seed/sku-001-back/600/600\",\n          \"is_primary\": false,\n          \"sort_order\": 1,\n          \"download\": true\n        },\n        {\n          \"url\": \"https://picsum.photos/seed/sku-001-side/600/600\",\n          \"is_primary\": false,\n          \"sort_order\": 2,\n          \"download\": true\n        }\n      ],\n      \"existing_product_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/products/import","host":["{{baseUrl}}"],"path":["api","v2","products","import"]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5123\n  },\n  \"message\": \"Import queued — track progress in the job tray.\"\n}"}]}]},{"name":"Organization","item":[{"name":"List Product Brands","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands?search=nike&sort=name&page=1&limit=25&archived=0","host":["{{baseUrl}}"],"path":["api","product-brands"],"query":[{"key":"search","value":"nike","description":"General text search across searchable columns (name)","disabled":true},{"key":"sort","value":"name","description":"Sort column. Prefix with - for descending (e.g. -name). Sortable: name, created_at, updated_at.","disabled":true},{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"25","description":"Results per page (default: 25)","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true}]},"description":"Returns a paginated list of product brands.\n\nAuthentication: Requires Bearer token.\n\nSupports search, sort, pagination, archived filter, and column inclusion/exclusion.\n\nAllowed sort fields: name, created_at, updated_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-brands?search=nike&sort=name&page=1&limit=25&archived=0","host":["{{baseUrl}}"],"path":["api","product-brands"],"query":[{"key":"search","value":"nike","description":"General text search across searchable columns (name)","disabled":true},{"key":"sort","value":"name","description":"Sort column. Prefix with - for descending (e.g. -name). Sortable: name, created_at, updated_at.","disabled":true},{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"25","description":"Results per page (default: 25)","disabled":true},{"key":"archived","value":"0","description":"0 = active only (default), 1 = archived only","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Nike\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-03-20T14:30:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Adidas\",\n      \"created_at\": \"2024-01-16T09:00:00.000000Z\",\n      \"updated_at\": \"2024-03-21T11:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 25,\n  \"total\": 112,\n  \"from\": 1,\n  \"to\": 25\n}"}]},{"name":"Create Product Brand","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-brands","host":["{{baseUrl}}"],"path":["api","product-brands"]},"description":"Creates a new product brand.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `name` (required, max 255, unique across product_brands)","body":{"mode":"raw","raw":"{\n  \"name\": \"Nike\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-brands","host":["{{baseUrl}}"],"path":["api","product-brands"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Nike\",\n    \"created_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Product brand has been created successfully\"\n}"}]},{"name":"Bulk Delete Product Brands","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands","host":["{{baseUrl}}"],"path":["api","product-brands"]},"description":"Bulk deletes multiple product brands by ID.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `ids` (required, array of integers)"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/product-brands","host":["{{baseUrl}}"],"path":["api","product-brands"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 product brands have been deleted successfully\"\n}"}]},{"name":"Get Product Brand","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single product brand by ID.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Nike\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-20T14:30:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Product Brand","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a product brand's name.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `name` (required, max 255, unique ignoring current record)","body":{"mode":"raw","raw":"{\n  \"name\": \"Nike Inc.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Nike Inc.\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Product brand Nike Inc. has been updated successfully\"\n}"}]},{"name":"Delete Product Brand","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a product brand. Fails if any products are still linked to the brand.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/product-brands/{id}","host":["{{baseUrl}}"],"path":["api","product-brands",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product brand Nike has been deleted successfully\"\n}"}]},{"name":"Archive Product Brand","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/{id}/archive","host":["{{baseUrl}}"],"path":["api","product-brands",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a product brand. Sets archived_at timestamp. Returns a warning if already archived.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-brands/{id}/archive","host":["{{baseUrl}}"],"path":["api","product-brands",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Nike\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T12:00:00.000000Z\",\n    \"archived_at\": \"2024-04-01T12:00:00.000000Z\"\n  },\n  \"message\": \"Product brand Nike has been archived successfully\"\n}"}]},{"name":"Unarchive Product Brand","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","product-brands",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a product brand. Clears archived_at. Returns a warning if already active.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-brands/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","product-brands",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Nike\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-04-01T12:30:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Product brand Nike has been unarchived successfully\"\n}"}]},{"name":"Bulk Archive Product Brands","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-brands/archive","host":["{{baseUrl}}"],"path":["api","product-brands","archive"]},"description":"Bulk archives multiple product brands.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-brands/archive","host":["{{baseUrl}}"],"path":["api","product-brands","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 product brands have been archived successfully\"\n}"}]},{"name":"Bulk Unarchive Product Brands","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-brands/unarchive","host":["{{baseUrl}}"],"path":["api","product-brands","unarchive"]},"description":"Bulk unarchives multiple product brands.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-brands/unarchive","host":["{{baseUrl}}"],"path":["api","product-brands","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 product brands have been unarchived successfully\"\n}"}]},{"name":"Check Product Brands Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-brands/deletable","host":["{{baseUrl}}"],"path":["api","product-brands","deletable"]},"description":"Checks whether each of the given product brand IDs can be safely deleted. A brand is not deletable if products are linked to it.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- `ids` (required, array of integers, each must exist in product_brands table)\n- `ids.*` (integer)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-brands/deletable","host":["{{baseUrl}}"],"path":["api","product-brands","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Nike\",\n      \"deletable\": false,\n      \"reason\": {\n        \"Products\": \"Product brand(Nike) is currently used by 12 product(s)\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Generic\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Unused Brand\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Search Product Brands","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/search?search=nike","host":["{{baseUrl}}"],"path":["api","product-brands","search"],"query":[{"key":"search","value":"nike","description":"Optional. Partial name match (LIKE %search%). Returns up to 50 results ordered by name.","disabled":true}]},"description":"Simple search endpoint returning up to 50 product brands matching the name. Returns product brand object collection.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-brands/search?search=nike","host":["{{baseUrl}}"],"path":["api","product-brands","search"],"query":[{"key":"search","value":"nike","description":"Optional. Partial name match (LIKE %search%). Returns up to 50 results ordered by name.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Nike\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-03-20T14:30:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 8,\n      \"name\": \"Nike Sport\",\n      \"created_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"updated_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ]\n}"}]},{"name":"Preview Product Brands Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/import/preview","host":["{{baseUrl}}"],"path":["api","product-brands","import","preview"]},"description":"Preview the result of importing product brands from a CSV/Excel file without committing the import.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-brands/import/preview","host":["{{baseUrl}}"],"path":["api","product-brands","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"headers\": [\n      \"name\"\n    ],\n    \"rows\": [\n      {\n        \"name\": \"New Brand A\",\n        \"status\": \"create\"\n      },\n      {\n        \"name\": \"Nike\",\n        \"status\": \"update\"\n      }\n    ],\n    \"total\": 2,\n    \"errors\": []\n  }\n}"}]},{"name":"Import Product Brands","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/product-brands/import","host":["{{baseUrl}}"],"path":["api","product-brands","import"]},"description":"Imports product brands from a CSV or Excel file. Each row must have a `name` column.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-brands/import","host":["{{baseUrl}}"],"path":["api","product-brands","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import completed: 10 created, 2 updated, 0 errors\"\n}"}]},{"name":"Get Brand Detail Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/brands/{brand}","host":["{{baseUrl}}"],"path":["api","v2","brands",":brand"],"variable":[{"key":"brand","value":"1","description":"Brand ID (archived brands are resolvable)"}]},"description":"Returns a single brand with lightweight aggregate stats for the Brand detail page header. Includes archived brands (a deep-link to an archived brand still resolves).\n\nResponse fields: id, name, archived_at, created_at, updated_at, products_count (count of products assigned to the brand).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/brands/{brand}","host":["{{baseUrl}}"],"path":["api","v2","brands",":brand"],"variable":[{"key":"brand","value":"1","description":"Brand ID (archived brands are resolvable)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Nike\",\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-20T14:30:00.000000Z\",\n    \"products_count\": 128\n  }\n}"}]},{"name":"Get Brand Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/brands/{brand}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","brands",":brand","activity-log"],"variable":[{"key":"brand","value":"1","description":"Brand ID (archived brands are resolvable)"}]},"description":"Paginated, filterable activity log for a brand. Surfaces two signals: the brand's own events (rename, archive, restore) and product brand-assignment changes (a product's brand being set to or cleared from this brand).\n\nEach entry: id, description, event, subject_type (ProductBrand or Product), subject_id, properties (attributes/old change diff), causer_name, created_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/brands/{brand}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","brands",":brand","activity-log"],"variable":[{"key":"brand","value":"1","description":"Brand ID (archived brands are resolvable)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"description\": null,\n      \"event\": \"updated\",\n      \"subject_type\": \"ProductBrand\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"name\": \"Nike\"\n        },\n        \"old\": {\n          \"name\": \"Nike Inc\"\n        }\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2024-03-20T14:30:00.000000Z\"\n    },\n    {\n      \"id\": 5008,\n      \"description\": null,\n      \"event\": \"created\",\n      \"subject_type\": \"Product\",\n      \"subject_id\": 44,\n      \"properties\": {\n        \"attributes\": {\n          \"brand_id\": 1,\n          \"sku\": \"AIRMAX-90\"\n        }\n      },\n      \"causer_name\": \"System\",\n      \"created_at\": \"2024-03-19T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Get Category","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"1","description":"Category ID"}]},"description":"Show a single product category with full detail including children, attribute groups, attributes, parent, and root info.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse includes:\n- `products_count` — total products assigned to this category and all sub-categories\n- `products_ids` — first 10 product IDs assigned\n- `subcategories_count` — count of all subcategories\n- `attribute_groups` / `attributes` — linked attribute groups and attributes"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"1","description":"Category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Electronics\",\n    \"parent_id\": null,\n    \"parent_name\": null,\n    \"category_tree\": null,\n    \"is_leaf\": false,\n    \"level\": 0,\n    \"products_count\": 128,\n    \"products_ids\": [\n      10,\n      11,\n      12,\n      13,\n      14,\n      15,\n      16,\n      17,\n      18,\n      19\n    ],\n    \"subcategories_count\": 4,\n    \"attribute_groups_count\": 2,\n    \"attribute_groups\": [\n      {\n        \"id\": 1,\n        \"name\": \"Technical Specs\"\n      }\n    ],\n    \"attributes_count\": 5,\n    \"attributes\": [\n      {\n        \"id\": 3,\n        \"name\": \"Color\",\n        \"type\": \"text\"\n      },\n      {\n        \"id\": 4,\n        \"name\": \"Weight\",\n        \"type\": \"number\"\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-20T08:30:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Category","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"5","description":"Category ID"}]},"description":"Update an existing product category. Attribute groups and attributes are synced (replaced entirely if provided).\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (optional) — category name; must be unique within the same parent\n- `parent_id` (optional) — parent category ID\n- `attribute_groups` (optional) — array of attribute group IDs to sync\n- `attributes` (optional) — array of attribute IDs to sync\n\n**Requires permission:** `categories.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Gaming Laptops\",\n  \"parent_id\": 1,\n  \"attribute_groups\": [\n    1\n  ],\n  \"attributes\": [\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"5","description":"Category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Gaming Laptops\",\n    \"parent_id\": 1,\n    \"parent_name\": null,\n    \"is_leaf\": true,\n    \"level\": 1,\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-02T09:15:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"category Gaming Laptops was updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Category","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"5","description":"Category ID"}]},"description":"Delete a product category. Only leaf categories (is_leaf = true) can be deleted.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if the category is not a leaf node (has children).\n\n**Requires permission:** `categories.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/categories/{category}","host":["{{baseUrl}}"],"path":["api","categories",":category"],"variable":[{"key":"category","value":"5","description":"Category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"category and its associations Gaming Laptops was deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"List Categories","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/categories?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","categories"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Records per page (default: 15)","disabled":true}]},"description":"List product categories. Supports search, sort, pagination, and archiving filters.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `page` / `limit` — pagination\n- `search` — full-text search on name\n- `sort` — sortable columns: id, name, created_at, updated_at, archived_at\n- `archived` — 0 (active), 1 (archived)\n- `filter[name]` — filter by name\n- `included[]` / `excluded[]` — force-include or exclude specific IDs"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/categories?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","categories"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Records per page (default: 15)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"parent_id\": null,\n      \"parent_name\": null,\n      \"is_leaf\": false,\n      \"level\": 0,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-20T08:30:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Smartphones\",\n      \"parent_id\": 1,\n      \"parent_name\": \"Electronics\",\n      \"is_leaf\": true,\n      \"level\": 1,\n      \"created_at\": \"2024-01-16T09:00:00.000000Z\",\n      \"updated_at\": \"2024-01-21T12:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 42,\n  \"status\": \"success\"\n}"}]},{"name":"Create Category","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories","host":["{{baseUrl}}"],"path":["api","categories"]},"description":"Create a new product category.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (required) — category name; must be unique within the same parent\n- `parent_id` (optional) — parent category ID; null creates a root category\n- `attribute_groups` (optional) — array of attribute group IDs to link\n- `attributes` (optional) — array of attribute IDs to link\n\n**Requires permission:** `categories.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Laptops\",\n  \"parent_id\": 1,\n  \"attribute_groups\": [\n    1,\n    2\n  ],\n  \"attributes\": [\n    3,\n    4,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/categories","host":["{{baseUrl}}"],"path":["api","categories"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Laptops\",\n    \"parent_id\": 1,\n    \"parent_name\": null,\n    \"is_leaf\": true,\n    \"level\": 1,\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"category was created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Categories","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/categories","host":["{{baseUrl}}"],"path":["api","categories"]},"description":"Bulk delete multiple product categories by their IDs. Only leaf categories can be deleted.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of category IDs to delete\n\n**Requires permission:** `categories.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/categories","host":["{{baseUrl}}"],"path":["api","categories"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 categories deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Category Tree","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/categories/tree","host":["{{baseUrl}}"],"path":["api","categories","tree"]},"description":"Returns all categories as a nested tree structure for hierarchical display.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEach node includes: id, name, parent_id, is_leaf, subcategories_count, children[]"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/categories/tree","host":["{{baseUrl}}"],"path":["api","categories","tree"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"parent_id\": null,\n      \"is_leaf\": false,\n      \"subcategories_count\": 2,\n      \"children\": [\n        {\n          \"id\": 2,\n          \"name\": \"Smartphones\",\n          \"parent_id\": 1,\n          \"is_leaf\": true,\n          \"subcategories_count\": 0,\n          \"children\": []\n        },\n        {\n          \"id\": 3,\n          \"name\": \"Laptops\",\n          \"parent_id\": 1,\n          \"is_leaf\": true,\n          \"subcategories_count\": 0,\n          \"children\": []\n        }\n      ]\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List Categories (Management View)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/categories/for-manage","host":["{{baseUrl}}"],"path":["api","categories","for-manage"]},"description":"Returns categories at a specific level for the product category assignment/manage UI. Includes counts for products, attributes, and attribute groups.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `parent_id` (optional) — limit to children of this parent; omit for root-level categories"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/categories/for-manage","host":["{{baseUrl}}"],"path":["api","categories","for-manage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"parent_id\": null,\n      \"children_count\": 3,\n      \"is_leaf\": false,\n      \"level\": 0,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-20T08:30:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Assign Category to Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/assign-category-to-product","host":["{{baseUrl}}"],"path":["api","categories","assign-category-to-product"]},"description":"Assign a category to a product and optionally set it as the primary category. Uses updateOrCreate so re-posting changes is_primary.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `category_id` (required) — must be a leaf category\n- `product_id` (required) — must exist in products table\n- `is_primary` (optional, boolean) — if true, unsets primary from all other categories for this product\n\nReturns 201 on creation, 200 on update.\n\n**Requires permission:** `categories.update`","body":{"mode":"raw","raw":"{\n  \"category_id\": 2,\n  \"product_id\": 100,\n  \"is_primary\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/categories/assign-category-to-product","host":["{{baseUrl}}"],"path":["api","categories","assign-category-to-product"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"category was assigned to product, and set as primary category\",\n  \"status\": \"success\"\n}"}]},{"name":"Reassign Category to Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/reassign-to-products","host":["{{baseUrl}}"],"path":["api","categories","reassign-to-products"]},"description":"Bulk reassign all products from one leaf category to another. Products already in the new category are detached from the old one.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `old_category_id` (required) — must be an existing leaf category\n- `new_category_id` (required) — must be an existing leaf category; different from old_category_id\n\n**Requires permission:** `categories.update`","body":{"mode":"raw","raw":"{\n  \"old_category_id\": 3,\n  \"new_category_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/reassign-to-products","host":["{{baseUrl}}"],"path":["api","categories","reassign-to-products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"affected_records_count\": 47\n  },\n  \"message\": \"Products have been reassigned to the new category.\",\n  \"status\": \"success\"\n}"}]},{"name":"Archive Category","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/categories/{productCategoryId}/archive","host":["{{baseUrl}}"],"path":["api","categories",":productCategoryId","archive"],"variable":[{"key":"productCategoryId","value":"5","description":"Category ID"}]},"description":"Archive a single product category.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `categories.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/{productCategoryId}/archive","host":["{{baseUrl}}"],"path":["api","categories",":productCategoryId","archive"],"variable":[{"key":"productCategoryId","value":"5","description":"Category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Laptops\",\n    \"archived_at\": \"2024-03-10T11:00:00.000000Z\"\n  },\n  \"message\": \"category Laptops was archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Category","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/categories/{productCategoryId}/unarchived","host":["{{baseUrl}}"],"path":["api","categories",":productCategoryId","unarchived"],"variable":[{"key":"productCategoryId","value":"5","description":"Category ID"}]},"description":"Unarchive a single product category.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `categories.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/{productCategoryId}/unarchived","host":["{{baseUrl}}"],"path":["api","categories",":productCategoryId","unarchived"],"variable":[{"key":"productCategoryId","value":"5","description":"Category ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Laptops\",\n    \"archived_at\": null\n  },\n  \"message\": \"category Laptops was unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Categories","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/archive","host":["{{baseUrl}}"],"path":["api","categories","archive"]},"description":"Bulk archive multiple product categories by their IDs.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of category IDs to archive\n\n**Requires permission:** `categories.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/archive","host":["{{baseUrl}}"],"path":["api","categories","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 categories archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive Categories","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/unarchive","host":["{{baseUrl}}"],"path":["api","categories","unarchive"]},"description":"Bulk unarchive multiple product categories by their IDs.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of category IDs to unarchive\n\n**Requires permission:** `categories.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/categories/unarchive","host":["{{baseUrl}}"],"path":["api","categories","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 categories unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Check Categories Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/categories/deletable","host":["{{baseUrl}}"],"path":["api","categories","deletable"]},"description":"Check which categories can be deleted. Categories with children (is_leaf = false) cannot be deleted.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of category IDs to check\n\n**Requires permission:** `categories.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/categories/deletable","host":["{{baseUrl}}"],"path":["api","categories","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"deletable\": false,\n      \"reason\": {\n        \"productCategory\": \"Category cannot be deleted as it has sub-categories.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Smartphones\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Laptops\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Preview Categories Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/categories/import/preview","host":["{{baseUrl}}"],"path":["api","categories","import","preview"]},"description":"Preview a category import file before committing. Returns parsed rows and any validation errors.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `categories.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/categories/import/preview","host":["{{baseUrl}}"],"path":["api","categories","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"name\": \"Tablets\",\n        \"parent_id\": 1,\n        \"valid\": true,\n        \"errors\": []\n      }\n    ],\n    \"total\": 1,\n    \"valid\": 1,\n    \"invalid\": 0\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Import Categories","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/categories/import","host":["{{baseUrl}}"],"path":["api","categories","import"]},"description":"Import categories from a CSV or Excel file.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `categories.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/categories/import","host":["{{baseUrl}}"],"path":["api","categories","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 5,\n    \"skipped\": 0,\n    \"errors\": []\n  },\n  \"message\": \"Import completed successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Attribute","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/{id}","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single attribute with its group and option values.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attributes/{id}","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Color\",\n    \"type\": \"string\",\n    \"attribute_group_id\": 1,\n    \"attribute_group\": {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\"\n    },\n    \"display_options\": {\n      \"placeholder\": \"Enter color\"\n    },\n    \"validation\": null,\n    \"available_for_templates\": true,\n    \"option_values\": [\n      {\n        \"value\": \"Red\",\n        \"sort_order\": 1\n      },\n      {\n        \"value\": \"Blue\",\n        \"sort_order\": 2\n      }\n    ],\n    \"notes\": \"Primary product color\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T14:30:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Attribute","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attributes/{id}","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing attribute. All fields are optional (PATCH semantics). Providing option_values syncs them — values not included will be deleted.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEach entry in `option_values` may carry an optional variant SWATCH — `swatch_hex` (a hex colour, max 20) and/or `swatch_image_url` (an image URL, max 500). When the attribute is used as a variant axis (e.g. Color), channels that support swatches (Walmart) render this chip for every variant that selects the value. Send null to clear a swatch.\n\nReturns **422** with code `IsLinked` if the update would remove an option value that is still assigned to a product — the response lists the in-use values under `errors[].data.in_use`. Add those values back, or reassign/clear them on the affected products, before removing the option.","body":{"mode":"raw","raw":"{\n  \"name\": \"Product Color\",\n  \"type\": \"string\",\n  \"option_values\": [\n    {\n      \"value\": \"Red\",\n      \"sort_order\": 1,\n      \"swatch_hex\": \"#FF0000\",\n      \"swatch_image_url\": null\n    },\n    {\n      \"value\": \"Blue\",\n      \"sort_order\": 2,\n      \"swatch_hex\": \"#0000FF\",\n      \"swatch_image_url\": null\n    },\n    {\n      \"value\": \"Green\",\n      \"sort_order\": 3,\n      \"swatch_hex\": \"#00A651\",\n      \"swatch_image_url\": \"https://cdn.example.com/swatches/green.jpg\"\n    }\n  ],\n  \"available_for_templates\": true,\n  \"notes\": \"Updated color attribute\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attributes/{id}","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"attribute 'Product Color' updated successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Product Color\",\n    \"type\": \"string\",\n    \"attribute_group_id\": 1,\n    \"display_options\": null,\n    \"option_values\": [\n      {\n        \"value\": \"Red\",\n        \"sort_order\": 1\n      },\n      {\n        \"value\": \"Blue\",\n        \"sort_order\": 2\n      },\n      {\n        \"value\": \"Green\",\n        \"sort_order\": 3\n      }\n    ],\n    \"notes\": \"Updated color attribute\",\n    \"updated_at\": \"2024-06-15T14:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Attribute","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/{id}?ignore_relations=0","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"query":[{"key":"ignore_relations","value":"0","description":"Set to 1 to force delete even if used by products","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes an attribute along with its values and product attribute assignments. Returns an error if the attribute is used by products unless ignore_relations=1.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- ignore_relations (optional): 0 (default) = block if used, 1 = force delete"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/attributes/{id}?ignore_relations=0","host":["{{baseUrl}}"],"path":["api","attributes",":id"],"query":[{"key":"ignore_relations","value":"0","description":"Set to 1 to force delete even if used by products","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"attribute 'Color' deleted successfully\"\n}"}]},{"name":"Get Attributes Grouped","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/grouped","host":["{{baseUrl}}"],"path":["api","attributes","grouped"]},"description":"Returns all attributes organized by their attribute group, plus a list of ungrouped attributes.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attributes/grouped","host":["{{baseUrl}}"],"path":["api","attributes","grouped"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"grouped\": [\n    {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\",\n      \"sort_order\": 1,\n      \"attributes\": [\n        {\n          \"id\": 1,\n          \"name\": \"Color\",\n          \"type\": \"string\",\n          \"sort_order\": 1,\n          \"attribute_id\": 1,\n          \"display_options\": null,\n          \"validation\": null\n        }\n      ]\n    }\n  ],\n  \"ungrouped\": [\n    {\n      \"id\": 10,\n      \"name\": \"Internal Notes\"\n    }\n  ]\n}"}]},{"name":"List Attributes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attributes?page=1&limit=15&sort=name&search=","host":["{{baseUrl}}"],"path":["api","attributes"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"name","description":"Sort field (prefix with - for descending)","disabled":true},{"key":"search","value":"","description":"Search by attribute name","disabled":true}]},"description":"Returns a paginated list of attributes.\n\nAuthentication: Requires Bearer token.\n\nSort fields: name, type, created_at, updated_at, archived_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attributes?page=1&limit=15&sort=name&search=","host":["{{baseUrl}}"],"path":["api","attributes"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"name","description":"Sort field (prefix with - for descending)","disabled":true},{"key":"search","value":"","description":"Search by attribute name","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Color\",\n      \"type\": \"string\",\n      \"attribute_group_id\": 1,\n      \"notes\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T14:30:00.000000Z\",\n      \"archived_at\": null,\n      \"display_options\": null,\n      \"validation\": null,\n      \"available_for_templates\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 38\n}"}]},{"name":"Create Attribute","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attributes","host":["{{baseUrl}}"],"path":["api","attributes"]},"description":"Creates a new attribute.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Unique name, max 255 chars\n- type (required): One of: string, longtext, date, datetime, numeric, integer, checkbox\n- display_options (optional): JSON object with display configuration\n- option_values (optional): Array of selectable options for dropdown-type attributes\n  - option_values.*.value (optional): Option value string, max 255 chars\n  - option_values.*.sort_order (optional): Sort order integer\n- validation (optional): JSON validation rules\n- available_for_templates (optional): Boolean — makes attribute available in email templates\n- attribute_group_id (optional): ID of the group to assign this attribute to\n- notes (optional): Internal notes, max 255 chars\n\n**Requires permission:** `attributes.create`\n\nEach entry in `option_values` may carry an optional variant SWATCH — `swatch_hex` (a hex colour, max 20) and/or `swatch_image_url` (an image URL, max 500). When the attribute is used as a variant axis (e.g. Color), channels that support swatches (Walmart) render this chip for every variant that selects the value. Send null to clear a swatch.","body":{"mode":"raw","raw":"{\n  \"name\": \"Color\",\n  \"type\": \"string\",\n  \"display_options\": {\n    \"has_options\": true,\n    \"type\": \"Multi\",\n    \"placeholder\": \"Enter color\"\n  },\n  \"option_values\": [\n    {\n      \"value\": \"Red\",\n      \"sort_order\": 1,\n      \"swatch_hex\": \"#FF0000\",\n      \"swatch_image_url\": \"https://cdn.example.com/swatches/red.jpg\"\n    },\n    {\n      \"value\": \"Blue\",\n      \"sort_order\": 2,\n      \"swatch_hex\": \"#0000FF\",\n      \"swatch_image_url\": null\n    }\n  ],\n  \"validation\": null,\n  \"available_for_templates\": true,\n  \"attribute_group_id\": 1,\n  \"notes\": \"Primary product color\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attributes","host":["{{baseUrl}}"],"path":["api","attributes"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"attribute created successfully\",\n  \"data\": {\n    \"id\": 15,\n    \"name\": \"Color\",\n    \"type\": \"string\",\n    \"attribute_group_id\": 1,\n    \"display_options\": {\n      \"placeholder\": \"Enter color\"\n    },\n    \"validation\": null,\n    \"available_for_templates\": true,\n    \"option_values\": [\n      {\n        \"value\": \"Red\",\n        \"sort_order\": 1\n      },\n      {\n        \"value\": \"Blue\",\n        \"sort_order\": 2\n      }\n    ],\n    \"notes\": \"Primary product color\",\n    \"created_at\": \"2024-06-15T12:00:00.000000Z\",\n    \"updated_at\": \"2024-06-15T12:00:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Delete Attributes","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/attributes","host":["{{baseUrl}}"],"path":["api","attributes"]},"description":"Bulk deletes multiple attributes by ID array or current list view filters.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attributes.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/attributes","host":["{{baseUrl}}"],"path":["api","attributes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attributes deleted successfully\"\n}"}]},{"name":"Archive Attribute","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/{id}/archive","host":["{{baseUrl}}"],"path":["api","attributes",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a single attribute. Idempotent — returns a warning if already archived.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attributes/{id}/archive","host":["{{baseUrl}}"],"path":["api","attributes",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"attribute 'Color' archived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Color\",\n    \"archived_at\": \"2024-06-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive Attribute","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","attributes",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a single attribute.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attributes/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","attributes",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"attribute 'Color' unarchived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Color\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Attributes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attributes/archive","host":["{{baseUrl}}"],"path":["api","attributes","archive"]},"description":"Bulk archives multiple attributes by ID array or current list view filters.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attributes.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attributes/archive","host":["{{baseUrl}}"],"path":["api","attributes","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attributes archived successfully\"\n}"}]},{"name":"Bulk Unarchive Attributes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attributes/unarchive","host":["{{baseUrl}}"],"path":["api","attributes","unarchive"]},"description":"Bulk unarchives multiple attributes by ID array or current list view filters.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attributes.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attributes/unarchive","host":["{{baseUrl}}"],"path":["api","attributes","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attributes unarchived successfully\"\n}"}]},{"name":"Check Attributes Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attributes/deletable","host":["{{baseUrl}}"],"path":["api","attributes","deletable"]},"description":"Checks whether each provided attribute ID can be safely deleted.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of attribute IDs to check (integers that exist in attributes table)\n\n**Requires permission:** `attributes.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attributes/deletable","host":["{{baseUrl}}"],"path":["api","attributes","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Color\",\n      \"deletable\": false,\n      \"reason\": \"Used by 5 products\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Size\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Import Attributes","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/import","host":["{{baseUrl}}"],"path":["api","attributes","import"]},"description":"Imports attributes from a CSV or Excel file.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `attributes.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attributes/import","host":["{{baseUrl}}"],"path":["api","attributes","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Import completed\",\n  \"data\": {\n    \"imported\": 10,\n    \"errors\": []\n  }\n}"}]},{"name":"Preview Attributes Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/attributes/import/preview","host":["{{baseUrl}}"],"path":["api","attributes","import","preview"]},"description":"Previews attribute import data from a file without actually importing.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `attributes.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attributes/import/preview","host":["{{baseUrl}}"],"path":["api","attributes","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"rows\": [\n      {\n        \"name\": \"Material\",\n        \"type\": \"string\",\n        \"valid\": true,\n        \"errors\": []\n      }\n    ],\n    \"total\": 1,\n    \"valid\": 1,\n    \"invalid\": 0\n  }\n}"}]},{"name":"List Attribute Groups (Management View)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/for-manage","host":["{{baseUrl}}"],"path":["api","attribute-groups","for-manage"]},"description":"Returns all attribute groups ordered by sort_order, including nested attributes, product counts, and category counts. Used for the attribute group management page.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attribute-groups/for-manage","host":["{{baseUrl}}"],"path":["api","attribute-groups","for-manage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\",\n      \"sort_order\": 1,\n      \"num_attributes\": 2,\n      \"num_categories\": 1,\n      \"num_products\": 15,\n      \"attributes\": [\n        {\n          \"id\": 1,\n          \"name\": \"Color\",\n          \"type\": \"string\",\n          \"sort_order\": 1,\n          \"attribute_id\": 1,\n          \"display_options\": null,\n          \"validation\": null\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Attribute Group","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single attribute group with full details including products, categories, and attributes.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Physical Attributes\",\n    \"sort_order\": 1,\n    \"products_count_directly\": 10,\n    \"products_ids_directly\": [\n      101,\n      102,\n      103\n    ],\n    \"products_count_through_categories\": 25,\n    \"products_ids_through_categories\": [\n      104,\n      105,\n      106\n    ],\n    \"attributes_count\": 2,\n    \"attributes\": [\n      {\n        \"id\": 1,\n        \"name\": \"Color\",\n        \"type\": \"string\",\n        \"sort_order\": 1,\n        \"attribute_id\": 1,\n        \"display_options\": null,\n        \"validation\": null\n      }\n    ],\n    \"categories_count\": 1,\n    \"categories\": [\n      {\n        \"id\": 5,\n        \"name\": \"Apparel\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Attribute Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing attribute group. All fields are optional (PATCH semantics on PUT). Providing the attributes array syncs assigned attributes — attributes not included will be removed from the group.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Physical Attributes\",\n  \"sort_order\": 2,\n  \"attributes\": [\n    {\n      \"id\": 1,\n      \"sort_order\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute group 'Updated Physical Attributes' updated successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Physical Attributes\",\n    \"sort_order\": 2,\n    \"attributes_count\": 1,\n    \"attributes\": [\n      {\n        \"id\": 1,\n        \"name\": \"Color\",\n        \"type\": \"string\",\n        \"sort_order\": 1,\n        \"attribute_id\": 1,\n        \"display_options\": null,\n        \"validation\": null\n      }\n    ]\n  }\n}"}]},{"name":"Delete Attribute Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a single attribute group. Returns an error if the group is linked to categories or products.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute group 'Physical Attributes' deleted successfully\"\n}"}]},{"name":"List Attribute Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups?page=1&limit=15&sort=name&search=","host":["{{baseUrl}}"],"path":["api","attribute-groups"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"name","description":"Sort field (prefix with - for descending, e.g. -name)","disabled":true},{"key":"search","value":"","description":"Search by attribute group name","disabled":true}]},"description":"Returns a paginated list of attribute groups. Supports search, sort, and archive filtering.\n\nAuthentication: Requires Bearer token.\n\nSort fields: name, sort_order, created_at, updated_at, archived_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/attribute-groups?page=1&limit=15&sort=name&search=","host":["{{baseUrl}}"],"path":["api","attribute-groups"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"name","description":"Sort field (prefix with - for descending, e.g. -name)","disabled":true},{"key":"search","value":"","description":"Search by attribute group name","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\",\n      \"sort_order\": 1,\n      \"num_attributes\": 5,\n      \"num_categories\": 3,\n      \"num_products\": 42,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T14:30:00.000000Z\",\n      \"archived_at\": null,\n      \"attributes\": [\n        {\n          \"id\": 1,\n          \"name\": \"Color\",\n          \"type\": \"string\",\n          \"sort_order\": 1,\n          \"attribute_id\": 1,\n          \"display_options\": null,\n          \"validation\": null\n        },\n        {\n          \"id\": 2,\n          \"name\": \"Weight\",\n          \"type\": \"numeric\",\n          \"sort_order\": 2,\n          \"attribute_id\": 2,\n          \"display_options\": null,\n          \"validation\": null\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Create Attribute Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attribute-groups","host":["{{baseUrl}}"],"path":["api","attribute-groups"]},"description":"Creates a new attribute group. Optionally assigns existing attributes to the group.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Unique name for the group, max 255 chars\n- sort_order (optional): Integer sort position\n- attributes (optional): Array of attribute objects to assign\n  - attributes.*.id (required): ID of an existing attribute\n  - attributes.*.sort_order (optional): Sort order within the group\n\nNote: An attribute can only belong to one group — assigning it to a new group removes it from the previous one.\n\n**Requires permission:** `attribute_groups.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Physical Attributes\",\n  \"sort_order\": 1,\n  \"attributes\": [\n    {\n      \"id\": 1,\n      \"sort_order\": 1\n    },\n    {\n      \"id\": 2,\n      \"sort_order\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attribute-groups","host":["{{baseUrl}}"],"path":["api","attribute-groups"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute group created successfully\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Physical Attributes\",\n    \"sort_order\": 1,\n    \"attributes_count\": 2,\n    \"attributes\": [\n      {\n        \"id\": 1,\n        \"name\": \"Color\",\n        \"type\": \"string\",\n        \"sort_order\": 1,\n        \"attribute_id\": 1,\n        \"display_options\": null,\n        \"validation\": null\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Delete Attribute Groups","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups","host":["{{baseUrl}}"],"path":["api","attribute-groups"]},"description":"Bulk deletes multiple attribute groups by ID array or by current list view filters.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attribute_groups.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/attribute-groups","host":["{{baseUrl}}"],"path":["api","attribute-groups"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute groups deleted successfully\"\n}"}]},{"name":"Archive Attribute Group","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}/archive","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a single attribute group by ID. Idempotent — returns a warning if already archived.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}/archive","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute group 'Physical Attributes' archived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Physical Attributes\",\n    \"archived_at\": \"2024-06-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive Attribute Group","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a single attribute group by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attribute-groups/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","attribute-groups",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute group 'Physical Attributes' unarchived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Physical Attributes\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Attribute Groups","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attribute-groups/archive","host":["{{baseUrl}}"],"path":["api","attribute-groups","archive"]},"description":"Bulk archives multiple attribute groups by ID array or by current list view filters.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attribute_groups.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attribute-groups/archive","host":["{{baseUrl}}"],"path":["api","attribute-groups","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute groups archived successfully\"\n}"}]},{"name":"Bulk Unarchive Attribute Groups","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attribute-groups/unarchive","host":["{{baseUrl}}"],"path":["api","attribute-groups","unarchive"]},"description":"Bulk unarchives multiple attribute groups by ID array or by current list view filters.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `attribute_groups.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/attribute-groups/unarchive","host":["{{baseUrl}}"],"path":["api","attribute-groups","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Attribute groups unarchived successfully\"\n}"}]},{"name":"Check Attribute Groups Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/attribute-groups/deletable","host":["{{baseUrl}}"],"path":["api","attribute-groups","deletable"]},"description":"Checks whether each provided attribute group ID can be safely deleted (not linked to categories or products).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required): Array of attribute group IDs to check\n\n**Requires permission:** `attribute_groups.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attribute-groups/deletable","host":["{{baseUrl}}"],"path":["api","attribute-groups","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Dimensions\",\n      \"deletable\": false,\n      \"reason\": \"Linked to categories\"\n    }\n  ]\n}"}]},{"name":"Import Attribute Groups","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/import","host":["{{baseUrl}}"],"path":["api","attribute-groups","import"]},"description":"Imports attribute groups from a CSV or Excel file.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `attribute_groups.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attribute-groups/import","host":["{{baseUrl}}"],"path":["api","attribute-groups","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Import completed successfully\",\n  \"data\": {\n    \"imported\": 5,\n    \"errors\": []\n  }\n}"}]},{"name":"Preview Attribute Groups Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/attribute-groups/import/preview","host":["{{baseUrl}}"],"path":["api","attribute-groups","import","preview"]},"description":"Previews attribute group import data from a file without actually importing. Returns rows with validation status.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n\n**Requires permission:** `attribute_groups.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/attribute-groups/import/preview","host":["{{baseUrl}}"],"path":["api","attribute-groups","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"rows\": [\n      {\n        \"name\": \"New Group\",\n        \"sort_order\": 1,\n        \"valid\": true,\n        \"errors\": []\n      }\n    ],\n    \"total\": 1,\n    \"valid\": 1,\n    \"invalid\": 0\n  }\n}"}]}]},{"name":"Pricing","item":[{"name":"Get Pricing Tier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"1","description":"Pricing tier ID"}]},"description":"Show a single product pricing tier.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"1","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Standard\",\n    \"pricing_type\": \"absolute\",\n    \"base_pricing_tier_id\": null,\n    \"base_pricing_tier_name\": null,\n    \"relative_basis\": null,\n    \"base_supplier_pricing_tier_id\": null,\n    \"base_supplier_pricing_tier_name\": null,\n    \"base_attribute_id\": null,\n    \"base_attribute_name\": null,\n    \"attr_rate\": null,\n    \"attr_offset\": null,\n    \"adjustment_percentage\": null,\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": null,\n    \"currency_code\": \"USD\",\n    \"is_default\": true,\n    \"dependent_tier_count\": 1,\n    \"chain_depth\": 0,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-10T09:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Pricing Tier","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"2","description":"Pricing tier ID"}]},"description":"Update an existing product pricing tier. currency_code cannot be changed on update.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional on update):\n- `name` (string, max:255, unique)\n- `pricing_type` — `absolute` or `relative`\n- `base_pricing_tier_id` (nullable integer) — required if pricing_type=relative\n- `adjustment_percentage` (nullable numeric, -99.9999 to 999.9999) — required if pricing_type=relative\n- `adjustment_fixed_amount` (nullable numeric)\n- `rounding_value` (nullable numeric, gt:0)\n\n**Relative tiers** (`pricing_type=relative`) require `relative_basis`, one of:\n- `pricing_tier` — derive from another tier's price. Requires `base_pricing_tier_id` + `adjustment_percentage`.\n- `supplier_pricing_tier` — cost-plus from the product's primary supplier cost. Optional `base_supplier_pricing_tier_id` (defaults to the default supplier tier) + `adjustment_percentage`.\n- `attribute` — derive from a numeric/integer product attribute: `value × attr_rate + attr_offset`. Requires `base_attribute_id` + `attr_rate` (optional `attr_offset`).\n\n`rounding_value` and `adjustment_fixed_amount` apply to every basis. Supplier/pricing-tier bases inherit currency from their source; attribute basis uses `currency_code`.\n\n**Requires permission:** `pricing_tiers.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Trade Wholesale\",\n  \"pricing_type\": \"relative\",\n  \"relative_basis\": \"pricing_tier\",\n  \"base_pricing_tier_id\": 1,\n  \"adjustment_percentage\": -20,\n  \"rounding_value\": 0.1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"2","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Trade Wholesale\",\n    \"pricing_type\": \"relative\",\n    \"base_pricing_tier_id\": 1,\n    \"base_pricing_tier_name\": \"Standard\",\n    \"relative_basis\": \"pricing_tier\",\n    \"base_supplier_pricing_tier_id\": null,\n    \"base_supplier_pricing_tier_name\": null,\n    \"base_attribute_id\": null,\n    \"base_attribute_name\": null,\n    \"attr_rate\": null,\n    \"attr_offset\": null,\n    \"adjustment_percentage\": \"-20.0000\",\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": \"0.1000\",\n    \"currency_code\": \"USD\",\n    \"is_default\": false,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 1,\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-05T14:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"product pricing tier Trade Wholesale was updated successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Pricing Tier","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"2","description":"Pricing tier ID"}]},"description":"Delete a product pricing tier. Fails if the tier is the default, is used by products, referenced in import mappings, or has active dependent tiers.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `pricing_tiers.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{product_pricing_tier}","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":product_pricing_tier"],"variable":[{"key":"product_pricing_tier","value":"2","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"product pricing tier Trade Wholesale was deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"List Pricing Tiers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Records per page (default: 15)","disabled":true}]},"description":"List product pricing tiers. Eager-loads the base pricing tier and counts dependent tiers.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `page` / `limit` — pagination\n- `search` — searches name and currency_code\n- `sort` — sortable columns: id, name, currency_code, is_default, pricing_type, created_at, updated_at, archived_at\n- `archived` — 0 (active only), 1 (archived only)\n- `filter[name]` / `filter[currency_code]` — column filters"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Records per page (default: 15)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard\",\n      \"pricing_type\": \"absolute\",\n      \"base_pricing_tier_id\": null,\n      \"base_pricing_tier_name\": null,\n      \"relative_basis\": null,\n      \"base_supplier_pricing_tier_id\": null,\n      \"base_supplier_pricing_tier_name\": null,\n      \"base_attribute_id\": null,\n      \"base_attribute_name\": null,\n      \"attr_rate\": null,\n      \"attr_offset\": null,\n      \"adjustment_percentage\": null,\n      \"adjustment_fixed_amount\": null,\n      \"rounding_value\": null,\n      \"currency_code\": \"USD\",\n      \"is_default\": true,\n      \"dependent_tier_count\": 1,\n      \"chain_depth\": 0,\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T09:00:00.000000Z\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale\",\n      \"pricing_type\": \"relative\",\n      \"base_pricing_tier_id\": 1,\n      \"base_pricing_tier_name\": \"Standard\",\n      \"relative_basis\": \"pricing_tier\",\n      \"base_supplier_pricing_tier_id\": null,\n      \"base_supplier_pricing_tier_name\": null,\n      \"base_attribute_id\": null,\n      \"base_attribute_name\": null,\n      \"attr_rate\": null,\n      \"attr_offset\": null,\n      \"adjustment_percentage\": \"-15.0000\",\n      \"adjustment_fixed_amount\": null,\n      \"rounding_value\": \"0.0500\",\n      \"currency_code\": \"USD\",\n      \"is_default\": false,\n      \"dependent_tier_count\": 0,\n      \"chain_depth\": 1,\n      \"created_at\": \"2024-01-05T09:00:00.000000Z\",\n      \"updated_at\": \"2024-02-01T11:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"status\": \"success\"\n}"}]},{"name":"Create Pricing Tier","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"]},"description":"Create a new product pricing tier. Supports both absolute and relative pricing.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `name` (required, string, max:255) — unique name for the tier\n- `currency_code` (required) — must exist in currencies table (e.g. USD, EUR). Relative tiers inherit currency from their base tier.\n- `pricing_type` (required) — `absolute` or `relative`. Defaults to `absolute` if omitted.\n- `base_pricing_tier_id` (required if pricing_type=relative, nullable) — the base tier to derive pricing from; must not create a circular reference\n- `adjustment_percentage` (required if pricing_type=relative, nullable, numeric -99.9999 to 999.9999) — percentage adjustment relative to the base tier\n- `adjustment_fixed_amount` (optional, nullable, numeric) — fixed amount adjustment\n- `rounding_value` (optional, nullable, numeric, gt:0) — round the final price to the nearest multiple of this value\n\nValidation rules:\n- A tier cannot reference itself as a base tier\n- Circular references are prevented\n- The default tier cannot be set to relative pricing type\n\n**Relative tiers** (`pricing_type=relative`) require `relative_basis`, one of:\n- `pricing_tier` — derive from another tier's price. Requires `base_pricing_tier_id` + `adjustment_percentage`.\n- `supplier_pricing_tier` — cost-plus from the product's primary supplier cost. Optional `base_supplier_pricing_tier_id` (defaults to the default supplier tier) + `adjustment_percentage`.\n- `attribute` — derive from a numeric/integer product attribute: `value × attr_rate + attr_offset`. Requires `base_attribute_id` + `attr_rate` (optional `attr_offset`).\n\n`rounding_value` and `adjustment_fixed_amount` apply to every basis. Supplier/pricing-tier bases inherit currency from their source; attribute basis uses `currency_code`.\n\n**Requires permission:** `pricing_tiers.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Wholesale\",\n  \"currency_code\": \"USD\",\n  \"pricing_type\": \"relative\",\n  \"relative_basis\": \"pricing_tier\",\n  \"base_pricing_tier_id\": 1,\n  \"adjustment_percentage\": -15,\n  \"adjustment_fixed_amount\": null,\n  \"rounding_value\": 0.05\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Wholesale\",\n    \"pricing_type\": \"relative\",\n    \"base_pricing_tier_id\": 1,\n    \"base_pricing_tier_name\": \"Standard\",\n    \"relative_basis\": \"pricing_tier\",\n    \"base_supplier_pricing_tier_id\": null,\n    \"base_supplier_pricing_tier_name\": null,\n    \"base_attribute_id\": null,\n    \"base_attribute_name\": null,\n    \"attr_rate\": null,\n    \"attr_offset\": null,\n    \"adjustment_percentage\": \"-15.0000\",\n    \"adjustment_fixed_amount\": null,\n    \"rounding_value\": \"0.0500\",\n    \"currency_code\": \"USD\",\n    \"is_default\": false,\n    \"dependent_tier_count\": 0,\n    \"chain_depth\": 1,\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"product pricing tier was created successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Pricing Tiers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"]},"description":"Bulk delete multiple pricing tiers by ID.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of pricing tier IDs to delete\n\n**Requires permission:** `pricing_tiers.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product pricing tiers deleted successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Set as Default Tier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/default","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","default"],"variable":[{"key":"productPricingTier","value":"1","description":"Pricing tier ID"}]},"description":"Set a pricing tier as the system default. Only absolute (non-relative) tiers that are not archived can be set as default. Unsetting the previous default is done automatically.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if the tier is archived or is a relative pricing type.\n\n**Requires permission:** `pricing_tiers.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/default","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","default"],"variable":[{"key":"productPricingTier","value":"1","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Standard\",\n    \"pricing_type\": \"absolute\",\n    \"is_default\": true,\n    \"currency_code\": \"USD\",\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-03-10T11:00:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"product pricing tier Standard was set as default successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Archive Pricing Tier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/archive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","archive"],"variable":[{"key":"productPricingTier","value":"2","description":"Pricing tier ID"}]},"description":"Archive a product pricing tier. Fails if the tier is the default tier or has active dependent tiers.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `pricing_tiers.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/archive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","archive"],"variable":[{"key":"productPricingTier","value":"2","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"product pricing tier Trade Wholesale was archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Pricing Tier","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/unarchived","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","unarchived"],"variable":[{"key":"productPricingTier","value":"2","description":"Pricing tier ID"}]},"description":"Unarchive a product pricing tier.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `pricing_tiers.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/{productPricingTier}/unarchived","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers",":productPricingTier","unarchived"],"variable":[{"key":"productPricingTier","value":"2","description":"Pricing tier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Trade Wholesale\",\n    \"pricing_type\": \"relative\",\n    \"is_default\": false,\n    \"currency_code\": \"USD\",\n    \"archived_at\": null\n  },\n  \"message\": \"product pricing tier Trade Wholesale was unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Pricing Tiers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/archive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","archive"]},"description":"Bulk archive multiple pricing tiers. Default tiers and tiers with active dependents are skipped with warnings.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of pricing tier IDs to archive\n\n**Requires permission:** `pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/archive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product pricing tiers archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive Pricing Tiers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/unarchive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","unarchive"]},"description":"Bulk unarchive multiple pricing tiers.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required) — array of pricing tier IDs to unarchive\n\n**Requires permission:** `pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/unarchive","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 product pricing tiers unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Check Pricing Tiers Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/deletable","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","deletable"]},"description":"Check which pricing tiers can be deleted. Deletion is blocked if: tier is default, is used by products, referenced in import mappings, or has active dependent (relative) tiers.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required, array) — pricing tier IDs to check; must exist in product_pricing_tiers table\n\n**Requires permission:** `pricing_tiers.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/deletable","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard\",\n      \"deletable\": false,\n      \"reason\": {\n        \"is_default\": \"Cannot delete the default pricing tier 'Standard'.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale\",\n      \"deletable\": false,\n      \"reason\": {\n        \"products\": \"5 products are currently using product pricing tier(Wholesale).\"\n      }\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Clearance\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Check Pricing Tiers Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/archivable","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","archivable"]},"description":"Check which pricing tiers can be archived. The default tier cannot be archived.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- `ids` (required, array) — pricing tier IDs to check; must exist in product_pricing_tiers table\n\n**Requires permission:** `pricing_tiers.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/archivable","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard\",\n      \"is_default\": true,\n      \"archivable\": false,\n      \"reason\": {\n        \"is_default\": \"Cannot archive the default pricing tier 'Standard'.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Wholesale\",\n      \"is_default\": false,\n      \"archivable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Clearance\",\n      \"is_default\": false,\n      \"archivable\": true,\n      \"reason\": null\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Preview Product Pricing Tier Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/import/preview","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","import","preview"]},"description":"Preview a pricing tier import file before committing. Returns parsed rows and validation errors.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `pricing_tiers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/import/preview","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"name\": \"VIP Tier\",\n        \"currency_code\": \"USD\",\n        \"pricing_type\": \"absolute\",\n        \"valid\": true,\n        \"errors\": []\n      }\n    ],\n    \"total\": 1,\n    \"valid\": 1,\n    \"invalid\": 0\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Import Pricing Tiers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/import","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","import"]},"description":"Import product pricing tiers from a CSV or Excel file.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nContent-Type: multipart/form-data\n- `file` (required) — CSV or Excel file\n\n**Requires permission:** `pricing_tiers.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/product-pricing-tiers/import","host":["{{baseUrl}}"],"path":["api","product-pricing-tiers","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 2,\n    \"skipped\": 0,\n    \"errors\": []\n  },\n  \"message\": \"Import completed successfully\",\n  \"status\": \"success\"\n}"}]}]},{"name":"CSV Templates","item":[{"name":"List CSV Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates?page=1&limit=15&search=&archived=0&sort=name","host":["{{baseUrl}}"],"path":["api","csv-templates"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"search","value":"","description":"Search string to filter templates by name","disabled":true},{"key":"archived","value":"0","description":"Include archived: 0 = active only (default), 1 = archived only","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, model, created_at, updated_at","disabled":true}]},"description":"Returns a paginated list of CSV import/export templates. Supports filtering by model type, pagination, and archive status.\n\nAuthentication: Requires Bearer token\n\nResponse fields:\n- id: Template ID\n- name: Template name (unique per model type)\n- template_type: The model type this template is for (e.g. 'product', 'sales_order')\n- columns: Array of column mappings\n- used_count: How many times this template has been used\n- last_import: Timestamp of last import using this template\n- last_export: Timestamp of last export using this template\n- archived_at: Archive timestamp (null if active)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/csv-templates?page=1&limit=15&search=&archived=0&sort=name","host":["{{baseUrl}}"],"path":["api","csv-templates"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"search","value":"","description":"Search string to filter templates by name","disabled":true},{"key":"archived","value":"0","description":"Include archived: 0 = active only (default), 1 = archived only","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, model, created_at, updated_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5,\n      \"name\": \"Standard Product Import\",\n      \"template_type\": \"product\",\n      \"columns\": [\n        {\n          \"column\": \"sku\",\n          \"header\": \"SKU\"\n        },\n        {\n          \"column\": \"name\",\n          \"header\": \"Product Name\"\n        }\n      ],\n      \"used_count\": 12,\n      \"last_import\": \"2024-01-10T09:00:00.000000Z\",\n      \"last_export\": null,\n      \"create_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T09:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 18\n}"}]},{"name":"Create CSV Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/csv-templates","host":["{{baseUrl}}"],"path":["api","csv-templates"]},"description":"Creates a new CSV template for import/export operations.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- name (string, required, max:255): Template name. Must be unique per model type.\n- model (string, required): The entity type this template applies to. Valid values: 'product', 'sales_order', 'product_brand', 'supplier'\n- columns (array, required, min:1): Array of column mapping objects defining which fields to include\n\n**Requires permission:** `csv_templates.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Product Import\",\n  \"model\": \"product\",\n  \"columns\": [\n    {\n      \"column\": \"sku\",\n      \"header\": \"SKU\"\n    },\n    {\n      \"column\": \"name\",\n      \"header\": \"Product Name\"\n    },\n    {\n      \"column\": \"barcode\",\n      \"header\": \"Barcode\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/csv-templates","host":["{{baseUrl}}"],"path":["api","csv-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"csv template created successfully.\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Standard Product Import\",\n    \"template_type\": \"product\",\n    \"columns\": [\n      {\n        \"column\": \"sku\",\n        \"header\": \"SKU\"\n      }\n    ],\n    \"used_count\": 0,\n    \"last_import\": null,\n    \"last_export\": null,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Get CSV Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]},"description":"Returns the details of a single CSV template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Standard Product Import\",\n    \"template_type\": \"product\",\n    \"columns\": [\n      {\n        \"column\": \"sku\",\n        \"header\": \"SKU\"\n      },\n      {\n        \"column\": \"name\",\n        \"header\": \"Product Name\"\n      }\n    ],\n    \"used_count\": 12,\n    \"last_import\": \"2024-01-10T09:00:00.000000Z\",\n    \"last_export\": null,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update CSV Template","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]},"description":"Updates an existing CSV template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- name (string, required, max:255): Template name. Must be unique per model type (ignoring the current template).\n- model (string, required): The entity type. Valid values: 'product', 'sales_order', 'product_brand', 'supplier'\n- columns (array, required, min:1): Updated array of column mappings\n\n**Requires permission:** `csv_templates.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Product Import v2\",\n  \"model\": \"product\",\n  \"columns\": [\n    {\n      \"column\": \"sku\",\n      \"header\": \"SKU\"\n    },\n    {\n      \"column\": \"name\",\n      \"header\": \"Product Name\"\n    },\n    {\n      \"column\": \"weight\",\n      \"header\": \"Weight\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"csv template Standard Product Import v2 updated successfully.\",\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Standard Product Import v2\",\n    \"template_type\": \"product\",\n    \"columns\": [\n      {\n        \"column\": \"sku\",\n        \"header\": \"SKU\"\n      },\n      {\n        \"column\": \"name\",\n        \"header\": \"Product Name\"\n      },\n      {\n        \"column\": \"weight\",\n        \"header\": \"Weight\"\n      }\n    ],\n    \"archived_at\": null\n  }\n}"}]},{"name":"Delete CSV Template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]},"description":"Deletes the specified CSV template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token\n\n**Requires permission:** `csv_templates.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/csv-templates/{csv_template}","host":["{{baseUrl}}"],"path":["api","csv-templates",":csv_template"],"variable":[{"key":"csv_template","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"csv template Standard Product Import deleted successfully.\"\n}"}]},{"name":"Archive CSV Template","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/archive","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","archive"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]},"description":"Archives the specified CSV template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\n**Requires permission:** `csv_templates.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/archive","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","archive"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"csv template Standard Product Import archived successfully.\",\n  \"data\": {\n    \"id\": 5,\n    \"archived_at\": \"2024-01-15T10:30:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive CSV Template","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/unarchived","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","unarchived"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]},"description":"Restores (unarchives) the specified CSV template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\n**Requires permission:** `csv_templates.archive`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/unarchived","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","unarchived"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"csv template Standard Product Import unarchived successfully.\",\n  \"data\": {\n    \"id\": 5,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Download Sample Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/download","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","download"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]},"description":"Returns the URL to the sample CSV file for this template. The sample file shows the expected column headers and example data.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nResponse: URL string (not a JSON object)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/download","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","download"],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"\"https://sku2.test/storage/csv-samples/standard-product-import.csv\""}]},{"name":"Export Data Using Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/export?archived=0&limit=1000","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","export"],"query":[{"key":"archived","value":"0","description":"Include archived records: 0 = active only (default), 1 = archived only","disabled":true},{"key":"limit","value":"1000","description":"Maximum number of records to export (optional)","disabled":true}],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]},"description":"Exports data using the specified CSV template. Returns a CSV file download with the columns defined in the template.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nResponse: text/csv file download\n\n**Requires permission:** `csv_templates.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/csv-templates/{csvTemplate}/export?archived=0&limit=1000","host":["{{baseUrl}}"],"path":["api","csv-templates",":csvTemplate","export"],"query":[{"key":"archived","value":"0","description":"Include archived records: 0 = active only (default), 1 = archived only","disabled":true},{"key":"limit","value":"1000","description":"Maximum number of records to export (optional)","disabled":true}],"variable":[{"key":"csvTemplate","value":"5","description":"CSV Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"SKU,Product Name,Barcode\nSKU-001,Widget A,123456789\nSKU-002,Widget B,987654321"}]},{"name":"Import Data Using Template","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/import","host":["{{baseUrl}}"],"path":["api","csv-templates","import"]},"description":"Imports data from a CSV file using the specified template. Supports preview mode to validate the file before committing.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nRequest body (multipart/form-data):\n- file (file, required unless tmp_file): The CSV file to import\n- tmp_file (string, required unless file): Path to a previously uploaded temporary file\n- template_id (integer, required unless model): ID of the template to use\n- model (string, required unless template_id): Model type for auto-detecting the template. Values: product, sales_order, product_brand, supplier\n- preview (boolean, optional): If true, returns a 10-row preview without importing (default: false)\n\n**Requires permission:** `csv_templates.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"template_id","type":"text","value":""},{"key":"model","type":"text","value":""},{"key":"preview","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/csv-templates/import","host":["{{baseUrl}}"],"path":["api","csv-templates","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 50,\n    \"errors\": [],\n    \"selected_template\": {\n      \"id\": 5,\n      \"name\": \"Standard Product Import\"\n    }\n  },\n  \"message\": \"Import completed successfully.\"\n}"}]},{"name":"Get Template Builder Columns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/csv-templates/{model}/prepare","host":["{{baseUrl}}"],"path":["api","csv-templates",":model","prepare"],"variable":[{"key":"model","value":"product","description":"Model type. Valid values: product, sales_order, product_brand, supplier"}]},"description":"Returns the available columns and related data for building or editing a CSV template for the specified model type.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nFor 'product' model, also returns:\n- relations.productAttributes: Available product attribute types\n- relations.productPricingTiers: Available pricing tiers\n- relations.suppliers: All suppliers\n- relations.SupplierPricingTiers: Supplier-specific pricing tiers"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/csv-templates/{model}/prepare","host":["{{baseUrl}}"],"path":["api","csv-templates",":model","prepare"],"variable":[{"key":"model","value":"product","description":"Model type. Valid values: product, sales_order, product_brand, supplier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"attributes\": [\n      \"id\",\n      \"sku\",\n      \"name\",\n      \"barcode\",\n      \"type\",\n      \"weight\",\n      \"weight_unit\",\n      \"brand\",\n      \"tags\",\n      \"image_url\",\n      \"category\",\n      \"length\",\n      \"width\",\n      \"height\",\n      \"created_at\"\n    ],\n    \"relations\": {\n      \"productAttributes\": [\n        {\n          \"id\": 1,\n          \"name\": \"Color\"\n        }\n      ],\n      \"productPricingTiers\": [\n        {\n          \"id\": 1,\n          \"name\": \"Retail\"\n        }\n      ],\n      \"suppliers\": [\n        {\n          \"id\": 1,\n          \"name\": \"ACME Corp\"\n        }\n      ],\n      \"SupplierPricingTiers\": [\n        {\n          \"id\": 1,\n          \"name\": \"Standard\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Bulk Archive CSV Templates","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/csv-templates/archive","host":["{{baseUrl}}"],"path":["api","csv-templates","archive"]},"description":"Archives multiple CSV templates.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nRequest body:\n- ids (array, required unless apply_to_all): Array of template IDs to archive\n- apply_to_all (boolean, optional): If true, archives all templates matching the provided filters\n- filters (array, optional): Filter criteria when apply_to_all is true\n\n**Requires permission:** `csv_templates.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/csv-templates/archive","host":["{{baseUrl}}"],"path":["api","csv-templates","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 csv templates archived successfully.\"\n}"}]},{"name":"Bulk Unarchive CSV Templates","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/csv-templates/unarchive","host":["{{baseUrl}}"],"path":["api","csv-templates","unarchive"]},"description":"Restores (unarchives) multiple CSV templates.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (Power User access required)\n\nRequest body:\n- ids (array, required unless apply_to_all): Array of template IDs to unarchive\n- apply_to_all (boolean, optional): If true, unarchives all templates matching the provided filters\n- filters (array, optional): Filter criteria when apply_to_all is true\n\n**Requires permission:** `csv_templates.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    5,\n    6,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/csv-templates/unarchive","host":["{{baseUrl}}"],"path":["api","csv-templates","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 csv templates unarchived successfully.\"\n}"}]}]},{"name":"Adjustments & Transfers","item":[{"name":"Get Inventory Adjustment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Retrieve a single inventory adjustment by ID. Loads fifoLayers and required list view relations.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"adjustment_date\": \"2024-03-15\",\n    \"product_id\": 42,\n    \"sku\": \"SKU-ABC-123\",\n    \"product_name\": \"Blue Widget 500ml\",\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 180,\n    \"near_expiry_threshold_days\": 60,\n    \"min_remaining_shelf_life_days\": 105,\n    \"product_average_cost\": 12.5,\n    \"quantity\": 50,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"notes\": \"Cycle count correction\",\n    \"reason\": null,\n    \"is_correction\": false,\n    \"type\": {\n      \"link_type\": null,\n      \"link_id\": null,\n      \"parent_link_type\": null,\n      \"parent_link_id\": null\n    },\n    \"reference\": null,\n    \"unit_cost\": 12.5,\n    \"lots\": [\n      {\n        \"fifo_layer_id\": 9012,\n        \"batch_number\": \"LOT-2026-0042\",\n        \"expiry_date\": \"2026-07-04\",\n        \"manufacture_date\": \"2026-01-04\",\n        \"lot_notes\": \"Received from PO-1234\",\n        \"quantity\": 50\n      }\n    ],\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-15T14:23:00Z\",\n    \"updated_at\": \"2024-03-15T14:23:00Z\"\n  }\n}"}]},{"name":"Update Inventory Adjustment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Update an existing inventory adjustment.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- adjustment_date (optional): Date of adjustment in Y-m-d format\n- warehouse_id (optional): ID of the target warehouse\n- quantity (required): Adjustment quantity (numeric, < 1,000,000, decimals supported e.g. 0.5)\n- adjustment_type (optional): One of: increase, decrease\n- unit_cost (optional): Cost per unit (>= 0)\n- notes (optional): Free-text notes\n- warehouse_location_id (optional): Specific location within the warehouse\n- condition (optional): Item condition\n- integration_unique_id (optional): External reference ID\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"adjustment_date\": \"2024-03-16\",\n  \"warehouse_id\": 1,\n  \"quantity\": 75,\n  \"adjustment_type\": \"increase\",\n  \"unit_cost\": 13,\n  \"notes\": \"Updated: corrected quantity\",\n  \"warehouse_location_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory has been adjusted\",\n  \"data\": {\n    \"id\": 101,\n    \"adjustment_date\": \"2024-03-16\",\n    \"product_id\": 42,\n    \"sku\": \"SKU-ABC-123\",\n    \"product_name\": \"Blue Widget 500ml\",\n    \"quantity\": 75,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"notes\": \"Updated: corrected quantity\",\n    \"unit_cost\": 13,\n    \"archived_at\": null,\n    \"updated_at\": \"2024-03-16T09:00:00Z\"\n  }\n}"}]},{"name":"Delete Inventory Adjustment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Delete an inventory adjustment. Reverses the inventory movement. Will fail if doing so would result in negative fulfilled quantities.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventory_adjustment}","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventory_adjustment"],"variable":[{"key":"inventory_adjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory adjustment 101 has been successfully deleted\"\n}"}]},{"name":"List Inventory Adjustments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments?archived=0&search=&sort=-adjustment_date&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search across product SKU, product name, notes","disabled":true},{"key":"sort","value":"-adjustment_date","description":"Sort field. Prefix with - for descending. Allowed: id, adjustment_date, quantity, unit_cost, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Number of records per page","disabled":true}]},"description":"List all inventory adjustments. Supports filtering, sorting, search and pagination.\n\nAuthentication: Requires Bearer token.\n\nSort fields: id, adjustment_date, quantity, unit_cost, created_at, updated_at.\n\ntable filters: archived (0/1), search, filter[warehouse_id], filter[product_id]."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-adjustments?archived=0&search=&sort=-adjustment_date&page=1&limit=25","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"],"query":[{"key":"archived","value":"0","description":"Filter by archived status: 0 (active) or 1 (archived). Default: 0","disabled":true},{"key":"search","value":"","description":"Search across product SKU, product name, notes","disabled":true},{"key":"sort","value":"-adjustment_date","description":"Sort field. Prefix with - for descending. Allowed: id, adjustment_date, quantity, unit_cost, created_at, updated_at","disabled":true},{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"25","description":"Number of records per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"adjustment_date\": \"2024-03-15\",\n      \"product_id\": 42,\n      \"sku\": \"SKU-ABC-123\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"product_average_cost\": 12.5,\n      \"quantity\": 50,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"notes\": \"Cycle count correction\",\n      \"reason\": null,\n      \"is_correction\": false,\n      \"type\": null,\n      \"reference\": null,\n      \"unit_cost\": 12.5,\n      \"archived_at\": null,\n      \"created_at\": \"2024-03-15T14:23:00Z\",\n      \"updated_at\": \"2024-03-15T14:23:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 25,\n  \"total\": 112,\n  \"from\": 1,\n  \"to\": 25\n}"}]},{"name":"Create Inventory Adjustment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"]},"description":"Create a new inventory adjustment. Supports increase, decrease, and set adjustment types.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- adjustment_date (required): Date of adjustment in Y-m-d format\n- product_id (required): ID of the product to adjust (not bundles/matrix products)\n- warehouse_id (required): ID of the target warehouse (must have a default location)\n- quantity (required): Adjustment quantity (numeric, < 1,000,000, decimals supported e.g. 0.5). Must be non-zero for increase/decrease\n- adjustment_type (required): One of: increase, decrease, set. Default: increase\n- unit_cost (optional/required for increase/set): Cost per unit (must be >= 0). Required if product has no average cost\n- notes (optional): Free-text notes\n- warehouse_location_id (optional): Specific location within the warehouse\n- condition (optional): Item condition description\n- integration_unique_id (optional): External reference ID\n\nErrors: 400 if insufficient stock (for decrease) or protected inventory conflict.\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"adjustment_date\": \"2024-03-15\",\n  \"product_id\": 42,\n  \"warehouse_id\": 1,\n  \"quantity\": 50,\n  \"adjustment_type\": \"increase\",\n  \"unit_cost\": 12.5,\n  \"notes\": \"Cycle count correction\",\n  \"warehouse_location_id\": null,\n  \"condition\": null,\n  \"integration_unique_id\": null,\n  \"lots\": [\n    {\n      \"batch_number\": \"LOT-2026-0042\",\n      \"manufacture_date\": \"2026-01-04\",\n      \"expiry_date\": \"2026-07-04\",\n      \"quantity\": 50,\n      \"lot_notes\": \"Received from PO-1234\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory has been adjusted\",\n  \"data\": {\n    \"id\": 102,\n    \"adjustment_date\": \"2024-03-15\",\n    \"product_id\": 42,\n    \"sku\": \"SKU-ABC-123\",\n    \"product_name\": \"Blue Widget 500ml\",\n    \"is_lot_tracked\": true,\n    \"lot_tracking_method\": \"fifo\",\n    \"shelf_life_days\": 180,\n    \"near_expiry_threshold_days\": 60,\n    \"min_remaining_shelf_life_days\": 105,\n    \"product_average_cost\": 12.5,\n    \"quantity\": 50,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"notes\": \"Cycle count correction\",\n    \"reason\": null,\n    \"is_correction\": false,\n    \"unit_cost\": 12.5,\n    \"lots\": [\n      {\n        \"fifo_layer_id\": 9012,\n        \"batch_number\": \"LOT-2026-0042\",\n        \"expiry_date\": \"2026-07-04\",\n        \"manufacture_date\": \"2026-01-04\",\n        \"lot_notes\": \"Received from PO-1234\",\n        \"quantity\": 50\n      }\n    ],\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-15T14:30:00Z\",\n    \"updated_at\": \"2024-03-15T14:30:00Z\"\n  }\n}"}]},{"name":"Bulk Delete Inventory Adjustments","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"]},"description":"Bulk delete multiple inventory adjustments by ID, or delete all matching current filters.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody: { ids: [integer array] } — specific IDs to delete. Omit ids to delete all matching current filters.\n\n**Requires permission:** `inventory.adjust`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","inventory-adjustments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 inventory adjustments deleted successfully\"\n}"}]},{"name":"Bulk Archive Inventory Adjustments","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/archive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","archive"]},"description":"Bulk archive multiple inventory adjustments.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/archive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 inventory adjustments archived successfully\"\n}"}]},{"name":"Bulk Unarchive Inventory Adjustments","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/unarchive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","unarchive"]},"description":"Bulk unarchive multiple inventory adjustments.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/unarchive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 inventory adjustments unarchived successfully\"\n}"}]},{"name":"Archive Inventory Adjustment","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{adjustment}/archive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":adjustment","archive"],"variable":[{"key":"adjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Archive a single inventory adjustment.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{adjustment}/archive","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":adjustment","archive"],"variable":[{"key":"adjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory adjustment 101 has been archived\",\n  \"data\": {\n    \"id\": 101,\n    \"archived_at\": \"2024-03-16T10:00:00Z\"\n  }\n}"}]},{"name":"Unarchive Inventory Adjustment","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{adjustment}/unarchived","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":adjustment","unarchived"],"variable":[{"key":"adjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Unarchive a single inventory adjustment.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.adjust`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{adjustment}/unarchived","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":adjustment","unarchived"],"variable":[{"key":"adjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory adjustment 101 has been unarchived\",\n  \"data\": {\n    \"id\": 101,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Check Inventory Adjustments Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/deletable","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","deletable"]},"description":"Check which inventory adjustments can be deleted. Returns a deletability status for each requested ID.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of integer IDs to check\n\n**Requires permission:** `inventory.adjust`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/deletable","host":["{{baseUrl}}"],"path":["api","inventory-adjustments","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 102,\n      \"deletable\": false,\n      \"reason\": {\n        \"fulfilledQuantity\": \"The fulfilled quantity would not be covered\"\n      }\n    },\n    {\n      \"id\": 103,\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Get Adjustment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventoryAdjustment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventoryAdjustment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Number of activity log entries per page. Default: 15","disabled":true}],"variable":[{"key":"inventoryAdjustment","value":"101","description":"Inventory adjustment ID"}]},"description":"Get paginated activity log for a specific inventory adjustment. Includes who made the change and what changed.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- per_page: Number of entries per page (default: 15)\n- filter[search]: Search by causer name, event, or properties\n- page: Page number for pagination"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-adjustments/{inventoryAdjustment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","inventory-adjustments",":inventoryAdjustment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Number of activity log entries per page. Default: 15","disabled":true}],"variable":[{"key":"inventoryAdjustment","value":"101","description":"Inventory adjustment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"InventoryAdjustment\",\n      \"subject_id\": 101,\n      \"properties\": {\n        \"old\": {\n          \"quantity\": 50\n        },\n        \"attributes\": {\n          \"quantity\": 75\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2024-03-16T09:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"List Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations?page=1&per_page=10&filter[search]=&filter[warehouse_id]=&filter[supplier_id]=&filter[product_id]=&filter[status]=active&filter[id]=&filter[quantity]=&filter[priority]=&filter[created_at]=&filter[fulfilled_at]=&filter[cancelled_at]=&filter[product_sku]=&filter[product_name]=&filter_groups[conjunction]=and&sort=-created_at","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search across id, sku, product name, and source reference","disabled":true},{"key":"filter[warehouse_id]","value":"","description":"Exact match on warehouse ID","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Exact match on supplier ID","disabled":true},{"key":"filter[product_id]","value":"","description":"Exact match on product ID","disabled":true},{"key":"filter[status]","value":"active","description":"Sentinel: all | active (default) | pending | released | cancelled | fulfilled","disabled":true},{"key":"filter[id]","value":"","description":"Numeric filter on id","disabled":true},{"key":"filter[quantity]","value":"","description":"Numeric filter on quantity","disabled":true},{"key":"filter[priority]","value":"","description":"Numeric filter on priority","disabled":true},{"key":"filter[created_at]","value":"","description":"Datetime filter on created_at","disabled":true},{"key":"filter[fulfilled_at]","value":"","description":"Datetime filter on fulfilled_at","disabled":true},{"key":"filter[cancelled_at]","value":"","description":"Datetime filter on cancelled_at","disabled":true},{"key":"filter[product_sku]","value":"","description":"Text filter on product SKU","disabled":true},{"key":"filter[product_name]","value":"","description":"Text filter on product name","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"Advanced filter tree conjunction: and | or. Use with filter_groups[children][] for grouped conditions.","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Options: id, quantity, priority, status, created_at","disabled":true}]},"description":"Returns a paginated list of inventory allocations.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Simple filters** (`filter[status]`): Sentinel values control the list scope:\n- `active` (default) — pending + released allocations\n- `all` — every status\n- `pending`, `released`, `cancelled`, `fulfilled` — specific status\n\n**Advanced filters** (`filter_groups`): Tree-based GroupedFilterSupport filters on id, quantity, priority, status, warehouse_id, supplier_id, created_at, fulfilled_at, cancelled_at, product_sku, product_name. The `filter[search]` parameter is a cross-column search.\n\n**Sort options**: id, quantity, priority, status, created_at. Default: `-created_at`.\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations?page=1&per_page=10&filter[search]=&filter[warehouse_id]=&filter[supplier_id]=&filter[product_id]=&filter[status]=active&filter[id]=&filter[quantity]=&filter[priority]=&filter[created_at]=&filter[fulfilled_at]=&filter[cancelled_at]=&filter[product_sku]=&filter[product_name]=&filter_groups[conjunction]=and&sort=-created_at","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search across id, sku, product name, and source reference","disabled":true},{"key":"filter[warehouse_id]","value":"","description":"Exact match on warehouse ID","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Exact match on supplier ID","disabled":true},{"key":"filter[product_id]","value":"","description":"Exact match on product ID","disabled":true},{"key":"filter[status]","value":"active","description":"Sentinel: all | active (default) | pending | released | cancelled | fulfilled","disabled":true},{"key":"filter[id]","value":"","description":"Numeric filter on id","disabled":true},{"key":"filter[quantity]","value":"","description":"Numeric filter on quantity","disabled":true},{"key":"filter[priority]","value":"","description":"Numeric filter on priority","disabled":true},{"key":"filter[created_at]","value":"","description":"Datetime filter on created_at","disabled":true},{"key":"filter[fulfilled_at]","value":"","description":"Datetime filter on fulfilled_at","disabled":true},{"key":"filter[cancelled_at]","value":"","description":"Datetime filter on cancelled_at","disabled":true},{"key":"filter[product_sku]","value":"","description":"Text filter on product SKU","disabled":true},{"key":"filter[product_name]","value":"","description":"Text filter on product name","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"Advanced filter tree conjunction: and | or. Use with filter_groups[children][] for grouped conditions.","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix with - for descending. Options: id, quantity, priority, status, created_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10045,\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast DC\"\n      },\n      \"link_id\": 55347,\n      \"link_type\": \"App\\\\Models\\\\SalesOrderLine\",\n      \"link_type_label\": \"Sales Order Line\",\n      \"link_route\": \"/sales-orders/9821\",\n      \"link_reference\": \"SO-9821\",\n      \"date\": \"2025-04-10\",\n      \"quantity\": 5,\n      \"status\": \"pending\",\n      \"status_label\": \"Pending\",\n      \"priority\": 1,\n      \"supplier_id\": 14,\n      \"supplier\": {\n        \"id\": 14,\n        \"name\": \"Acme Corp\"\n      },\n      \"purchase_order_line_id\": null,\n      \"is_tight_coverage\": false,\n      \"release_source_id\": null,\n      \"release_source_type\": null,\n      \"fulfilled_at\": null,\n      \"cancelled_at\": null,\n      \"created_at\": \"2025-04-10T08:22:11.000000Z\",\n      \"updated_at\": \"2025-04-10T08:22:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 118,\n  \"unfiltered_total\": 947,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Allocation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]},"description":"Returns a single inventory allocation by ID.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nwarehouse_location_id and the nested warehouse_location object reflect the bin this allocation is pinned to (null when not pinned). warehouse.locations_enabled indicates whether the warehouse uses bin locations."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 10045,\n  \"product_id\": 812,\n  \"product\": {\n    \"id\": 812,\n    \"sku\": \"WIDGET-BLU\",\n    \"name\": \"Blue Widget\"\n  },\n  \"warehouse_id\": 3,\n  \"warehouse\": {\n    \"id\": 3,\n    \"name\": \"East Coast DC\",\n    \"locations_enabled\": true\n  },\n  \"warehouse_location_id\": 402,\n  \"warehouse_location\": {\n    \"id\": 402,\n    \"code\": \"ST-09\",\n    \"name\": \"Reserve Aisle 9\"\n  },\n  \"link_id\": 55347,\n  \"link_type\": \"App\\\\Models\\\\SalesOrderLine\",\n  \"link_type_label\": \"Sales Order Line\",\n  \"link_route\": \"/sales-orders/9821\",\n  \"link_reference\": \"SO-9821\",\n  \"date\": \"2025-04-10\",\n  \"quantity\": 5,\n  \"status\": \"pending\",\n  \"status_label\": \"Pending\",\n  \"priority\": 1,\n  \"supplier_id\": 14,\n  \"supplier\": {\n    \"id\": 14,\n    \"name\": \"Acme Corp\"\n  },\n  \"purchase_order_line_id\": null,\n  \"is_tight_coverage\": false,\n  \"release_source_id\": null,\n  \"release_source_type\": null,\n  \"fulfilled_at\": null,\n  \"cancelled_at\": null,\n  \"created_at\": \"2025-04-10T08:22:11.000000Z\",\n  \"updated_at\": \"2025-04-10T08:22:11.000000Z\"\n}"}]},{"name":"Reorder Allocation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/reorder","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","reorder"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]},"description":"Reorders an allocation relative to another.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `reorder_type` — `above` | `below` | `top` | `bottom`\n- `options.above_id` — ID of the allocation to place this one above (used when reorder_type is `above`)","body":{"mode":"raw","raw":"{\n  \"reorder_type\": \"above\",\n  \"options\": {\n    \"above_id\": 10040\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/reorder","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","reorder"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Allocation reordered successfully.\"\n}"}]},{"name":"Reassign Coverage","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/reassign-coverage","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","reassign-coverage"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]},"description":"Manually (re)assigns a single allocation's PO-line coverage. Binding a PO line transitions the allocation to `AwaitingReceipt` and pins it as tight coverage (so a later automatic rebalance won't move it).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `purchase_order_line_id` (required, nullable integer) — the PO line to cover this allocation with. Pass `null` to clear coverage and revert the allocation to `Planned`.\n\nReturns `422` when the PO line belongs to a different product, or the PO is draft/closed/cancelled/voided, or the line is already fully received.","body":{"mode":"raw","raw":"{\n  \"purchase_order_line_id\": 5567\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/reassign-coverage","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","reassign-coverage"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10045,\n    \"priority\": 3,\n    \"backorder_date\": \"2026-05-10T14:22:00.000000Z\",\n    \"backordered_quantity\": 8,\n    \"quantity\": 8,\n    \"status\": \"awaiting_receipt\",\n    \"status_label\": \"Awaiting Receipt\",\n    \"is_tight_coverage\": true,\n    \"sales_order\": {\n      \"id\": 33021,\n      \"number\": \"SO-033021\",\n      \"order_date\": \"2026-05-08\"\n    },\n    \"sku\": {\n      \"id\": 812,\n      \"sku\": \"WIDGET-BLU\",\n      \"name\": \"Blue Widget\"\n    },\n    \"supplier\": {\n      \"id\": 47,\n      \"name\": \"Acme Supplies\"\n    },\n    \"coverage\": {\n      \"purchase_order_line_id\": 5567,\n      \"purchase_order_id\": 902,\n      \"purchase_order_number\": \"PO-000902\",\n      \"covered_quantity\": 8,\n      \"is_tight\": true\n    },\n    \"scheduled_at\": \"2026-05-20\",\n    \"created_at\": \"2026-05-10T14:22:00.000000Z\"\n  }\n}"}]},{"name":"Get Move Targets","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/move-targets","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","move-targets"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID (must be an on-hand `allocated` allocation linked to a sales order line)"}]},"description":"Lists the candidate destination sales order lines that on-hand (`allocated`) stock from this allocation can be moved to.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the backordered lines (status `planned` / `awaiting_receipt`) waiting on the **same product and warehouse pool** as the source allocation, excluding the source's own line. Each entry includes how much of that line is still backordered, so the caller can cap the move quantity.\n\nReturns an empty list when the allocation is not `allocated`, is not linked to a sales order line, or there are no other backordered lines in the pool."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/move-targets","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","move-targets"],"variable":[{"key":"allocation","value":"10045","description":"Allocation ID (must be an on-hand `allocated` allocation linked to a sales order line)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_order_line_id\": 55512,\n      \"sales_order_id\": 33099,\n      \"sales_order_number\": \"SO-033099\",\n      \"customer_id\": 33099,\n      \"customer_name\": \"Acme Retail\",\n      \"order_date\": \"2026-05-12\",\n      \"backordered_quantity\": 4\n    },\n    {\n      \"sales_order_line_id\": 55540,\n      \"sales_order_id\": 33104,\n      \"sales_order_number\": \"SO-033104\",\n      \"customer_id\": 33104,\n      \"customer_name\": \"Blue Mountain Co\",\n      \"order_date\": \"2026-05-13\",\n      \"backordered_quantity\": 2\n    }\n  ]\n}"}]},{"name":"Move To Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/move","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","move"],"variable":[{"key":"allocation","value":"10045","description":"Source allocation ID (must be an on-hand `allocated` allocation linked to a sales order line)"}]},"description":"Moves on-hand (`allocated`) stock from this allocation to a backordered line in the same product + warehouse pool — a **conserved swap**.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe moved quantity releases the destination line's backorder (`planned` / `awaiting_receipt` → `allocated`), carrying the source allocation's FIFO `release_source` reference. The source's `allocated` row is reduced by the same quantity (or cancelled if fully consumed), and the source's demand is recreated as a `planned` backorder. Total on-hand commitment, total demand, and FIFO cost layering are all preserved.\n\n**Body**:\n- `destination_sales_order_line_id` (required, integer) — the backordered sales order line to move stock to. Must exist and be in the same product + warehouse pool. Get valid targets from `GET /move-targets`.\n- `quantity` (required, numeric, > 0) — how much on-hand stock to move. Must not exceed the source's movable on-hand quantity (allocated minus any stock committed to open fulfillments) nor the destination line's backordered quantity.\n\nReturns `422` when the source is not `allocated`, the destination is a different product/warehouse or the same line, the quantity exceeds the movable on-hand stock (e.g. committed to an open fulfillment) or the destination's backorder, or the destination has no matching backorder to release.","body":{"mode":"raw","raw":"{\n  \"destination_sales_order_line_id\": 55512,\n  \"quantity\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{allocation}/move","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":allocation","move"],"variable":[{"key":"allocation","value":"10045","description":"Source allocation ID (must be an on-hand `allocated` allocation linked to a sales order line)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10072,\n    \"priority\": 2,\n    \"backorder_date\": null,\n    \"backordered_quantity\": 0,\n    \"quantity\": 4,\n    \"status\": \"allocated\",\n    \"status_label\": \"Allocated\",\n    \"is_tight_coverage\": false,\n    \"sales_order\": {\n      \"id\": 33099,\n      \"number\": \"SO-033099\",\n      \"order_date\": \"2026-05-12\"\n    },\n    \"sku\": {\n      \"id\": 812,\n      \"sku\": \"WIDGET-BLU\",\n      \"name\": \"Blue Widget\"\n    },\n    \"supplier\": {\n      \"id\": 47,\n      \"name\": \"Acme Supplies\"\n    },\n    \"coverage\": null,\n    \"scheduled_at\": null,\n    \"created_at\": \"2026-06-15T09:14:00.000000Z\"\n  }\n}"}]},{"name":"List Pull-Stock Donors","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/pull-stock-donors?destination_sales_order_line_id=55600","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","pull-stock-donors"],"query":[{"key":"destination_sales_order_line_id","value":"55600","description":"Required. The backordered sales order line that would receive the pulled stock.","disabled":true}]},"description":"Lists the sales order lines a backordered line can pull on-hand stock from. Returns other sales orders holding **soft** allocations (`allocated`, not yet committed to a printed shipping label) of the same product in the same warehouse pool, excluding the backordered line's own sales order.\n\nEach donor entry reports `movable_quantity` (soft on-hand that can be pulled) and `priority` (lower number = higher priority), ordered least-urgent first so the safest donors appear at the top.\n\nQuery:\n- `destination_sales_order_line_id` (required, integer) — the backordered sales order line that would receive the stock.\n\nReturns an empty list when no other order in the pool holds soft-allocated stock."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/pull-stock-donors?destination_sales_order_line_id=55600","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","pull-stock-donors"],"query":[{"key":"destination_sales_order_line_id","value":"55600","description":"Required. The backordered sales order line that would receive the pulled stock.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_order_line_id\": 55540,\n      \"sales_order_id\": 33104,\n      \"sales_order_number\": \"SO-033104\",\n      \"customer_id\": 44011,\n      \"customer_name\": \"Blue Mountain Co\",\n      \"order_date\": \"2026-05-13\",\n      \"priority\": 8,\n      \"movable_quantity\": 5\n    },\n    {\n      \"sales_order_line_id\": 55512,\n      \"sales_order_id\": 33099,\n      \"sales_order_number\": \"SO-033099\",\n      \"customer_id\": 44011,\n      \"customer_name\": \"Acme Retail\",\n      \"order_date\": \"2026-05-12\",\n      \"priority\": 3,\n      \"movable_quantity\": 2\n    }\n  ]\n}"}]},{"name":"Pull Stock To Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/pull-stock","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","pull-stock"]},"description":"Pulls soft on-hand stock from one or more donor sales order lines onto a backordered line, atomically. Each donor's soft allocation is backordered by the pulled quantity and the freed on-hand is allocated to the destination line — a **conserved swap** that preserves total demand and FIFO cost layering across every affected order. All pulls succeed or roll back together.\n\n**Body**:\n- `destination_sales_order_line_id` (required, integer) — the backordered line that receives the stock.\n- `pulls` (required, array, min 1) — the donors to pull from.\n- `pulls[].sales_order_line_id` (required, integer) — a donor sales order line holding soft allocations of the same product + warehouse. Get valid donors from `GET /pull-stock-donors`.\n- `pulls[].quantity` (required, numeric, > 0) — how much soft on-hand to pull from that donor.\n\nReturns `422` when a donor no longer holds enough soft-allocated stock, a donor is the same line as the destination, or the destination has no matching backorder to receive the pull.\n\nOn success returns the total `pulled_quantity` and the refreshed donor list.","body":{"mode":"raw","raw":"{\n  \"destination_sales_order_line_id\": 55600,\n  \"pulls\": [\n    {\n      \"sales_order_line_id\": 55540,\n      \"quantity\": 2\n    },\n    {\n      \"sales_order_line_id\": 55512,\n      \"quantity\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/pull-stock","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","pull-stock"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pulled_quantity\": 3,\n    \"donors\": [\n      {\n        \"sales_order_line_id\": 55540,\n        \"sales_order_id\": 33104,\n        \"sales_order_number\": \"SO-033104\",\n        \"customer_id\": 44011,\n        \"customer_name\": \"Blue Mountain Co\",\n        \"order_date\": \"2026-05-13\",\n        \"priority\": 8,\n        \"movable_quantity\": 3\n      }\n    ]\n  }\n}"}]},{"name":"Reserve Allocation to Bin","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{inventoryAllocation}/pin-bin","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":inventoryAllocation","pin-bin"],"variable":[{"key":"inventoryAllocation","value":"","description":"The inventory allocation ID."}]},"description":"Hard-reserve an allocation's stock to a specific bin so it's held there for its order and picked from there.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_location_id\": 16\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{inventoryAllocation}/pin-bin","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":inventoryAllocation","pin-bin"],"variable":[{"key":"inventoryAllocation","value":"","description":"The inventory allocation ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 221,\n    \"warehouse_location_id\": 16\n  },\n  \"message\": \"Stock reserved to the bin.\"\n}"}]},{"name":"Clear Bin Reservation","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{inventoryAllocation}/pin-bin","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":inventoryAllocation","pin-bin"],"variable":[{"key":"inventoryAllocation","value":"","description":"The inventory allocation ID."}]},"description":"Clear an allocation's hard bin reservation.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/{inventoryAllocation}/pin-bin","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations",":inventoryAllocation","pin-bin"],"variable":[{"key":"inventoryAllocation","value":"","description":"The inventory allocation ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 221,\n    \"warehouse_location_id\": null\n  },\n  \"message\": \"Bin reservation cleared.\"\n}"}]},{"name":"List Backorders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders?page=1&per_page=10&filter[search]=&filter[status]=&filter[supplier_id]=&filter[covered_by_po]=&filter[eta_state]=&filter[sku]=&filter[product_name]=&filter[supplier_name]=&filter[quantity]=&filter[priority]=&filter[created_at]=&sort=priority","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search across id, sku, product name, supplier name, sales order number, PO number","disabled":true},{"key":"filter[status]","value":"","description":"Backorder status: pending | released | partial | cancelled","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID","disabled":true},{"key":"filter[covered_by_po]","value":"","description":"true | false — filter by whether the backorder is covered by a PO","disabled":true},{"key":"filter[eta_state]","value":"","description":"on_time | late | unknown","disabled":true},{"key":"filter[sku]","value":"","description":"Text filter on product SKU","disabled":true},{"key":"filter[product_name]","value":"","description":"Text filter on product name","disabled":true},{"key":"filter[supplier_name]","value":"","description":"Text filter on supplier name","disabled":true},{"key":"filter[quantity]","value":"","description":"Numeric filter on backorder quantity","disabled":true},{"key":"filter[priority]","value":"","description":"Numeric filter on priority","disabled":true},{"key":"filter[created_at]","value":"","description":"Datetime filter on created_at","disabled":true},{"key":"sort","value":"priority","description":"Sort field. Options: id, priority, quantity, created_at, updated_at, backorder_date, backordered_quantity, released_quantity, sku, product_name, supplier, order_date, sales_order_number, eta. Default: priority","disabled":true}]},"description":"Returns a paginated backorder queue showing allocations that are awaiting stock.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Supports GET and POST** — POST can be used to send large filter payloads in the request body.\n\n**Sort options**: id, priority, quantity, created_at, updated_at, backorder_date, backordered_quantity, released_quantity, sku, product_name, supplier, order_date, sales_order_number, eta. Default: `priority`.\n\nEach backorder row also carries `in_transit_stock` (inbound stock in motion across warehouses), alongside `other_warehouse_stock`. Both are populated in the CSV/XLSX export."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders?page=1&per_page=10&filter[search]=&filter[status]=&filter[supplier_id]=&filter[covered_by_po]=&filter[eta_state]=&filter[sku]=&filter[product_name]=&filter[supplier_name]=&filter[quantity]=&filter[priority]=&filter[created_at]=&sort=priority","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search across id, sku, product name, supplier name, sales order number, PO number","disabled":true},{"key":"filter[status]","value":"","description":"Backorder status: pending | released | partial | cancelled","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID","disabled":true},{"key":"filter[covered_by_po]","value":"","description":"true | false — filter by whether the backorder is covered by a PO","disabled":true},{"key":"filter[eta_state]","value":"","description":"on_time | late | unknown","disabled":true},{"key":"filter[sku]","value":"","description":"Text filter on product SKU","disabled":true},{"key":"filter[product_name]","value":"","description":"Text filter on product name","disabled":true},{"key":"filter[supplier_name]","value":"","description":"Text filter on supplier name","disabled":true},{"key":"filter[quantity]","value":"","description":"Numeric filter on backorder quantity","disabled":true},{"key":"filter[priority]","value":"","description":"Numeric filter on priority","disabled":true},{"key":"filter[created_at]","value":"","description":"Datetime filter on created_at","disabled":true},{"key":"sort","value":"priority","description":"Sort field. Options: id, priority, quantity, created_at, updated_at, backorder_date, backordered_quantity, released_quantity, sku, product_name, supplier, order_date, sales_order_number, eta. Default: priority","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10045,\n      \"priority\": 1,\n      \"backorder_date\": \"2025-04-10\",\n      \"order_date\": \"2025-04-08\",\n      \"sku\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\"\n      },\n      \"product_name\": \"Blue Widget\",\n      \"backordered_quantity\": 5,\n      \"released_quantity\": 0,\n      \"quantity\": 5,\n      \"status\": \"pending\",\n      \"status_label\": \"Pending\",\n      \"supplier\": {\n        \"id\": 14,\n        \"name\": \"Acme Corp\"\n      },\n      \"sales_order_number\": {\n        \"sales_order_line_id\": 55347,\n        \"sales_order_id\": 9821,\n        \"sales_order_number\": \"SO-9821\"\n      },\n      \"covered_by_po\": false,\n      \"is_tight_coverage\": false,\n      \"purchase_order_line_id\": null,\n      \"purchase_order\": null,\n      \"eta\": null,\n      \"eta_state\": \"unknown\",\n      \"eta_source\": null,\n      \"has_split_coverage\": false,\n      \"other_warehouse_stock\": {\n        \"total\": 0,\n        \"warehouses\": []\n      },\n      \"in_transit_stock\": {\n        \"total\": 0,\n        \"warehouses\": []\n      },\n      \"scheduled_at\": null,\n      \"created_at\": \"2025-04-10T08:22:11.000000Z\",\n      \"updated_at\": \"2025-04-10T08:22:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Search Backorders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders"]},"description":"Returns the same paginated list of backorders as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA `status` scope selects which backorders are returned: `active` (default; outstanding backorders awaiting stock or receipt), `released` (backorders that have since been allocated or fulfilled), `released_fulfilled`, `released_submitted`, `released_unfulfilled`, or `all`.\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against allocation id, SKU, product name, supplier, sales order number, and purchase order number.\n\nText columns (`sku`, `product_name`, `supplier_name`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `quantity`, `priority`, `backordered_quantity`, `released_quantity`, `created_at`, `updated_at`, `backorder_date`, `order_date`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. Boolean filters `covered_by_po` and `has_other_wh_stock` accept `is` with true/false; `eta_state` accepts `is` with `has_eta`, `late_eta`, or `missing_eta`; `supplier_id` accepts a numeric id or `none`.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, priority, quantity, created_at, updated_at, backorder_date, backordered_quantity, released_quantity, sku, product_name, supplier, order_date, sales_order_number, eta. Results default to `priority`.","body":{"mode":"raw","raw":"{\n  \"status\": \"active\",\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"priority\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"covered_by_po\",\n          \"operator\": \"is\",\n          \"value\": false\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"product_name\",\n          \"operator\": \"contains\",\n          \"value\": \"Widget\"\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 77120,\n      \"priority\": 1,\n      \"backorder_date\": \"2026-06-25T11:03:00.000000Z\",\n      \"order_date\": \"2026-06-24\",\n      \"sku\": {\n        \"id\": 3312,\n        \"sku\": \"WIDGET-BLUE-01\"\n      },\n      \"product_name\": \"Blue Widget\",\n      \"backordered_quantity\": 12,\n      \"released_quantity\": 0,\n      \"quantity\": 12,\n      \"status\": \"planned\",\n      \"status_label\": \"Planned\",\n      \"supplier\": {\n        \"id\": 44,\n        \"name\": \"Acme Supply Co\"\n      },\n      \"sales_order_number\": {\n        \"sales_order_line_id\": 88231,\n        \"sales_order_id\": 6021,\n        \"sales_order_number\": \"SO-6021\"\n      },\n      \"covered_by_po\": false,\n      \"is_tight_coverage\": false,\n      \"purchase_order_line_id\": null,\n      \"purchase_order\": null,\n      \"eta\": null,\n      \"eta_state\": \"missing_no_po\",\n      \"eta_source\": null,\n      \"has_split_coverage\": false,\n      \"other_warehouse_stock\": [],\n      \"scheduled_at\": \"2026-07-10\",\n      \"created_at\": \"2026-06-25T11:03:00.000000Z\",\n      \"updated_at\": \"2026-06-25T11:03:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 3,\n  \"total\": 61,\n  \"next_page_url\": \"https://api.example.com/api/v2/inventory-allocations/backorders?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Export Backorders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders/export?format=xlsx&scope=filtered&filter[status]=active","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders","export"],"query":[{"key":"format","value":"xlsx","description":"Export file format: xlsx (default) or csv","disabled":true},{"key":"scope","value":"filtered","description":"Which records to export: all (ignores filters, keeps status tab) | filtered (default, honors active filters/search) | current_page (just the page the user is viewing) | selected (requires ids param)","disabled":true},{"key":"filter[status]","value":"active","description":"Status tab. Preserved even when scope=all. Values: active | pending | released | partial | cancelled","disabled":true}]},"description":"Downloads the backorder queue as an XLSX or CSV file.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUses the same status scope, search, and grouped filter pipeline as `List Backorders`, so the export always matches what the user sees in the UI for the active status tab.\n\n**Scopes:**\n- `all` — export every backorder in the current status tab, ignoring filters/search/sort\n- `filtered` (default) — honor all active filters, search, and sort\n- `current_page` — just the page currently rendered by the list view\n- `selected` — the IDs passed via the `ids` query param (comma-separated)\n\n**Columns:**\nPass `columns` as a comma-separated list of keys to limit the export to the visible list view columns (in request order). Omit `columns` to export every available column.\n\n**Response:**\nReturns a binary download — `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for xlsx, `text/csv` for csv. Filename pattern: `backorders-YYYY-MM-DD-HH-MM-SS.{format}`.\n\nEach backorder row also carries `in_transit_stock` (inbound stock in motion across warehouses), alongside `other_warehouse_stock`. Both are populated in the CSV/XLSX export."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/backorders/export?format=xlsx&scope=filtered&filter[status]=active","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","backorders","export"],"query":[{"key":"format","value":"xlsx","description":"Export file format: xlsx (default) or csv","disabled":true},{"key":"scope","value":"filtered","description":"Which records to export: all (ignores filters, keeps status tab) | filtered (default, honors active filters/search) | current_page (just the page the user is viewing) | selected (requires ids param)","disabled":true},{"key":"filter[status]","value":"active","description":"Status tab. Preserved even when scope=all. Values: active | pending | released | partial | cancelled","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary xlsx contents>"}]},{"name":"Get Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/summary","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","summary"]},"description":"Returns summary statistics for inventory allocations — total counts by status, total quantities, coverage metrics.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/summary","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_count\": 34,\n    \"released_count\": 12,\n    \"fulfilled_count\": 201,\n    \"cancelled_count\": 5,\n    \"pending_quantity\": 340,\n    \"released_quantity\": 87,\n    \"tight_coverage_count\": 8\n  }\n}"}]},{"name":"Get Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/breakdown","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","breakdown"]},"description":"Returns a breakdown of allocations grouped by relevant dimensions (warehouse, supplier, status) for dashboard widgets.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/breakdown","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","breakdown"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"by_status\": [\n      {\n        \"status\": \"pending\",\n        \"count\": 34,\n        \"quantity\": 340\n      },\n      {\n        \"status\": \"released\",\n        \"count\": 12,\n        \"quantity\": 87\n      }\n    ],\n    \"by_warehouse\": [\n      {\n        \"warehouse_id\": 3,\n        \"warehouse_name\": \"East Coast DC\",\n        \"count\": 28\n      }\n    ],\n    \"by_supplier\": [\n      {\n        \"supplier_id\": 14,\n        \"supplier_name\": \"Acme Corp\",\n        \"count\": 20\n      }\n    ]\n  }\n}"}]},{"name":"Get Product Analysis","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/product/{productId}/analysis","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","product",":productId","analysis"],"variable":[{"key":"productId","value":"812","description":"Product ID"}]},"description":"Returns allocation analysis for a specific product — current allocations, coverage status, and demand history.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/product/{productId}/analysis","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","product",":productId","analysis"],"variable":[{"key":"productId","value":"812","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 812,\n      \"sku\": \"WIDGET-BLU\",\n      \"name\": \"Blue Widget\"\n    },\n    \"active_allocations\": 3,\n    \"total_allocated_quantity\": 15,\n    \"total_stock\": 20,\n    \"available_after_allocations\": 5,\n    \"tight_coverage\": false\n  }\n}"}]},{"name":"Get Supplier Analysis","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/supplier/{supplierId}/analysis","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","supplier",":supplierId","analysis"],"variable":[{"key":"supplierId","value":"14","description":"Supplier ID"}]},"description":"Returns allocation analysis for a specific supplier — coverage metrics, pending PO quantities, backorder exposure.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/supplier/{supplierId}/analysis","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","supplier",":supplierId","analysis"],"variable":[{"key":"supplierId","value":"14","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"supplier\": {\n      \"id\": 14,\n      \"name\": \"Acme Corp\"\n    },\n    \"pending_backorders\": 8,\n    \"total_backordered_quantity\": 42,\n    \"po_covered_quantity\": 30,\n    \"uncovered_quantity\": 12\n  }\n}"}]},{"name":"List Coverage Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/product/{productId}/coverage-options","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","product",":productId","coverage-options"],"variable":[{"key":"productId","value":"812","description":"Product ID"}]},"description":"Lists the open PO lines a product's allocation can be manually covered by — used to populate the 'Change PO Coverage' picker.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns non-draft / non-closed / non-cancelled / non-voided PO lines with unreceived quantity remaining, sorted by earliest resolved ETA first (lines with no resolvable ETA sort last, by creation order). `resolved_eta` is the inbound-shipment expected arrival date, falling back to the PO header's estimated delivery date."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/product/{productId}/coverage-options","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","product",":productId","coverage-options"],"variable":[{"key":"productId","value":"812","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 5567,\n      \"purchase_order_id\": 902,\n      \"purchase_order_number\": \"PO-000902\",\n      \"quantity\": 100,\n      \"received_quantity\": 20,\n      \"unreceived_quantity\": 80,\n      \"resolved_eta\": \"2026-05-28\"\n    },\n    {\n      \"purchase_order_line_id\": 5612,\n      \"purchase_order_id\": 915,\n      \"purchase_order_number\": \"PO-000915\",\n      \"quantity\": 50,\n      \"received_quantity\": 0,\n      \"unreceived_quantity\": 50,\n      \"resolved_eta\": \"2026-06-10\"\n    }\n  ]\n}"}]},{"name":"List Allocation Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/suppliers","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","suppliers"]},"description":"Returns a list of suppliers that have active inventory allocations — used to populate supplier filter dropdowns.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/suppliers","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","suppliers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 14,\n      \"name\": \"Acme Corp\"\n    },\n    {\n      \"id\": 22,\n      \"name\": \"Global Supply Ltd\"\n    }\n  ]\n}"}]},{"name":"Search Allocation Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/search-suppliers?query=acme","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","search-suppliers"],"query":[{"key":"query","value":"acme","description":"Supplier name search string","disabled":true}]},"description":"Searches suppliers by name for autocomplete dropdowns. Returns suppliers that match the query string.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/search-suppliers?query=acme","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","search-suppliers"],"query":[{"key":"query","value":"acme","description":"Supplier name search string","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 14,\n      \"name\": \"Acme Corp\"\n    },\n    {\n      \"id\": 31,\n      \"name\": \"Acme International\"\n    }\n  ]\n}"}]},{"name":"Export Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/export?format=xlsx&scope=filtered&ids=","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered | selected | all","disabled":true},{"key":"ids","value":"","description":"Comma-separated allocation IDs when scope=selected","disabled":true}]},"description":"Downloads an export of inventory allocations.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query Parameters**:\n- `format` — `xlsx` (default)\n- `scope` — `filtered` (apply current filters), `selected` (specific IDs), `all`\n- `ids` — Required when `scope=selected`. Comma-separated allocation IDs.\n\nReturns a binary file download response."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/export?format=xlsx&scope=filtered&ids=","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered | selected | all","disabled":true},{"key":"ids","value":"","description":"Comma-separated allocation IDs when scope=selected","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file)"}]},{"name":"Sync Coverages","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/sync-coverages","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","sync-coverages"]},"description":"Dispatches a background job to sync allocation coverages. Returns a `tracked_job_log_id` for monitoring progress via the tracked job log endpoints.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/sync-coverages","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","sync-coverages"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Sync coverages job started.\"\n}"}]},{"name":"Rebalance Coverages","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/rebalance-coverages","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","rebalance-coverages"]},"description":"Dispatches a background job that rebalances allocation coverages — it tears down every non-tight `AwaitingReceipt` coverage and rebuilds it from scratch using the current resolved PO ETAs (inbound-shipment expected arrival, falling back to the PO header's estimated delivery date).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nManually pinned (tight) coverage is never touched. Returns a `tracked_job_log_id` for monitoring progress via the tracked job log endpoints.\n\nUse this after PO ETAs change so existing PO-line ↔ allocation bindings reflect earliest-ETA-first ordering.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/rebalance-coverages","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","rebalance-coverages"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4822\n  },\n  \"message\": \"Coverage rebalance job has been queued\"\n}"}]},{"name":"Release Allocations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/release-allocations","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","release-allocations"]},"description":"Dispatches a background job to release eligible allocations to fulfillment. Returns a `tracked_job_log_id` for monitoring progress via the tracked job log endpoints.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/release-allocations","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","release-allocations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4822\n  },\n  \"message\": \"Release allocations job started.\"\n}"}]},{"name":"Reset Priorities","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/reset-priorities","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","reset-priorities"]},"description":"Dispatches a background job to reset allocation priorities using the specified method.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `method` (required) — Priority reset method: `fifo` | `lifo` | custom\n- `overwrite_tight_coverages` (boolean) — Whether to reassign tight coverage allocations\n- `resync_coverages` (boolean) — Whether to resync coverages after reset\n\nReturns a `tracked_job_log_id`.","body":{"mode":"raw","raw":"{\n  \"method\": \"fifo\",\n  \"overwrite_tight_coverages\": false,\n  \"resync_coverages\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/reset-priorities","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","reset-priorities"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4823\n  },\n  \"message\": \"Reset priorities job started.\"\n}"}]},{"name":"Compact Priorities","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/compact-priorities","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","compact-priorities"]},"description":"Dispatches a background job to compact allocation priority numbers — fills in gaps from deleted/cancelled allocations so priorities are sequential. Returns a `tracked_job_log_id`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/compact-priorities","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","compact-priorities"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4825\n  },\n  \"message\": \"Compact priorities job started.\"\n}"}]},{"name":"Evaluate Releases","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/evaluate-releases","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","evaluate-releases"]},"description":"Dispatches a background job to evaluate which allocations are ready for release.\n\n**Body**:\n- `dispatch_fulfillments` (boolean) — If `true`, automatically dispatch fulfillments for ready allocations. If `false`, only evaluate and mark.\n\nReturns a `tracked_job_log_id`.","body":{"mode":"raw","raw":"{\n  \"dispatch_fulfillments\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/evaluate-releases","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","evaluate-releases"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4824\n  },\n  \"message\": \"Evaluate releases job started.\"\n}"}]},{"name":"Check Release Availability","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/check-release-availability","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","check-release-availability"]},"description":"Checks whether the specified allocations have sufficient stock to be released. Returns availability status per allocation.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `allocation_ids` — Array of allocation IDs to check","body":{"mode":"raw","raw":"{\n  \"allocation_ids\": [\n    10045,\n    10046,\n    10047\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/check-release-availability","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","check-release-availability"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"allocation_id\": 10045,\n      \"available\": true,\n      \"stock\": 20,\n      \"required\": 5\n    },\n    {\n      \"allocation_id\": 10046,\n      \"available\": false,\n      \"stock\": 2,\n      \"required\": 10\n    },\n    {\n      \"allocation_id\": 10047,\n      \"available\": true,\n      \"stock\": 8,\n      \"required\": 3\n    }\n  ]\n}"}]},{"name":"Release Selected Backorders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/release-selected","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","release-selected"]},"description":"Immediately releases the specified allocations to fulfillment.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `allocation_ids` — Array of allocation IDs to release","body":{"mode":"raw","raw":"{\n  \"allocation_ids\": [\n    10045,\n    10047\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/release-selected","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","release-selected"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 allocations released successfully.\",\n  \"released_count\": 2\n}"}]},{"name":"Submit Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/submit-fulfillments","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","submit-fulfillments"]},"description":"Submits fulfillments for the specified released allocations.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `allocation_ids` — Array of allocation IDs to submit fulfillments for","body":{"mode":"raw","raw":"{\n  \"allocation_ids\": [\n    10045,\n    10047\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/submit-fulfillments","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","submit-fulfillments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillments submitted for 2 allocations.\"\n}"}]},{"name":"Delete Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/delete-fulfillments","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","delete-fulfillments"]},"description":"Deletes pending fulfillments for the specified allocations, reverting them to released status.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `allocation_ids` — Array of allocation IDs whose fulfillments should be deleted","body":{"mode":"raw","raw":"{\n  \"allocation_ids\": [\n    10045\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/delete-fulfillments","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","delete-fulfillments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillments deleted for 1 allocation.\"\n}"}]},{"name":"Unreserve Allocations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/unreserve","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","unreserve"]},"description":"Cancels (unreserves) the specified allocations.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `allocation_ids` — Array of allocation IDs to cancel\n- `disable_auto_release` (boolean) — If `true`, disables automatic re-release for the linked source document after cancellation","body":{"mode":"raw","raw":"{\n  \"allocation_ids\": [\n    10045,\n    10046\n  ],\n  \"disable_auto_release\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/unreserve","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","unreserve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 allocations cancelled.\"\n}"}]},{"name":"Switch Supplier Options","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/switch-supplier-options","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","switch-supplier-options"]},"description":"Returns the per-allocation supplier picker payload used by the Allocation Pipeline Change Supplier dialog. Only allocations in `planned` or `awaiting_receipt` status are eligible. For each eligible allocation, returns the list of suppliers configured for that product (via `supplier_products`), excluding archived suppliers.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `ids` (required, array, min 1) — Array of inventory allocation IDs.\n- `ids.*` (integer) — Each ID must be an integer.\n\n**Notes**:\n- Allocations whose status is not `planned` or `awaiting_receipt` are silently filtered out (they are not eligible for supplier change).\n- Each row's `suppliers` list is sorted with the default supplier first, then alphabetically by name.\n- Use the returned `current_supplier.id` to highlight the existing selection in the UI.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10045,\n    10046\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/switch-supplier-options","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","switch-supplier-options"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10045,\n      \"product_id\": 8821,\n      \"sku\": \"SPN-STD-SPIRAL-BLK\",\n      \"product_name\": \"Spiral Notebook - Black\",\n      \"current_supplier\": {\n        \"id\": 14,\n        \"name\": \"HomeLife\"\n      },\n      \"suppliers\": [\n        {\n          \"id\": 14,\n          \"name\": \"HomeLife\",\n          \"is_default\": true\n        },\n        {\n          \"id\": 27,\n          \"name\": \"A Bar Above\",\n          \"is_default\": false\n        }\n      ]\n    },\n    {\n      \"id\": 10046,\n      \"product_id\": 9102,\n      \"sku\": \"WGT-001\",\n      \"product_name\": \"Widget 001\",\n      \"current_supplier\": null,\n      \"suppliers\": [\n        {\n          \"id\": 31,\n          \"name\": \"Acme Supply Co.\",\n          \"is_default\": true\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Switch Suppliers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/switch-suppliers","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","switch-suppliers"]},"description":"Bulk updates the supplier on one or more inventory allocations. Each assignment is validated against `supplier_products` so the chosen supplier must already be configured for the allocation's product. Allocations not in `planned` or `awaiting_receipt` status are skipped.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**:\n- `assignments` (required, array, min 1) — List of allocation/supplier pairs to apply.\n- `assignments.*.allocation_id` (required, integer, exists in `inventory_allocations`) — ID of the allocation to update.\n- `assignments.*.supplier_id` (required, integer, exists in `suppliers`) — ID of the supplier to assign.\n\n**Behavior**:\n- Assignments where the new supplier matches the current supplier are counted as `skipped` (no-op).\n- Assignments referencing an allocation that is no longer in `planned`/`awaiting_receipt` are counted as `skipped`.\n- Assignments where the supplier is not configured for the product return per-row errors and do NOT update the allocation.\n- The endpoint is best-effort per row; partial success is normal (e.g., 3 updated, 1 skipped, 1 error).","body":{"mode":"raw","raw":"{\n  \"assignments\": [\n    {\n      \"allocation_id\": 10045,\n      \"supplier_id\": 27\n    },\n    {\n      \"allocation_id\": 10046,\n      \"supplier_id\": 31\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/inventory-allocations/switch-suppliers","host":["{{baseUrl}}"],"path":["api","v2","inventory-allocations","switch-suppliers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Updated supplier on 2 allocation(s).\",\n  \"data\": {\n    \"updated\": 2,\n    \"skipped\": 0,\n    \"errors\": []\n  }\n}"}]},{"name":"Create Warehouse Transfer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers","host":["{{baseUrl}}"],"path":["api","warehouses","transfers"]},"description":"Creates a warehouse transfer (in draft status) moving stock between two warehouses.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: from_warehouse_id and to_warehouse_id (required, must differ), transfer_date, eta (must not be before transfer_date), products (array of {product_id, quantity, quantity_cancelled, description, sales_channel_unique_id}), shipping_method_id, shipment (object with shipment_date, tracking_number, cost - creates an initial shipment), shipment_id (required when the destination is an Amazon FBA warehouse - the Amazon inbound shipment ID), order_id and custom_field_values (array of {custom_field_id, value}).\n\nReturns 400 when a product does not have enough available stock in the source warehouse.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"transfer_date\": \"2026-06-01\",\n  \"eta\": \"2026-06-15\",\n  \"from_warehouse_id\": 2,\n  \"to_warehouse_id\": 5,\n  \"shipping_method_id\": 3,\n  \"products\": [\n    {\n      \"product_id\": 101,\n      \"quantity\": 100\n    },\n    {\n      \"product_id\": 102,\n      \"quantity\": 50\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers","host":["{{baseUrl}}"],"path":["api","warehouses","transfers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer created successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Bulk Delete Warehouse Transfers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers","host":["{{baseUrl}}"],"path":["api","warehouses","transfers"]},"description":"Deletes multiple warehouse transfers, reversing their inventory movements. Provide either ids (array of transfer IDs) or apply_to_all=true with an optional filters object.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 400 when received stock from a transfer has already been consumed downstream.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/transfers","host":["{{baseUrl}}"],"path":["api","warehouses","transfers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 2,\n    \"failCount\": 0\n  },\n  \"message\": \"2 records processed successfully.\"\n}"}]},{"name":"Update Warehouse Transfer","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Updates a warehouse transfer. Accepts the same fields as Create Warehouse Transfer (all optional) plus tags (array of tag names to sync). The products array replaces the transfer's line items; include existing line ids to keep them.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTransfers to an Amazon FBA warehouse can only be edited while in draft status. Returns 422 when editing a line that has already been shipped or when stock is insufficient.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"eta\": \"2026-06-20\",\n  \"products\": [\n    {\n      \"id\": 9001,\n      \"product_id\": 101,\n      \"quantity\": 120\n    }\n  ],\n  \"tags\": [\n    \"restock\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer updated successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null,\n    \"shipment_percent\": 0,\n    \"receipt_percent\": 0,\n    \"items\": [\n      {\n        \"id\": 9001,\n        \"quantity\": 100,\n        \"product_id\": 101,\n        \"product\": {\n          \"id\": 101,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Widget\",\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"sku\": \"WIDGET-001\",\n        \"barcode\": 123456789012,\n        \"sales_channel_unique_id\": null,\n        \"name\": \"Widget\",\n        \"image_url\": null,\n        \"quantity_cancelled\": 0,\n        \"quantity_received\": 0,\n        \"quantity_shipped\": 0\n      }\n    ],\n    \"tags\": [\n      \"restock\"\n    ],\n    \"total_quantity\": 100\n  }\n}"}]},{"name":"Delete Warehouse Transfer","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Deletes a warehouse transfer and reverses its inventory movements. Deletion fails when received stock from this transfer has already been consumed downstream (sold, transferred again, or adjusted).\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer 512 deleted successfully.\"\n}"}]},{"name":"Duplicate Warehouse Transfer","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/duplicate","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","duplicate"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID to duplicate"}]},"description":"Creates a new draft warehouse transfer copying the source transfer's warehouses and line items.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/duplicate","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","duplicate"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID to duplicate"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer created successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"List Warehouse Transfers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers?page=1&per_page=10&filter[search]=&filter[archived]=&filter[transfer_type]=&filter[has_blemished]=&filter[has_inbound_plan]=&filter[include_deleted]=&filter_groups[conjunction]=and&sort=-transfer_date","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Cross-column search: id, transfer_number, from_warehouse name, to_warehouse name, item SKU, item FNSKU","disabled":true},{"key":"filter[archived]","value":"","description":"true | false — filter archived transfers","disabled":true},{"key":"filter[transfer_type]","value":"","description":"Text filter on transfer_type: standard | fba_inbound | awd","disabled":true},{"key":"filter[has_blemished]","value":"","description":"Text filter — true | false","disabled":true},{"key":"filter[has_inbound_plan]","value":"","description":"Text filter — true | false (FBA inbound plan link)","disabled":true},{"key":"filter[include_deleted]","value":"","description":"true — include soft-deleted transfers","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"Advanced filter tree conjunction: and | or. Use with filter_groups[children][] for grouped conditions.","disabled":true},{"key":"sort","value":"-transfer_date","description":"Sort field. Prefix with - for descending. Options: id, warehouse_transfer_number, transfer_date, transfer_status, shipment_status, receipt_status, created_at, updated_at, eta, archived_at, asn_last_sent_at, status, from_warehouse_name, to_warehouse_name, from_warehouse, to_warehouse. Default: -transfer_date","disabled":true}]},"description":"Returns a paginated list of warehouse transfers.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Supports GET and POST** — POST can be used to send large filter payloads in the request body.\n\n**Filters** (via Spatie QueryBuilder + GroupedFilterSupport):\n- `filter[search]` — Cross-column search on id, transfer_number, from/to warehouse name, item SKU, item FNSKU\n- `filter[archived]` — Boolean (true|false) — archived transfers\n- `filter[transfer_type]` — Transfer type text filter: `standard`, `fba_inbound`, `awd`\n- `filter[has_blemished]` — Boolean text filter\n- `filter[has_inbound_plan]` — Boolean text filter (FBA)\n- `filter[include_deleted]` — Include soft-deleted records\n- `filter_groups` — Tree-based advanced filters (GroupedFilterSupport)\n\n**Sort options**: id, warehouse_transfer_number, transfer_date, transfer_status, shipment_status, receipt_status, created_at, updated_at, eta, archived_at, asn_last_sent_at, status, from_warehouse_name, to_warehouse_name, from_warehouse, to_warehouse. Default: `-transfer_date`.\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers?page=1&per_page=10&filter[search]=&filter[archived]=&filter[transfer_type]=&filter[has_blemished]=&filter[has_inbound_plan]=&filter[include_deleted]=&filter_groups[conjunction]=and&sort=-transfer_date","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Cross-column search: id, transfer_number, from_warehouse name, to_warehouse name, item SKU, item FNSKU","disabled":true},{"key":"filter[archived]","value":"","description":"true | false — filter archived transfers","disabled":true},{"key":"filter[transfer_type]","value":"","description":"Text filter on transfer_type: standard | fba_inbound | awd","disabled":true},{"key":"filter[has_blemished]","value":"","description":"Text filter — true | false","disabled":true},{"key":"filter[has_inbound_plan]","value":"","description":"Text filter — true | false (FBA inbound plan link)","disabled":true},{"key":"filter[include_deleted]","value":"","description":"true — include soft-deleted transfers","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"Advanced filter tree conjunction: and | or. Use with filter_groups[children][] for grouped conditions.","disabled":true},{"key":"sort","value":"-transfer_date","description":"Sort field. Prefix with - for descending. Options: id, warehouse_transfer_number, transfer_date, transfer_status, shipment_status, receipt_status, created_at, updated_at, eta, archived_at, asn_last_sent_at, status, from_warehouse_name, to_warehouse_name, from_warehouse, to_warehouse. Default: -transfer_date","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"transfer_type\": \"standard\",\n      \"warehouse_transfer_number\": \"WT-501\",\n      \"transfer_date\": \"2025-04-10\",\n      \"from_warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"to_warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast DC\"\n      },\n      \"status\": \"in_transit\",\n      \"shipment_status\": \"shipped\",\n      \"shipment_percent\": 100,\n      \"receipt_status\": \"partial\",\n      \"receipt_percent\": 60,\n      \"shipping_method\": \"Ground\",\n      \"fully_shipped_at\": \"2025-04-11T14:00:00.000000Z\",\n      \"fully_received_at\": null,\n      \"items\": 3,\n      \"eta\": \"2025-04-15\",\n      \"created_at\": \"2025-04-10T08:00:00.000000Z\",\n      \"updated_at\": \"2025-04-11T14:05:00.000000Z\",\n      \"archived_at\": null,\n      \"tags\": [],\n      \"line_item_count\": 3,\n      \"total_quantity\": 150,\n      \"notes\": null,\n      \"adjustments\": [],\n      \"shipments\": [],\n      \"financial_lines\": []\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 8,\n  \"per_page\": 10,\n  \"total\": 78,\n  \"unfiltered_total\": 412,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Search Warehouse Transfers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers"]},"description":"Returns the same paginated list of warehouse transfers as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL. The response includes an `unfiltered_total` alongside the standard paginator totals so clients can show both the filtered and total record counts.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against transfer id, transfer number, source and destination warehouses, item SKU, and item FNSKU.\n\nText and status columns (`transfer_status`, `shipment_status`, `receipt_status`, `from_warehouse`, `to_warehouse`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `transfer_date`, `created_at`, `updated_at`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. The `transfer_type` filter accepts `standard`, `fba_inbound`, `awd_inbound`, or `awd_fba_replenishment`; `has_blemished`, `has_inbound_plan`, `archived`, and `include_deleted` are boolean toggles. Custom field filters are also supported.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, warehouse_transfer_number, transfer_date, transfer_status, shipment_status, receipt_status, created_at, updated_at, eta, archived_at, asn_last_sent_at, from_warehouse_name, to_warehouse_name. Results default to `-transfer_date`.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-transfer_date\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"transfer_type\",\n          \"operator\": \"is\",\n          \"value\": \"fba_inbound\"\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"shipment_status\",\n          \"operator\": \"is_not\",\n          \"value\": \"shipped\"\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3021,\n      \"transfer_type\": \"fba_inbound\",\n      \"warehouse_transfer_number\": \"WT-3021\",\n      \"transfer_date\": \"2026-06-27T00:00:00.000000Z\",\n      \"from_warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"standard\",\n        \"integration_instance_id\": null\n      },\n      \"to_warehouse\": {\n        \"id\": 9,\n        \"name\": \"Amazon FBA - US\",\n        \"type\": \"amazon_fba\"\n      },\n      \"status\": \"in_progress\",\n      \"shipment_status\": \"partially_shipped\",\n      \"shipment_id\": 1201,\n      \"receipt_status\": \"pending\",\n      \"fully_shipped_at\": null,\n      \"fully_received_at\": null,\n      \"eta\": \"2026-07-05\",\n      \"created_at\": \"2026-06-27T13:00:00.000000Z\",\n      \"updated_at\": \"2026-06-28T08:22:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 5,\n  \"total\": 118,\n  \"unfiltered_total\": 342,\n  \"next_page_url\": \"https://api.example.com/api/v2/warehouse-transfers?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Get Warehouse Transfer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns the full detail view of a warehouse transfer.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEager-loads: from_warehouse, to_warehouse, tags, adjustments, shipments (with lines and receipts), financial_lines, and COGS data. Also preloads current stock levels for both warehouses."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 501,\n  \"transfer_type\": \"standard\",\n  \"warehouse_transfer_number\": \"WT-501\",\n  \"transfer_date\": \"2025-04-10\",\n  \"from_warehouse\": {\n    \"id\": 1,\n    \"name\": \"Main Warehouse\"\n  },\n  \"to_warehouse\": {\n    \"id\": 3,\n    \"name\": \"East Coast DC\"\n  },\n  \"status\": \"in_transit\",\n  \"shipment_status\": \"shipped\",\n  \"shipment_percent\": 100,\n  \"receipt_status\": \"partial\",\n  \"receipt_percent\": 60,\n  \"shipping_method\": \"Ground\",\n  \"fully_shipped_at\": \"2025-04-11T14:00:00.000000Z\",\n  \"fully_received_at\": null,\n  \"items\": 3,\n  \"eta\": \"2025-04-15\",\n  \"created_at\": \"2025-04-10T08:00:00.000000Z\",\n  \"updated_at\": \"2025-04-11T14:05:00.000000Z\",\n  \"archived_at\": null,\n  \"tags\": [\n    {\n      \"id\": 5,\n      \"name\": \"urgent\"\n    }\n  ],\n  \"line_item_count\": 3,\n  \"total_quantity\": 150,\n  \"notes\": \"Rush transfer for East Coast restock\",\n  \"adjustments\": [],\n  \"shipments\": [\n    {\n      \"id\": 201,\n      \"shipped_at\": \"2025-04-11T14:00:00.000000Z\",\n      \"tracking_number\": \"1Z999AA1234567890\",\n      \"line_count\": 3,\n      \"receipts\": []\n    }\n  ],\n  \"financial_lines\": []\n}"}]},{"name":"Get Tab Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/tab-counts","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","tab-counts"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns badge counts for all detail page tabs in a single request — line items, shipments, receipts, inventory movements, FIFO layers, allocations, activity log. Used to populate tab badges without loading each tab's full data.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/tab-counts","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","tab-counts"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"line_items\": 3,\n    \"shipments\": 1,\n    \"receipts\": 1,\n    \"inventory_movements\": 45,\n    \"fifo_layers\": 3,\n    \"allocations\": 2,\n    \"activity_log\": 12\n  }\n}"}]},{"name":"Browse Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/browse-products?query=widget&in_stock_only=true&limit=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","browse-products"],"query":[{"key":"query","value":"widget","description":"Product search string (name or SKU)","disabled":true},{"key":"in_stock_only","value":"true","description":"true — only return products with available stock in the from_warehouse","disabled":true},{"key":"limit","value":"25","description":"Maximum number of results (default: 25)","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Searches products that can be added to this warehouse transfer. Scoped to the transfer's `from_warehouse`.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query Parameters**:\n- `query` — Product name or SKU search\n- `in_stock_only` — Restrict to products with stock in the source warehouse\n- `limit` — Max results (default: 25)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/browse-products?query=widget&in_stock_only=true&limit=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","browse-products"],"query":[{"key":"query","value":"widget","description":"Product search string (name or SKU)","disabled":true},{"key":"in_stock_only","value":"true","description":"true — only return products with available stock in the from_warehouse","disabled":true},{"key":"limit","value":"25","description":"Maximum number of results (default: 25)","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 812,\n      \"sku\": \"WIDGET-BLU\",\n      \"name\": \"Blue Widget\",\n      \"stock\": 45,\n      \"available_stock\": 38\n    },\n    {\n      \"id\": 813,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget\",\n      \"stock\": 20,\n      \"available_stock\": 20\n    }\n  ]\n}"}]},{"name":"Get Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/line-items","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","line-items"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns the line items for a warehouse transfer, including product details, quantities, shipped/received quantities, and COGS values.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/line-items","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","line-items"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3001,\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\",\n        \"name\": \"Blue Widget\"\n      },\n      \"quantity\": 50,\n      \"shipped_quantity\": 50,\n      \"received_quantity\": 30,\n      \"unit_cost\": \"12.50\",\n      \"total_cost\": \"625.00\",\n      \"notes\": null\n    },\n    {\n      \"id\": 3002,\n      \"product_id\": 813,\n      \"product\": {\n        \"id\": 813,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"quantity\": 100,\n      \"shipped_quantity\": 100,\n      \"received_quantity\": 60,\n      \"unit_cost\": \"9.75\",\n      \"total_cost\": \"975.00\",\n      \"notes\": null\n    }\n  ]\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns paginated inventory movements generated by this warehouse transfer (both ship-out and receive-in movements).\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88001,\n      \"type\": \"warehouse_transfer_ship\",\n      \"type_label\": \"WT Ship\",\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"quantity\": -50,\n      \"date\": \"2025-04-11\",\n      \"created_at\": \"2025-04-11T14:00:00.000000Z\"\n    },\n    {\n      \"id\": 88002,\n      \"type\": \"warehouse_transfer_receive\",\n      \"type_label\": \"WT Receive\",\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast DC\"\n      },\n      \"quantity\": 30,\n      \"date\": \"2025-04-13\",\n      \"created_at\": \"2025-04-13T09:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 25,\n  \"total\": 45\n}"}]},{"name":"Get FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/fifo-layers?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","fifo-layers"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search FIFO layers by product SKU or name","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns the FIFO inventory layers for this warehouse transfer (paginated).\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Two layer types depending on the transfer's destination:**\n- **Standard transfers** (destination is a regular warehouse) return regular `FifoLayer` rows produced when the transfer was received. The `origin` object carries the polymorphic receipt-line link.\n- **Amazon inbound transfers** (destination is an Amazon FBA/AWD warehouse — i.e. FBA inbound, AWD inbound, or AWD→FBA replenishment) don't produce regular `FifoLayer` rows; inventory enters Amazon and is tracked by `AmazonFifoLayer`. For these, the corresponding Amazon FIFO layers are returned in the same shape, each flagged with `is_amazon: true`, exposing `source_label` / `source_reference` (the Amazon source: ledger / discrepancy / initial inventory) in place of a receipt `origin`, plus a `detail_route` to the Amazon FIFO layer detail page. The Amazon layers are linked indirectly via the transfer's Amazon inbound shipment(s) (`AmazonNewFbaInboundShipment.sku_link`).\n\n**Query Parameters**:\n- `per_page` — Items per page (default: 15)\n- `filter[search]` — Search by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/fifo-layers?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","fifo-layers"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search FIFO layers by product SKU or name","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7701,\n      \"is_amazon\": false,\n      \"product_id\": 812,\n      \"fifo_layer_date\": \"2025-04-13T09:30:00.000000Z\",\n      \"sku\": \"WIDGET-BLU\",\n      \"product_name\": \"Blue Widget\",\n      \"original_quantity\": 30,\n      \"fulfilled_quantity\": 2,\n      \"available_quantity\": 28,\n      \"avg_cost\": \"12.5000\",\n      \"total_cost\": \"375.0000\",\n      \"origin\": {\n        \"link_type\": \"App\\\\Models\\\\WarehouseTransferShipmentReceiptLine\",\n        \"link_id\": 44012,\n        \"name\": \"Warehouse Transfer Receipt Line\",\n        \"parent_link_id\": 9120,\n        \"detail_link_id\": 501,\n        \"reference\": \"WT-501\",\n        \"parent_reference\": \"WT-501\",\n        \"manufacturing_order\": null\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast DC\"\n      },\n      \"created_at\": \"2025-04-13T09:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 3\n}"}]},{"name":"Get Product Cost Composition","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{productId}/cost-composition","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":productId","cost-composition"],"variable":[{"key":"productId","value":"101","description":"Product ID"}]},"description":"Returns the per-component cost composition of a product's weighted-average unit cost — how much each consumed component (and any landed-cost or labor category) contributes to the average unit cost. Useful for manufactured or assembled goods to see what makes up the final cost, not just the blended number.\n\nAggregated across the product's active warehouse FIFO layers, prorated by each layer's remaining quantity, so the composition ties out to the weighted-average cost. Amazon FBA inventory is excluded (separate WAC ledger). Layers with no categorized breakdown fall into an \"Uncategorized\" bucket.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{productId}/cost-composition","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":productId","cost-composition"],"variable":[{"key":"productId","value":"101","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"components\": [\n      {\n        \"category\": \"Helmet Shell\",\n        \"total\": 400,\n        \"per_unit\": 40,\n        \"pct\": 80\n      },\n      {\n        \"category\": \"Carry Pouch\",\n        \"total\": 60,\n        \"per_unit\": 6,\n        \"pct\": 12\n      },\n      {\n        \"category\": \"Sticker Pack\",\n        \"total\": 40,\n        \"per_unit\": 4,\n        \"pct\": 8\n      }\n    ],\n    \"total_available\": 10,\n    \"avg_cost\": 50\n  }\n}"}]},{"name":"Get Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/allocations?filter[status]=all&filter[warehouse_id]=&filter[search]=&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","allocations"],"query":[{"key":"filter[status]","value":"all","description":"Allocation status filter: all | active | pending | released | cancelled | fulfilled","disabled":true},{"key":"filter[warehouse_id]","value":"","description":"Filter by destination warehouse ID","disabled":true},{"key":"filter[search]","value":"","description":"Search by product SKU or name","disabled":true},{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns inventory allocations linked to this warehouse transfer.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query Parameters**:\n- `filter[status]` — `all` | `active` | `pending` | `released` | `cancelled` | `fulfilled`\n- `filter[warehouse_id]` — Filter by warehouse\n- `filter[search]` — Search by product SKU or name\n- `per_page` — Items per page"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/allocations?filter[status]=all&filter[warehouse_id]=&filter[search]=&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","allocations"],"query":[{"key":"filter[status]","value":"all","description":"Allocation status filter: all | active | pending | released | cancelled | fulfilled","disabled":true},{"key":"filter[warehouse_id]","value":"","description":"Filter by destination warehouse ID","disabled":true},{"key":"filter[search]","value":"","description":"Search by product SKU or name","disabled":true},{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10045,\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast DC\"\n      },\n      \"quantity\": 5,\n      \"status\": \"pending\",\n      \"status_label\": \"Pending\",\n      \"priority\": 1,\n      \"created_at\": \"2025-04-10T08:22:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2\n}"}]},{"name":"Generate Accounting Transactions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/generate-accounting-transactions","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","generate-accounting-transactions"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Generates or regenerates accounting transactions (financial lines) for this warehouse transfer based on the current COGS data.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/generate-accounting-transactions","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","generate-accounting-transactions"],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Accounting transactions generated successfully.\",\n  \"financial_lines_count\": 6\n}"}]},{"name":"Create Receiving Discrepancy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receiving-discrepancy","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receiving-discrepancy"],"variable":[{"key":"transfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Creates a receiving-discrepancy accounting transaction for a warehouse transfer, recording the financial gain/loss from the difference between expected and received quantities.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `transaction_date` (optional, date) — date to record the transaction on; defaults to now when omitted.\n\nNote: Receiving discrepancies cannot be created for Amazon-to-Amazon transfers (e.g. AWD→FBA) — Amazon reconciles those transfers automatically, so the endpoint returns 400.\n\n**Requires permission:** `warehouse_transfers.receive`","body":{"mode":"raw","raw":"{\n  \"transaction_date\": \"2026-05-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receiving-discrepancy","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receiving-discrepancy"],"variable":[{"key":"transfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully closed with receiving discrepancy\"\n}"}]},{"name":"Get Transfer Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]},"description":"Returns paginated activity log entries for a warehouse transfer.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/{warehouseTransfer}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers",":warehouseTransfer","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"warehouseTransfer","value":"501","description":"Warehouse Transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9901,\n      \"event\": \"created\",\n      \"description\": \"Warehouse transfer WT-501 created\",\n      \"causer\": {\n        \"id\": 1,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2025-04-10T08:00:00.000000Z\",\n      \"properties\": {}\n    },\n    {\n      \"id\": 9902,\n      \"event\": \"updated\",\n      \"description\": \"Status changed to in_transit\",\n      \"causer\": {\n        \"id\": 1,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2025-04-11T14:05:00.000000Z\",\n      \"properties\": {\n        \"old\": {\n          \"status\": \"pending\"\n        },\n        \"new\": {\n          \"status\": \"in_transit\"\n        }\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 12\n}"}]},{"name":"Download Lines Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/import-lines/template","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","import-lines","template"]},"description":"Downloads a multi-sheet XLSX template for the warehouse transfer lines bulk import.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Response**: A binary `.xlsx` file (zip-based Office Open XML).\n- `Content-Type`: `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- `Content-Disposition`: `attachment; filename=\"warehouse-transfer-lines-import-template-YYYY-MM-DD.xlsx\"`\n\n**Sheets:**\n1. **Import Here** — the row-data sheet with two required columns (`sku`, `quantity`) plus 3 example rows. Header row is frozen; columns are autofiltered; the SKU column has a comment explaining required fields.\n2. **Field Guide** — reference sheet describing each column (Required, Description, Valid Values, Example).\n\nNo query parameters or request body. Used by the \"Import Lines from CSV\" workflow on the warehouse transfer detail page (the resulting filled-out file is then POSTed to `/api/warehouses/transfers/import-lines`).\n\n**Requires permission:** `warehouse_transfers.import`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/import-lines/template","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","import-lines","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary XLSX file — zip archive starting with PK\\x03\\x04 signature>"}]},{"name":"Import Warehouse Transfer Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/import-lines","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","import-lines"]},"description":"Imports line items into an existing warehouse transfer from CSV data. Provide either file (a stored upload reference) or csvString (inline CSV content). The CSV must contain a sku column; quantity is optional and defaults to 1. Rows with the same SKU are merged and quantities summed.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: warehouse_transfer_id (required), file or csvString (one required), replace (boolean - when true, replaces all existing lines instead of adding), separator (default \",\") and escape (default '\"').\n\nReturns 400 when the CSV contains SKUs that do not match any product. Download a template from GET /api/warehouses/transfers/import-lines/template.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_transfer_id\": 512,\n  \"csvString\": \"sku,quantity\\nWIDGET-001,100\\nWIDGET-002,50\",\n  \"replace\": false,\n  \"separator\": \",\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/import-lines","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","import-lines"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer lines imported successfully.\"\n}"}]},{"name":"Export Warehouse Transfers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/export","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","export"]},"description":"Download warehouse transfers as an XLSX or CSV file. Requires export permission for warehouse transfers.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nExport controls:\n- `format` — xlsx (default) or csv.\n- `content_mode` — summary (default, one row per transfer) or line_items (one row per transfer line, with the transfer columns repeated and line columns appended: Line ID, Item SKU, Item Name, Item Description, Item Qty, Cancelled Qty, Item FNSKU).\n- `scope` — filtered (default: respects active filters/search), all (ignores filters), current_page (only the current page of the list), or selected (only the IDs passed in `ids`).\n- `ids` — comma-separated transfer IDs; required when scope=selected.\n- `columns` — comma-separated column keys to restrict/reorder transfer-level columns. Available keys: id, warehouse_transfer_number, transfer_date, from_warehouse, to_warehouse, transfer_type, status, shipment_status, receipt_status, shipping_method, shipment_id, line_item_count, eta, fully_shipped_at, fully_received_at, tags, created_at, updated_at (plus any custom-field columns defined for transfers).\n\nFilters (same set as List Warehouse Transfers; applied when scope is filtered or current_page):\n- `filter[search]` — matches transfer ID, transfer number, from/to warehouse name, item SKU, and item FNSKU.\n- `filter[archived]` — archived visibility: omit for non-archived only, `only` for archived only, `all` for everything.\n- `filter[include_deleted]` — `include` adds deleted transfers, `only` returns just deleted ones.\n- `filter[transfer_status.{op}]`, `filter[shipment_status.{op}]`, `filter[receipt_status.{op}]` — text operators; receipt_status also accepts the special value received_for_less.\n- `filter[transfer_type.{op}]` — values: standard, fba_inbound, awd_inbound, awd_fba_replenishment; operators: is, is_not, is_one_of, is_not_one_of.\n- `filter[has_blemished.is]=1` / `filter[has_inbound_plan.is]=1` — flag filters (is / is_not).\n- `filter[id.{op}]` — numeric operators.\n- `filter[from_warehouse.{op}]`, `filter[to_warehouse.{op}]` — warehouse ID, text operators.\n- `filter[transfer_date.{op}]`, `filter[created_at.{op}]`, `filter[updated_at.{op}]` — date operators.\n\nText operators: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty. Numeric operators: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty. Date operators: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days.\n\n`filter_groups` — base64-encoded JSON tree for nested AND/OR filter groups over the same columns.\n\nSorting: `sort` with optional `-` prefix for descending. Allowed sorts: id, warehouse_transfer_number, transfer_date, transfer_status, shipment_status, receipt_status, created_at, updated_at, eta, archived_at, asn_last_sent_at, status, from_warehouse_name, to_warehouse_name, from_warehouse, to_warehouse. Default: -transfer_date.\n\nResponse: binary file download (Content-Type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for xlsx, text/csv for csv).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/export","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file download — one row per warehouse transfer, or per line item when content_mode=line_items)"}]},{"name":"Get Warehouse Transfer Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/filter-options","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","filter-options"]},"description":"Returns the list of warehouses available for filtering warehouse transfers, as id/name pairs (Amazon FBA, virtual, and supplier warehouses are excluded, and archived warehouses are omitted). Use it to populate the warehouse filter dropdowns on the transfers list.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/filter-options","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","filter-options"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouses\": [\n      {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"East Coast DC\"\n      }\n    ]\n  }\n}"}]},{"name":"Create Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/shipments","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","shipments"],"variable":[{"key":"transfer","value":"38207","description":"Warehouse transfer ID (must be in open status)"}]},"description":"Creates a shipment for an already-open traditional (non-Amazon FBA) warehouse transfer. This is the explicit second step of the split lifecycle: open the transfer first (allocations only), then ship.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Effects:**\n- Deducts source warehouse stock\n- Creates `-active` and `+in_transit` inventory movements\n- Fulfils the line-level allocations created during open (Allocated → Fulfilled)\n\n**Request body (all fields optional unless noted):**\n- `shipment_date` (date) — defaults to today if omitted\n- `shipping_method_id` (integer) — must exist in `shipping_methods`\n- `tracking_number` (string, max 255)\n- `cost` (numeric, >= 0, < 100000)\n- `lines` (array, min 1 when present) — if omitted, all remaining open line quantities are shipped\n  - `lines[].warehouse_transfer_line_id` (integer, required_with:lines) — must belong to the transfer\n  - `lines[].quantity` (numeric, required_with:lines, min 0.0001)\n\n**Responses:**\n- `201 Created` — warehouse transfer object with updated shipments\n- `422 Unprocessable Entity` (`WarehouseTransferIsNotOpen`) — transfer is not in open status\n- `422 Unprocessable Entity` (`WarehouseTransferLineIsUnacceptable`) — a transfer line's requested quantity exceeds its allocated sum (allocations out of sync, e.g. stuck Fulfilled rows); the message includes the product SKU and the allocated quantity\n- `422 Unprocessable Entity` — transfer is an Amazon FBA transfer (use the Amazon-specific flow instead)\n- `400 Bad Request` (`ProductIsUnacceptable`) — not enough stock at the source warehouse for one of the requested lines\n\n**Requires permission:** `warehouse_transfers.ship`\nForm Request: `App\\Http\\Requests\\CreateWarehouseTransferShipmentRequest`\nRoute name: `warehouses.transfers.shipments.store`\n\nSource bin: each line may optionally set `warehouse_location_id` — the source-warehouse bin the line's dispatch should draw stock from. It must be an active (non-deprecated) bin in the transfer's source warehouse. When omitted, pickable source bins are walked automatically.","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2026-06-12\",\n  \"shipping_method_id\": 3,\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"cost\": 25.5,\n  \"lines\": [\n    {\n      \"warehouse_transfer_line_id\": 87499,\n      \"quantity\": 150,\n      \"warehouse_location_id\": 15\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/shipments","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","shipments"],"variable":[{"key":"transfer","value":"38207","description":"Warehouse transfer ID (must be in open status)"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 38207,\n    \"warehouse_transfer_number\": \"WH-38207\",\n    \"transfer_status\": \"open\",\n    \"shipment_status\": \"shipped\",\n    \"from_warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\"\n    },\n    \"to_warehouse\": {\n      \"id\": 8,\n      \"name\": \"Overflow Warehouse\"\n    },\n    \"transfer_date\": \"2026-06-12\",\n    \"shipments\": [\n      {\n        \"id\": 901,\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"shipped_at\": \"2026-06-12T16:00:00.000000Z\",\n        \"lines\": [\n          {\n            \"id\": 4001,\n            \"warehouse_transfer_line_id\": 87499,\n            \"quantity\": 150\n          }\n        ]\n      }\n    ]\n  },\n  \"message\": \"The warehouse transfer shipment created successfully\"\n}"}]},{"name":"Get Shipment Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment"],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]},"description":"Returns the detail view of a specific warehouse transfer shipment, including shipment lines and any associated receipts.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment"],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 201,\n  \"warehouse_transfer_id\": 501,\n  \"shipped_at\": \"2025-04-11T14:00:00.000000Z\",\n  \"tracking_number\": \"1Z999AA1234567890\",\n  \"carrier\": \"UPS\",\n  \"notes\": null,\n  \"lines\": [\n    {\n      \"id\": 4001,\n      \"warehouse_transfer_line_id\": 3001,\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\",\n        \"name\": \"Blue Widget\"\n      },\n      \"quantity\": 50\n    }\n  ],\n  \"receipts\": [\n    {\n      \"id\": 301,\n      \"received_at\": \"2025-04-13T09:30:00.000000Z\",\n      \"received_by\": \"John Doe\"\n    }\n  ],\n  \"created_at\": \"2025-04-11T14:00:00.000000Z\",\n  \"updated_at\": \"2025-04-13T09:30:00.000000Z\"\n}"}]},{"name":"Preview Shipment Line Quantity Change","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/lines/{line}/quantity-preview?quantity=12","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"12","description":"Target shipment line quantity (integer, >= 0). Required.","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Warehouse transfer shipment ID"},{"key":"line","value":"4001","description":"Warehouse transfer shipment line ID"}]},"description":"Preview the inventory implications of changing a warehouse transfer shipment line's quantity, without persisting any change.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns:\n- `current_quantity`, `new_quantity`, `delta`\n- `requires_confirmation` — true whenever delta != 0\n- `can_update` — false when either block applies\n- `blocks.below_received` — true if the requested quantity is below the total already received against this line; adjust receipts first\n- `blocks.above_transfer_line` — true if the requested quantity exceeds the parent warehouse transfer line quantity (the WT line caps the shipment, not source on-hand stock)\n- `implications.shipment_quantity` / `transfer_quantity` / `received_quantity` / `in_transit_quantity` — current vs after-update values. The parent warehouse transfer line quantity is ALWAYS unchanged (BBP invariant: the WT line is the canonical record of original intent)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/lines/{line}/quantity-preview?quantity=12","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"12","description":"Target shipment line quantity (integer, >= 0). Required.","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Warehouse transfer shipment ID"},{"key":"line","value":"4001","description":"Warehouse transfer shipment line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipment_id\": 201,\n    \"line_id\": 4001,\n    \"current_quantity\": 10,\n    \"new_quantity\": 8,\n    \"delta\": -2,\n    \"requires_confirmation\": true,\n    \"can_update\": true,\n    \"blocks\": {\n      \"below_received\": false,\n      \"above_transfer_line\": false\n    },\n    \"implications\": {\n      \"shipment_quantity\": {\n        \"label\": \"Warehouse transfer shipment line quantity\",\n        \"current\": 10,\n        \"after_update\": 8\n      },\n      \"transfer_quantity\": {\n        \"label\": \"Warehouse transfer line quantity (unchanged)\",\n        \"current\": 10,\n        \"after_update\": 10\n      },\n      \"received_quantity\": {\n        \"label\": \"Already received against this line\",\n        \"current\": 0,\n        \"after_update\": 0\n      },\n      \"in_transit_quantity\": {\n        \"label\": \"In-transit at destination after edit\",\n        \"current\": 10,\n        \"after_update\": 8\n      }\n    }\n  }\n}"}]},{"name":"Update Shipment Line Quantity","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/lines/{line}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","lines",":line"],"variable":[{"key":"shipment","value":"201","description":"Warehouse transfer shipment ID"},{"key":"line","value":"4001","description":"Warehouse transfer shipment line ID"}]},"description":"Update a warehouse transfer shipment line's quantity in place, scaling its inventory movements at the source (active negative) and destination (in-transit positive) accordingly.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `quantity` (integer, required, >= 0) — new shipment line quantity. Capped by the parent warehouse transfer line quantity.\n- `confirmed_implications` (boolean, optional) — must be `true` when the change is non-zero; otherwise the endpoint returns 409 with the preview payload so the caller can confirm.\n\nBehavior:\n- Increase: pulls `delta` additional units from source on-hand FIFO and places them in-transit toward the destination.\n- Decrease: returns `abs(delta)` units to source on-hand and removes them from in-transit at the destination.\n- The parent warehouse transfer line quantity is NEVER mutated by this endpoint — it preserves the original transfer intent (BBP invariant).\n\nErrors:\n- `409 Conflict` — non-zero delta without `confirmed_implications: true`; the preview is returned in `data` so callers can render and confirm.\n- `422 Unprocessable Entity` with `data.blocks.below_received: true` — requested quantity is below the total already received against this line; adjust receipts first.\n- `422 Unprocessable Entity` with `data.blocks.above_transfer_line: true` — requested quantity exceeds the parent warehouse transfer line quantity.\n- `422 Unprocessable Entity` from `InsufficientStockException` thrown by the inventory manager if FIFO consumption cannot satisfy the delta at the moment of save (race / concurrency safety net).\n\n**Requires permission:** `warehouse_transfers.ship`","body":{"mode":"raw","raw":"{\n  \"quantity\": 12,\n  \"confirmed_implications\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/lines/{line}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","lines",":line"],"variable":[{"key":"shipment","value":"201","description":"Warehouse transfer shipment ID"},{"key":"line","value":"4001","description":"Warehouse transfer shipment line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 201,\n    \"warehouse_transfer\": {\n      \"id\": 501,\n      \"warehouse_transfer_number\": \"WT-0501\"\n    },\n    \"from_warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\"\n    },\n    \"to_warehouse\": {\n      \"id\": 8,\n      \"name\": \"Overflow Warehouse\"\n    },\n    \"shipping_method\": null,\n    \"tracking_number\": \"1Z999AA1234567890\",\n    \"shipped_at\": \"2025-04-11T14:00:00.000000Z\",\n    \"fully_received_at\": null,\n    \"auto_generated_at_receipt\": false,\n    \"summary\": {\n      \"total_lines\": 1,\n      \"total_shipped\": 12,\n      \"total_received\": 0,\n      \"total_receipts\": 0\n    },\n    \"lines\": [\n      {\n        \"id\": 4001,\n        \"product\": {\n          \"id\": 812,\n          \"sku\": \"WIDGET-BLU\",\n          \"name\": \"Blue Widget\",\n          \"image_url\": null\n        },\n        \"description\": null,\n        \"quantity\": 12,\n        \"received_quantity\": 0\n      }\n    ],\n    \"receipts\": []\n  },\n  \"message\": \"Shipment line quantity updated successfully.\"\n}"}]},{"name":"Get Shipment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]},"description":"Returns paginated activity log entries for a specific shipment.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9910,\n      \"event\": \"created\",\n      \"description\": \"Shipment created with tracking 1Z999AA1234567890\",\n      \"causer\": {\n        \"id\": 1,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2025-04-11T14:00:00.000000Z\",\n      \"properties\": {}\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 3\n}"}]},{"name":"Get Shipment Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]},"description":"Returns paginated inventory movements scoped to the given warehouse transfer shipment. Movements are linked to the shipment's `WarehouseTransferShipmentLine` records (negative inventory events — stock leaving the source warehouse). Includes movement type, quantity, FIFO layer link, unit/total cost, and product/warehouse references for each movement. Used by the Movements tab on the shipment detail page.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/shipments/{shipment}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","shipments",":shipment","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"shipment","value":"201","description":"Shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 87553,\n      \"type\": \"transfer\",\n      \"inventory_status\": \"available\",\n      \"quantity\": -10,\n      \"reference\": \"WT-2025-0042\",\n      \"link_type\": \"App\\\\Models\\\\WarehouseTransferShipmentLine\",\n      \"link_id\": 4012,\n      \"parent_link_id\": 201,\n      \"detail_link_id\": null,\n      \"product_id\": 812,\n      \"product_sku\": \"WIDGET-BLU\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 8,\n      \"warehouse_name\": \"Source Warehouse\",\n      \"unit_cost\": 4.5,\n      \"unit_cost_provisional\": false,\n      \"total_cost\": 45,\n      \"layer\": {\n        \"name\": \"FIFO Layer #43850\",\n        \"layer_type\": \"App\\\\Models\\\\FifoLayer\",\n        \"layer_id\": 43850\n      },\n      \"inventory_movement_date\": \"2025-04-11T14:00:00.000000Z\",\n      \"created_at\": \"2025-04-11T14:00:01.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Delete Warehouse Transfer Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","shipments",":shipment"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"shipment","value":"204","description":"Shipment ID"}]},"description":"Deletes a shipment from the warehouse transfer, reversing its stock deduction at the source warehouse and returning the shipped quantities to available stock. Returns the updated transfer.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","shipments",":shipment"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"shipment","value":"204","description":"Shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer shipment 204 deleted successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"List Warehouse Transfer Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Returns all shipment receipts recorded against the warehouse transfer, including receipt lines with received quantities and the units still pending per shipment line.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 31,\n      \"received_at\": \"2026-06-10T09:00:00.000000Z\",\n      \"user\": {\n        \"id\": 4,\n        \"name\": \"Jane Smith\"\n      },\n      \"receipt_lines\": [\n        {\n          \"id\": 74,\n          \"product_id\": 101,\n          \"product_name\": \"Widget\",\n          \"product_sku\": \"WIDGET-001\",\n          \"quantity\": 60,\n          \"units_pending\": 40,\n          \"warehouse_transfer_line_id\": 9001\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Receipt Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt"],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]},"description":"Returns the detail view of a specific warehouse transfer receipt, including receipt lines. Automatically detects lines that generated blemished inventory adjustments.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt"],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 301,\n  \"warehouse_transfer_id\": 501,\n  \"shipment_id\": 201,\n  \"received_at\": \"2025-04-13T09:30:00.000000Z\",\n  \"received_by\": \"John Doe\",\n  \"notes\": null,\n  \"lines\": [\n    {\n      \"id\": 5001,\n      \"warehouse_transfer_line_id\": 3001,\n      \"product_id\": 812,\n      \"product\": {\n        \"id\": 812,\n        \"sku\": \"WIDGET-BLU\",\n        \"name\": \"Blue Widget\"\n      },\n      \"quantity\": 28,\n      \"blemished_quantity\": 2,\n      \"has_blemished_adjustment\": true\n    },\n    {\n      \"id\": 5002,\n      \"warehouse_transfer_line_id\": 3002,\n      \"product_id\": 813,\n      \"product\": {\n        \"id\": 813,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"quantity\": 60,\n      \"blemished_quantity\": 0,\n      \"has_blemished_adjustment\": false\n    }\n  ],\n  \"created_at\": \"2025-04-13T09:30:00.000000Z\",\n  \"updated_at\": \"2025-04-13T09:30:00.000000Z\"\n}"}]},{"name":"Preview Receipt Line Quantity Change","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/lines/{line}/quantity-preview?quantity=8","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"8","description":"Desired receipt line quantity (integer ≥ 0)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Warehouse transfer receipt ID"},{"key":"line","value":"5001","description":"Warehouse transfer receipt line ID"}]},"description":"Preview the implications of changing a warehouse transfer receipt line quantity without persisting any changes.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns:\n- `delta` — change vs. current quantity\n- `requires_confirmation` — true if the user must confirm before saving\n- `can_update` — false when blocking conditions exist\n- `blocks.above_shipped` — true if the new quantity exceeds the parent shipment line's shipped quantity (minus other receipts against the same shipment line)\n- `blocks.above_transfer_line` — true if the new quantity exceeds the parent warehouse transfer line quantity (minus other receipts against the same shipment line)\n- `caps.shipped_quantity` — shipment line shipped quantity\n- `caps.transfer_line_quantity` — warehouse transfer line quantity\n- `caps.other_receipts_total` — total received on the same shipment line via other receipts (excluding the line being edited)\n- `caps.max_quantity` — minimum of `shipped - other_receipts_total` and `transfer_line - other_receipts_total`\n- `implications.shipment_quantity` — shipment line quantity is NOT mutated by a receipt edit\n- `implications.transfer_quantity` — warehouse transfer line quantity is NOT mutated by a receipt edit\n- `implications.in_transit_quantity` — recomputed in-transit at destination after edit\n- `inventory` — FIFO usage / redistribution preview (when decreasing)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/lines/{line}/quantity-preview?quantity=8","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"8","description":"Desired receipt line quantity (integer ≥ 0)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Warehouse transfer receipt ID"},{"key":"line","value":"5001","description":"Warehouse transfer receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"receipt_type\": \"warehouse_transfer\",\n    \"line_id\": 5001,\n    \"current_quantity\": 10,\n    \"new_quantity\": 8,\n    \"delta\": -2,\n    \"requires_confirmation\": true,\n    \"can_update\": true,\n    \"blocks\": {\n      \"above_shipped\": false,\n      \"above_transfer_line\": false\n    },\n    \"caps\": {\n      \"shipped_quantity\": 10,\n      \"transfer_line_quantity\": 10,\n      \"other_receipts_total\": 0,\n      \"max_quantity\": 10\n    },\n    \"implications\": {\n      \"shipment_quantity\": {\n        \"label\": \"Warehouse transfer shipment line quantity (unchanged)\",\n        \"current\": 10,\n        \"after_update\": 10,\n        \"total_received_after_edit\": 8\n      },\n      \"transfer_quantity\": {\n        \"label\": \"Warehouse transfer line quantity (unchanged)\",\n        \"current\": 10,\n        \"after_update\": 10\n      },\n      \"in_transit_quantity\": {\n        \"label\": \"In-transit quantity at destination after edit\",\n        \"current\": 0,\n        \"after_update\": 2\n      }\n    },\n    \"inventory\": {\n      \"fifo_layer\": {\n        \"id\": 9001,\n        \"product_id\": 812,\n        \"warehouse_id\": 8,\n        \"original_quantity\": 10,\n        \"fulfilled_quantity\": 0,\n        \"available_quantity\": 10\n      },\n      \"decrease_quantity\": 2,\n      \"available_without_reassignment\": 10,\n      \"usage_quantity_to_redistribute\": 0,\n      \"requires_redistribution\": false,\n      \"can_redistribute\": true,\n      \"blocks_update\": false,\n      \"alternative_available_quantity\": 0,\n      \"alternative_shortage_quantity\": 0,\n      \"usages\": [],\n      \"alternative_layers\": []\n    }\n  }\n}"}]},{"name":"Update Receipt Line Quantity","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/lines/{line}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","lines",":line"],"variable":[{"key":"receipt","value":"301","description":"Warehouse transfer receipt ID"},{"key":"line","value":"5001","description":"Warehouse transfer receipt line ID"}]},"description":"Update a warehouse transfer receipt line's quantity. The shipment line and warehouse transfer line are NOT mutated by this edit — they remain canonical intent.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `quantity` (required, integer ≥ 0) — new receipt line quantity\n- `confirmed_implications` (optional, boolean) — required when the preview reports `requires_confirmation: true`\n- `redistribute_usages` (optional, boolean) — required when reducing quantity causes FIFO usage redistribution\n\nReturns 409 with the preview payload when confirmation is required and not yet provided.\n\nReturns 422 with `blocks.above_shipped: true` when the new quantity exceeds the shipment line shipped quantity (minus other receipts), and `blocks.above_transfer_line: true` when it exceeds the warehouse transfer line quantity. The cap subtracts the totals of OTHER receipt lines on the same shipment line, so concurrent partial receipts each get their fair share.\n\n**Requires permission:** `warehouse_transfers.receive`","body":{"mode":"raw","raw":"{\n  \"quantity\": 8,\n  \"confirmed_implications\": true,\n  \"redistribute_usages\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/lines/{line}","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","lines",":line"],"variable":[{"key":"receipt","value":"301","description":"Warehouse transfer receipt ID"},{"key":"line","value":"5001","description":"Warehouse transfer receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 301,\n    \"warehouse_transfer_id\": 501,\n    \"shipment_id\": 201,\n    \"received_at\": \"2025-04-13T09:30:00.000000Z\",\n    \"received_by\": \"John Doe\",\n    \"notes\": null,\n    \"lines\": [\n      {\n        \"id\": 5001,\n        \"warehouse_transfer_line_id\": 3001,\n        \"product_id\": 812,\n        \"product\": {\n          \"id\": 812,\n          \"sku\": \"WIDGET-BLU\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 8,\n        \"blemished_quantity\": 0,\n        \"has_blemished_adjustment\": false\n      }\n    ]\n  },\n  \"message\": \"Receipt line quantity updated successfully.\"\n}"}]},{"name":"Get Receipt Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]},"description":"Returns paginated activity log entries for a specific receipt.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/activity-log?per_page=25&filter[search]=","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true},{"key":"filter[search]","value":"","description":"Search activity log entries","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9920,\n      \"event\": \"created\",\n      \"description\": \"Receipt recorded — 90 units across 2 products\",\n      \"causer\": {\n        \"id\": 2,\n        \"name\": \"John Doe\"\n      },\n      \"created_at\": \"2025-04-13T09:30:00.000000Z\",\n      \"properties\": {}\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2\n}"}]},{"name":"Get Receipt Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]},"description":"Returns paginated inventory movements scoped to the given warehouse transfer receipt. Includes movement type, quantity, FIFO layer link, unit/total cost, and product/warehouse references for each movement. Used by the Movements tab on the receipt detail page.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88012,\n      \"type\": \"receipt\",\n      \"inventory_status\": \"available\",\n      \"quantity\": 28,\n      \"reference\": \"WT-2025-0042\",\n      \"link_type\": \"App\\\\Models\\\\WarehouseTransferShipmentReceiptLine\",\n      \"link_id\": 5001,\n      \"parent_link_id\": 301,\n      \"detail_link_id\": null,\n      \"product_id\": 812,\n      \"product_sku\": \"WIDGET-BLU\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 12,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 4.5,\n      \"unit_cost_provisional\": false,\n      \"total_cost\": 126,\n      \"layer\": {\n        \"name\": \"FIFO Layer #44021\",\n        \"layer_type\": \"App\\\\Models\\\\FifoLayer\",\n        \"layer_id\": 44021\n      },\n      \"inventory_movement_date\": \"2025-04-13T09:30:00.000000Z\",\n      \"created_at\": \"2025-04-13T09:30:01.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Get Receipt FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/fifo-layers?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]},"description":"Returns paginated FIFO layers created by the given warehouse transfer receipt. Each layer includes original/available quantity, average unit cost, total cost, polymorphic source link, and product/warehouse references. Used by the FIFO Layers tab on the receipt detail page.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/warehouse-transfers/receipts/{receipt}/fifo-layers?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","v2","warehouse-transfers","receipts",":receipt","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default 25)","disabled":true}],"variable":[{"key":"receipt","value":"301","description":"Receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 44021,\n      \"fifo_layer_date\": \"2025-04-13T09:30:00.000000Z\",\n      \"quantity\": 28,\n      \"fulfilled_quantity\": 0,\n      \"available_quantity\": 28,\n      \"unit_cost\": 4.5,\n      \"total_cost\": 126,\n      \"product_id\": 812,\n      \"product_sku\": \"WIDGET-BLU\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 12,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"source_type\": \"Warehouse Transfer Receipt Line\",\n      \"source_reference\": \"WT-2025-0042\",\n      \"link_type\": \"App\\\\Models\\\\WarehouseTransferShipmentReceiptLine\",\n      \"link_id\": 5001,\n      \"parent_link_id\": 301,\n      \"detail_link_id\": null,\n      \"condition\": \"new\",\n      \"created_at\": \"2025-04-13T09:30:01.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Receive Warehouse Transfer Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receive"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Records a receipt against a shipped warehouse transfer, adding the received quantities to stock at the destination warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: products (required array of {id: warehouse transfer line ID, quantity, shipment_line_id}), shipment_id (the shipment being received), receipt_date (defaults to now), blemished (array of {product_id, sku, quantity, condition, reference} - received units in damaged condition are booked in as a new blemished product with the given SKU), condition and integration_unique_id.\n\nThe transfer must be open, and received quantities cannot exceed shipped quantities.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipment_id\": 204,\n  \"receipt_date\": \"2026-06-10 09:00:00\",\n  \"products\": [\n    {\n      \"id\": 9001,\n      \"quantity\": 60,\n      \"shipment_line_id\": 3301\n    }\n  ],\n  \"blemished\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receive"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer shipment receipt created successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Update Warehouse Transfer Receipt","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts",":receipt"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"receipt","value":"31","description":"Receipt ID"}]},"description":"Updates a previously recorded receipt, adjusting received quantities.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: receipt_date (date, not in the future), products (required array of {id: product ID, quantity}) and blemished (array of {product_id, sku, quantity, condition, reference}).\n\nTotal received per product cannot exceed the total shipped quantity, and the transfer must be open.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"receipt_date\": \"2026-06-10 09:00:00\",\n  \"products\": [\n    {\n      \"id\": 101,\n      \"quantity\": 80\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts",":receipt"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"receipt","value":"31","description":"Receipt ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer shipment receipt updated successfully.\"\n}"}]},{"name":"Delete Warehouse Transfer Receipt","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts",":receipt"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"receipt","value":"31","description":"Receipt ID"}]},"description":"Deletes a receipt from the warehouse transfer, removing the received stock from the destination warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the received stock has already been consumed downstream; the response lists the blocking lines. Returns 400 when the transfer is not open.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","receipts",":receipt"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"receipt","value":"31","description":"Receipt ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer shipment receipt 31 deleted successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Open Warehouse Transfer","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/open","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","open"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Opens a draft warehouse transfer, making it active. Opening validates that the transfer has line items and allocates stock at the source warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOptionally accepts the same fields as Update Warehouse Transfer to apply changes while opening, plus force_shipment (boolean) to immediately create a shipment for the full quantities.\n\nReturns 400 when the transfer is already open, has no products, or stock is insufficient.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"force_shipment\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/open","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","open"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer opened successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Revert Warehouse Transfer to Draft","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/draft","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","draft"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Reverts an open warehouse transfer back to draft status, releasing allocated stock.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 400 when stock received by this transfer has already been consumed downstream, or when an Amazon FBA transfer still has shipments or pending inbound records (delete the shipments first).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/draft","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","draft"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer reverted to draft successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Close Warehouse Transfer Draft","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/close-draft","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","close-draft"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Closes a draft warehouse transfer, marking it closed without moving any stock.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/close-draft","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","close-draft"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer closed successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Mark Warehouse Transfer as Shipped","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","mark-as-shipped"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Marks an Amazon FBA inbound warehouse transfer as shipped, recording the shipment with Amazon inbound processing (including shortage handling and status updates).\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOnly valid for transfers whose destination is an Amazon FBA warehouse with a linked Amazon inbound shipment. Fields: shipment_date (Y-m-d, not in the future) and tracking_number (both optional).\n\nReturns 422 when the transfer is not an FBA transfer or has already been marked as shipped.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2026-06-05\",\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","mark-as-shipped"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Warehouse transfer marked as shipped successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Update Warehouse Transfer Shipment Details","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/update-shipment","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","update-shipment"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Updates the shipped date and tracking number of an Amazon FBA warehouse transfer after it has been shipped.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: shipment_date (Y-m-d, not in the future) and tracking_number (both optional).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2026-06-06\",\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/update-shipment","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","update-shipment"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Warehouse transfer shipment details updated successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Send Warehouse Transfer ASN","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/asn","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","asn"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Sends (or resends) an Advance Shipment Notice email for the transfer to its destination third-party logistics (3PL) warehouse.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe destination warehouse must be of type 3pl and have an email address on its address record; otherwise a 422 is returned.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/asn","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","asn"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"ASN email sent successfully.\"\n}"}]},{"name":"Archive Warehouse Transfer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/archive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","archive"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Archives a warehouse transfer, hiding it from active listings.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/archive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","archive"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer 512 archived successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Unarchive Warehouse Transfer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/unarchived","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","unarchived"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Restores an archived warehouse transfer to active status.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/unarchived","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","unarchived"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"warehouse transfer 512 unarchived successfully.\",\n  \"data\": {\n    \"id\": 512,\n    \"transfer_type\": \"standard\",\n    \"warehouse_transfer_number\": \"WT-000512\",\n    \"transfer_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"from_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"integration_instance_id\": null\n    },\n    \"to_warehouse\": {\n      \"id\": 5,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\"\n    },\n    \"status\": \"open\",\n    \"shipment_status\": \"unshipped\",\n    \"shipment_id\": null,\n    \"receipt_status\": \"unreceived\",\n    \"fully_shipped_at\": null,\n    \"fully_received_at\": null,\n    \"eta\": \"2026-06-15\",\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-02T08:30:00.000000Z\",\n    \"archived_at\": null,\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"WIDGET-001\",\n    \"asn_last_sent_at\": null\n  }\n}"}]},{"name":"Bulk Archive Warehouse Transfers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/archive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","archive"]},"description":"Archives multiple warehouse transfers. Provide either ids (array of transfer IDs) or apply_to_all=true with an optional filters object to target all transfers matching the current listing filters.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    512,\n    513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/archive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 2,\n    \"failCount\": 0\n  },\n  \"message\": \"2 records processed successfully.\"\n}"}]},{"name":"Bulk Unarchive Warehouse Transfers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/unarchive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","unarchive"]},"description":"Restores multiple archived warehouse transfers. Provide either ids (array of transfer IDs) or apply_to_all=true with an optional filters object.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    512,\n    513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/unarchive","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalCount\": 2,\n    \"failCount\": 0\n  },\n  \"message\": \"2 records processed successfully.\"\n}"}]},{"name":"Check Warehouse Transfers Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/deletable","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","deletable"]},"description":"Checks whether the given warehouse transfers can be deleted. Each result includes deletable (boolean) and reason (why deletion is blocked, or null). A transfer is not deletable when stock it received has already been consumed downstream.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    512,\n    513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/deletable","host":["{{baseUrl}}"],"path":["api","warehouses","transfers","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 513,\n      \"deletable\": false,\n      \"reason\": \"Received stock has been consumed by later movements\"\n    }\n  ]\n}"}]},{"name":"List Warehouse Transfer Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Returns the transfer's notes with their authors, newest first, paginated.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 15,\n      \"note\": \"Carrier pickup confirmed for Friday.\",\n      \"is_pinned\": false,\n      \"notable_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n      \"notable_id\": 512,\n      \"user_id\": 4,\n      \"user\": {\n        \"id\": 4,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2026-06-03T15:20:00.000000Z\",\n      \"updated_at\": \"2026-06-03T15:20:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/warehouses/transfers/512/notes?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/warehouses/transfers/512/notes?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/warehouses/transfers/512/notes\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Add Warehouse Transfer Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Adds a note to the warehouse transfer. Fields: note (required).\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"note\": \"Carrier pickup confirmed for Friday.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note created successfully.\",\n  \"data\": {\n    \"id\": 15,\n    \"note\": \"Carrier pickup confirmed for Friday.\",\n    \"is_pinned\": false,\n    \"notable_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n    \"notable_id\": 512,\n    \"user_id\": 4,\n    \"user\": {\n      \"id\": 4,\n      \"name\": \"Jane Smith\"\n    },\n    \"created_at\": \"2026-06-03T15:20:00.000000Z\",\n    \"updated_at\": \"2026-06-03T15:20:00.000000Z\"\n  }\n}"}]},{"name":"Toggle Warehouse Transfer Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes",":noteId","toggle-pin"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"noteId","value":"15","description":"Note ID"}]},"description":"Pins or unpins a note on the warehouse transfer. Pinned notes surface at the top of the notes list.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes",":noteId","toggle-pin"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"noteId","value":"15","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Note pinned\",\n  \"data\": {\n    \"id\": 15,\n    \"note\": \"Carrier pickup confirmed for Friday.\",\n    \"is_pinned\": true,\n    \"notable_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n    \"notable_id\": 512,\n    \"user_id\": 4,\n    \"user\": {\n      \"id\": 4,\n      \"name\": \"Jane Smith\"\n    },\n    \"created_at\": \"2026-06-03T15:20:00.000000Z\",\n    \"updated_at\": \"2026-06-03T15:20:00.000000Z\"\n  }\n}"}]},{"name":"Delete Warehouse Transfer Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes",":noteId"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"noteId","value":"15","description":"Note ID"}]},"description":"Deletes a note from the warehouse transfer.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","notes",":noteId"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"noteId","value":"15","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 15 deleted successfully.\"\n}"}]},{"name":"Create Warehouse Transfer Bill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Creates a supplier bill linked to the warehouse transfer, capturing third-party costs such as freight.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: supplier_id (required), invoice_number (required, unique), invoice_date (required), currency_id, currency_rate, lines (array of {description, quantity, amount, nominal_code_id, tax_rate_id, cost_category_id}), allocations (array of {warehouse_transfer_line_id, allocation_amount, proration_strategy} - must not exceed the bill total) and proration_strategy (required - how unallocated cost is distributed: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 3,\n  \"invoice_number\": \"INV-2026-0142\",\n  \"invoice_date\": \"2026-06-05\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"quantity_based\",\n  \"lines\": [\n    {\n      \"description\": \"Ocean freight\",\n      \"quantity\": 1,\n      \"amount\": 350,\n      \"nominal_code_id\": 15\n    }\n  ],\n  \"allocations\": [\n    {\n      \"warehouse_transfer_line_id\": 9001,\n      \"allocation_amount\": 350\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 77,\n    \"supplier_id\": 3,\n    \"invoice_number\": \"INV-2026-0142\",\n    \"invoice_date\": \"2026-06-05\",\n    \"link_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n    \"link_id\": 512,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"quantity_based\",\n    \"total\": 350,\n    \"created_at\": \"2026-06-05T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-05T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Get Warehouse Transfer Bill","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills",":bill"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"bill","value":"77","description":"Bill ID"}]},"description":"Returns a bill linked to the warehouse transfer. Responds 404 when the bill does not belong to this transfer.\n\n**Required scope: `warehouses:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills",":bill"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"bill","value":"77","description":"Bill ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 77,\n    \"supplier_id\": 3,\n    \"invoice_number\": \"INV-2026-0142\",\n    \"invoice_date\": \"2026-06-05\",\n    \"link_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n    \"link_id\": 512,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"quantity_based\",\n    \"total\": 350,\n    \"created_at\": \"2026-06-05T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-05T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Warehouse Transfer Bill","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills",":bill"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"bill","value":"77","description":"Bill ID"}]},"description":"Updates a bill linked to the warehouse transfer.\n\n**Required scope: `warehouses:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: invoice_number (required), invoice_date (required), supplier_id (required), currency_id, currency_rate, proration_strategy and allocations (array of {warehouse_transfer_line_id, allocation_amount, proration_strategy} - must not exceed the bill total). Responds 404 when the bill does not belong to this transfer.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 3,\n  \"invoice_number\": \"INV-2026-0142\",\n  \"invoice_date\": \"2026-06-05\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"quantity_based\",\n  \"allocations\": [\n    {\n      \"warehouse_transfer_line_id\": 9001,\n      \"allocation_amount\": 350\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/warehouses/transfers/{transfer}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","warehouses","transfers",":transfer","bills",":bill"],"variable":[{"key":"transfer","value":"512","description":"Warehouse transfer ID"},{"key":"bill","value":"77","description":"Bill ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 77,\n    \"supplier_id\": 3,\n    \"invoice_number\": \"INV-2026-0142\",\n    \"invoice_date\": \"2026-06-05\",\n    \"link_type\": \"App\\\\Models\\\\WarehouseTransfer\",\n    \"link_id\": 512,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"quantity_based\",\n    \"total\": 350,\n    \"created_at\": \"2026-06-05T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-05T12:00:00.000000Z\"\n  }\n}"}]},{"name":"List Location Transfers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/location-transfers","host":["{{baseUrl}}"],"path":["api","v2","location-transfers"]},"description":"Paginated history of location transfers (put-aways and relocations).\n\nAuthentication: Requires Bearer token.\n\nSearch: filter[search] matches transfer number, notes, warehouse name, and performing user's name; narrow with search_columns.\n\nOperator-aware filters: filter[number], filter[notes] (text), filter[id] (numeric), filter[completed_at], filter[created_at] (datetime). Each supports a bare implicit-is form (filter[number]=LT-000012) and an operator form (filter[number.contains]=LT). Text operators: is, is_not, contains, does_not_contain, starts_with, does_not_start_with, ends_with, does_not_end_with, is_one_of, is_not_one_of, is_empty, is_not_empty. Numeric operators: is, is_not, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_one_of, is_not_one_of, is_empty, is_not_empty. Datetime operators: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty.\n\nExact filters: filter[warehouse_id], filter[reason] (put_away | relocation), filter[product_id] (matches transfers containing a line for the product), filter[performed_by_user_id], filter[date_from] / filter[date_to] (date range on completion date, Y-m-d).\n\nfilter_groups accepts a base64-encoded JSON tree of AND/OR advanced filter groups and takes precedence over individual filter params.\n\nAllowed sorts: id, number, reason, completed_at, created_at (default -completed_at).\n\nEach row includes the warehouse, the performing user, and a lines_count. Line detail is returned by the single-transfer endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/location-transfers","host":["{{baseUrl}}"],"path":["api","v2","location-transfers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"number\": \"LT-000012\",\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"reason\": \"put_away\",\n      \"reason_label\": \"Put Away\",\n      \"notes\": \"Morning put-away from receiving dock\",\n      \"performed_by\": {\n        \"id\": 5,\n        \"name\": \"Jane Smith\"\n      },\n      \"completed_at\": \"2026-07-07T15:04:12.000000Z\",\n      \"lines_count\": 2,\n      \"created_at\": \"2026-07-07T15:04:12.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/v2/location-transfers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/v2/location-transfers?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/v2/location-transfers\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Location Transfer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/location-transfers","host":["{{baseUrl}}"],"path":["api","v2","location-transfers"]},"description":"Execute a location transfer atomically: the document is created, completed, and paired reclassification inventory movements are written per line (-quantity at the from-location, +quantity at the to-location) in a single transaction. Location transfers never affect costing or warehouse-level availability.\n\nAuthentication: Requires Bearer token.\n\nRules:\n- warehouse_id (required, integer): warehouse with locations enabled — returns 422 otherwise\n- reason (required, string): put_away or relocation\n- notes (optional, string)\n- lines (required, array, min 1)\n- lines[].product_id (required, integer)\n- lines[].from_warehouse_location_id (required, integer): must belong to the warehouse\n- lines[].to_warehouse_location_id (required, integer): must belong to the warehouse, differ from the from-location, and not be deprecated\n- lines[].quantity (required, number, > 0): the from-location balance must cover the total requested quantity across all lines drawing from the same product and location — returns 422 naming the available quantity otherwise\n\n**Requires permission:** `inventory.transfer`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"reason\": \"put_away\",\n  \"notes\": \"Morning put-away from receiving dock\",\n  \"lines\": [\n    {\n      \"product_id\": 42,\n      \"from_warehouse_location_id\": 7,\n      \"to_warehouse_location_id\": 15,\n      \"quantity\": 100\n    },\n    {\n      \"product_id\": 58,\n      \"from_warehouse_location_id\": 7,\n      \"to_warehouse_location_id\": 18,\n      \"quantity\": 24\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/location-transfers","host":["{{baseUrl}}"],"path":["api","v2","location-transfers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"number\": \"LT-000012\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"reason\": \"put_away\",\n    \"reason_label\": \"Put Away\",\n    \"notes\": \"Morning put-away from receiving dock\",\n    \"performed_by\": {\n      \"id\": 5,\n      \"name\": \"Jane Smith\"\n    },\n    \"completed_at\": \"2026-07-07T15:04:12.000000Z\",\n    \"lines_count\": 2,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"product_id\": 42,\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"SKU-ABC-123\",\n          \"name\": \"Blue Widget 500ml\"\n        },\n        \"from_location\": {\n          \"id\": 7,\n          \"code\": \"RECEIVING\",\n          \"name\": \"Receiving\",\n          \"type\": \"staging\",\n          \"type_label\": \"Staging\"\n        },\n        \"to_location\": {\n          \"id\": 15,\n          \"code\": \"A-01-2-B\",\n          \"name\": null,\n          \"type\": \"storage\",\n          \"type_label\": \"Storage\"\n        },\n        \"quantity\": 100\n      },\n      {\n        \"id\": 32,\n        \"product_id\": 58,\n        \"product\": {\n          \"id\": 58,\n          \"sku\": \"SKU-DEF-456\",\n          \"name\": \"Red Widget 250ml\"\n        },\n        \"from_location\": {\n          \"id\": 7,\n          \"code\": \"RECEIVING\",\n          \"name\": \"Receiving\",\n          \"type\": \"staging\",\n          \"type_label\": \"Staging\"\n        },\n        \"to_location\": {\n          \"id\": 18,\n          \"code\": \"A-02-1-A\",\n          \"name\": null,\n          \"type\": \"storage\",\n          \"type_label\": \"Storage\"\n        },\n        \"quantity\": 24\n      }\n    ],\n    \"created_at\": \"2026-07-07T15:04:12.000000Z\"\n  },\n  \"message\": \"Location transfer LT-000012 completed.\"\n}"}]},{"name":"Get Location Transfer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/location-transfers/{locationTransfer}","host":["{{baseUrl}}"],"path":["api","v2","location-transfers",":locationTransfer"],"variable":[{"key":"locationTransfer","value":"12","description":"Location transfer ID"}]},"description":"Retrieve a single location transfer with its lines. Each line includes the product and the from/to locations.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/location-transfers/{locationTransfer}","host":["{{baseUrl}}"],"path":["api","v2","location-transfers",":locationTransfer"],"variable":[{"key":"locationTransfer","value":"12","description":"Location transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"number\": \"LT-000012\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"reason\": \"put_away\",\n    \"reason_label\": \"Put Away\",\n    \"notes\": \"Morning put-away from receiving dock\",\n    \"performed_by\": {\n      \"id\": 5,\n      \"name\": \"Jane Smith\"\n    },\n    \"completed_at\": \"2026-07-07T15:04:12.000000Z\",\n    \"lines_count\": 2,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"product_id\": 42,\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"SKU-ABC-123\",\n          \"name\": \"Blue Widget 500ml\"\n        },\n        \"from_location\": {\n          \"id\": 7,\n          \"code\": \"RECEIVING\",\n          \"name\": \"Receiving\",\n          \"type\": \"staging\",\n          \"type_label\": \"Staging\"\n        },\n        \"to_location\": {\n          \"id\": 15,\n          \"code\": \"A-01-2-B\",\n          \"name\": null,\n          \"type\": \"storage\",\n          \"type_label\": \"Storage\"\n        },\n        \"quantity\": 100\n      },\n      {\n        \"id\": 32,\n        \"product_id\": 58,\n        \"product\": {\n          \"id\": 58,\n          \"sku\": \"SKU-DEF-456\",\n          \"name\": \"Red Widget 250ml\"\n        },\n        \"from_location\": {\n          \"id\": 7,\n          \"code\": \"RECEIVING\",\n          \"name\": \"Receiving\",\n          \"type\": \"staging\",\n          \"type_label\": \"Staging\"\n        },\n        \"to_location\": {\n          \"id\": 18,\n          \"code\": \"A-02-1-A\",\n          \"name\": null,\n          \"type\": \"storage\",\n          \"type_label\": \"Storage\"\n        },\n        \"quantity\": 24\n      }\n    ],\n    \"created_at\": \"2026-07-07T15:04:12.000000Z\"\n  }\n}"}]},{"name":"Get Put-Away Queue","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/put-away/queue","host":["{{baseUrl}}"],"path":["api","v2","put-away","queue"]},"description":"Paginated put-away queue: stock with a positive balance sitting in put-away-from locations (staging, returns, quarantine, damaged) — plus the Unassigned location when include_unassigned is truthy (default). Each row is decorated with the product's suggested destination bin (its preferred default storage location for the warehouse, when one is set and not deprecated).\n\nAuthentication: Requires Bearer token.\n\nSearch: filter[search] matches product SKU, product name, and location code; narrow with search_columns.\n\nOperator-aware filters: filter[sku], filter[name], filter[location_code] (text) and filter[quantity] (numeric). Each supports a bare implicit-is form and an operator form (filter[quantity.greater_than]=50). Text operators: is, is_not, contains, does_not_contain, starts_with, does_not_start_with, ends_with, does_not_end_with, is_one_of, is_not_one_of, is_empty, is_not_empty. Numeric operators: is, is_not, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_one_of, is_not_one_of, is_empty, is_not_empty.\n\nfilter[warehouse_id] filters to one warehouse (exact match). include_unassigned toggles the Unassigned location. filter_groups accepts a base64-encoded JSON tree of AND/OR advanced filter groups and takes precedence over individual filter params.\n\nAllowed sorts: product (SKU), location (code), quantity. Default order: location code, then product SKU.\n\nCreate a location transfer with reason put_away to work rows off the queue."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/put-away/queue","host":["{{baseUrl}}"],"path":["api","v2","put-away","queue"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 42,\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"SKU-ABC-123\",\n        \"name\": \"Blue Widget 500ml\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 7,\n      \"location\": {\n        \"id\": 7,\n        \"code\": \"RECEIVING\",\n        \"name\": \"Receiving\",\n        \"type\": \"staging\",\n        \"type_label\": \"Staging\"\n      },\n      \"quantity\": 100,\n      \"suggested_location\": {\n        \"id\": 15,\n        \"code\": \"A-01-2-B\"\n      }\n    },\n    {\n      \"product_id\": 77,\n      \"product\": {\n        \"id\": 77,\n        \"sku\": \"SKU-GHI-789\",\n        \"name\": \"Green Gadget XL\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse_location_id\": 2,\n      \"location\": {\n        \"id\": 2,\n        \"code\": \"UNASSIGNED\",\n        \"name\": \"Unassigned\",\n        \"type\": \"storage\",\n        \"type_label\": \"Storage\"\n      },\n      \"quantity\": 950,\n      \"suggested_location\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/v2/put-away/queue?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/v2/put-away/queue?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/v2/put-away/queue\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]}]},{"name":"Stock Takes","item":[{"name":"List Stock Takes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/list?filter[status]=open&filter[mode]=full_count&filter[warehouse]=1&filter[archived]=none&filter[variance_direction]=positive&filter[is_initial_count]=&filter[date_count]=&filter[value_change]=&filter[notes]=&filter[id]=&search=&sort=-id&per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","stock-takes","list"],"query":[{"key":"filter[status]","value":"open","description":"Optional. Filter by status: draft, open, closed.","disabled":true},{"key":"filter[mode]","value":"full_count","description":"Optional. Filter by mode: full_count, adjustment.","disabled":true},{"key":"filter[warehouse]","value":"1","description":"Optional. Filter by warehouse ID.","disabled":true},{"key":"filter[archived]","value":"none","description":"Optional. archived filter: none (default, non-archived only), only (archived only), all (all records).","disabled":true},{"key":"filter[variance_direction]","value":"positive","description":"Optional. Filter by variance direction: positive, negative, neutral.","disabled":true},{"key":"filter[is_initial_count]","value":"","description":"Optional. Filter by initial count (1 or 0).","disabled":true},{"key":"filter[date_count]","value":"","description":"Optional. Filter by count date.","disabled":true},{"key":"filter[value_change]","value":"","description":"Optional. Filter by value change amount.","disabled":true},{"key":"filter[notes]","value":"","description":"Optional. Filter by notes (partial match).","disabled":true},{"key":"filter[id]","value":"","description":"Optional. Filter by ID.","disabled":true},{"key":"search","value":"","description":"Optional. Search by ID, notes, or warehouse name.","disabled":true},{"key":"sort","value":"-id","description":"Optional. Sort field (prefix - for descending). Allowed: id, date_count, status, value_change, variance_direction, created_at, updated_at.","disabled":true},{"key":"per_page","value":"10","description":"Optional. Items per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Optional. Page number.","disabled":true}]},"description":"Get paginated stock takes with filtering, sorting and search. Uses Spatie QueryBuilder + GroupedFilterSupport.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilter columns available: id, status, mode, warehouse (ID), is_initial_count, variance_direction, notes, date_count, created_at, updated_at, value_change.\n\nArchived filter: none=non-archived only (default), only=archived only, all=all records.\n\nAllowed sorts: id, date_count, status, value_change, variance_direction, created_at, updated_at. Default sort: -id.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/list?filter[status]=open&filter[mode]=full_count&filter[warehouse]=1&filter[archived]=none&filter[variance_direction]=positive&filter[is_initial_count]=&filter[date_count]=&filter[value_change]=&filter[notes]=&filter[id]=&search=&sort=-id&per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","stock-takes","list"],"query":[{"key":"filter[status]","value":"open","description":"Optional. Filter by status: draft, open, closed.","disabled":true},{"key":"filter[mode]","value":"full_count","description":"Optional. Filter by mode: full_count, adjustment.","disabled":true},{"key":"filter[warehouse]","value":"1","description":"Optional. Filter by warehouse ID.","disabled":true},{"key":"filter[archived]","value":"none","description":"Optional. archived filter: none (default, non-archived only), only (archived only), all (all records).","disabled":true},{"key":"filter[variance_direction]","value":"positive","description":"Optional. Filter by variance direction: positive, negative, neutral.","disabled":true},{"key":"filter[is_initial_count]","value":"","description":"Optional. Filter by initial count (1 or 0).","disabled":true},{"key":"filter[date_count]","value":"","description":"Optional. Filter by count date.","disabled":true},{"key":"filter[value_change]","value":"","description":"Optional. Filter by value change amount.","disabled":true},{"key":"filter[notes]","value":"","description":"Optional. Filter by notes (partial match).","disabled":true},{"key":"filter[id]","value":"","description":"Optional. Filter by ID.","disabled":true},{"key":"search","value":"","description":"Optional. Search by ID, notes, or warehouse name.","disabled":true},{"key":"sort","value":"-id","description":"Optional. Sort field (prefix - for descending). Allowed: id, date_count, status, value_change, variance_direction, created_at, updated_at.","disabled":true},{"key":"per_page","value":"10","description":"Optional. Items per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Optional. Page number.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"date_count\": \"2024-10-10T00:00:00+00:00\",\n      \"is_initial_count\": false,\n      \"condition\": null,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"standard\",\n        \"country_code\": \"US\"\n      },\n      \"mode\": \"full_count\",\n      \"status\": \"open\",\n      \"value_change\": null,\n      \"variance_direction\": null,\n      \"notes\": \"Q4 annual count\",\n      \"created_at\": \"2024-10-08T09:00:00+00:00\",\n      \"updated_at\": \"2024-10-10T14:00:00+00:00\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28\n}"}]},{"name":"Search Stock Takes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/list","host":["{{baseUrl}}"],"path":["api","stock-takes","list"]},"description":"Returns the same paginated list of stock takes as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`. A free-text `search` term matches against the stock take id, notes, and warehouse name.\n\nText columns (`status`, `mode`, `variance_direction`, `notes`, `warehouse`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric, boolean and date columns (`id`, `value_change`, `is_initial_count`, `date_count`, `created_at`, `updated_at`, `archived`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, date_count, status, value_change, variance_direction, created_at, updated_at. Results default to `-id`.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-date_count\",\n  \"search\": \"\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"status\",\n          \"operator\": \"is\",\n          \"value\": \"completed\"\n        }\n      },\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"variance_direction\",\n          \"operator\": \"is\",\n          \"value\": \"negative\"\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/list","host":["{{baseUrl}}"],"path":["api","stock-takes","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 812,\n      \"date_count\": \"2026-06-28\",\n      \"is_initial_count\": false,\n      \"condition\": \"new\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"standard\",\n        \"country_code\": \"US\"\n      },\n      \"mode\": \"full\",\n      \"status\": \"completed\",\n      \"value_change\": -184.5,\n      \"variance_direction\": \"negative\",\n      \"notes\": \"Quarterly cycle count\",\n      \"created_at\": \"2026-06-28T09:12:00.000000Z\",\n      \"updated_at\": \"2026-06-28T15:41:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 4,\n  \"total\": 92,\n  \"next_page_url\": \"https://api.example.com/api/stock-takes/list?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Get Stock Take","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"42","description":"Stock take ID"}]},"description":"Get a single stock take with full details including items, warehouse, parent and child stock takes.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nLoads: warehouse, stockTakeItems (with inventoryMovements.fifoLayer for closed takes), parentStockTake, childStockTakes.\n\nResponse includes `deletable` (boolean) and `delete_blocked_reasons` (string[]): a draft/open stock take is always deletable; a closed stock take is deletable only when none of its FIFO cost layers have been consumed (otherwise `deletable` is false and `delete_blocked_reasons` lists the blocking stock take items).\n\nThe stock take exposes `is_blind`. For a blind count, items that have not yet been counted return null `snapshot_inventory` / `snapshot_available` / `snapshot_reserved` / `snapshot_committed_to_fulfillment` until they are counted. Each item also exposes its `variance_reason` (root-cause code, or null)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"date_count\": \"2024-10-10T00:00:00+00:00\",\n    \"is_initial_count\": false,\n    \"is_blind\": false,\n    \"condition\": null,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"country_code\": \"US\"\n    },\n    \"mode\": \"full_count\",\n    \"status\": \"open\",\n    \"deletable\": true,\n    \"delete_blocked_reasons\": [],\n    \"value_change\": null,\n    \"variance_direction\": null,\n    \"notes\": \"Q4 annual count\",\n    \"parent_stock_take\": null,\n    \"child_stock_takes\": [],\n    \"items\": [\n      {\n        \"id\": 101,\n        \"item_product_id\": 55,\n        \"item_sku\": \"PROD-55\",\n        \"item_name\": \"Widget\",\n        \"warehouse_id\": 2,\n        \"snapshot_inventory\": 100,\n        \"qty_counted\": 98,\n        \"variance_reason\": \"shrinkage\",\n        \"unit_cost\": 12.5,\n        \"is_lot_tracked\": true,\n        \"lot_tracking_method\": \"fefo\",\n        \"shelf_life_days\": 365,\n        \"near_expiry_threshold_days\": 30,\n        \"min_remaining_shelf_life_days\": 90,\n        \"lot_allocation\": [\n          {\n            \"fifo_layer_id\": 7101,\n            \"quantity\": 2\n          }\n        ],\n        \"lots\": [\n          {\n            \"fifo_layer_id\": 7101,\n            \"batch_number\": \"LOT-2026-0042\",\n            \"expiry_date\": \"2026-07-04\",\n            \"manufacture_date\": \"2026-01-04\",\n            \"lot_notes\": null,\n            \"quantity\": 50\n          }\n        ]\n      }\n    ],\n    \"during_count_movement_count\": 3,\n    \"created_at\": \"2024-10-08T09:00:00+00:00\",\n    \"updated_at\": \"2024-10-10T14:00:00+00:00\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Stock Take","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"42","description":"Stock take ID"}]},"description":"Update a stock take and its line items. Handles adding, updating, and removing items.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nitems: each item accepts product_id (required, must exist), qty_counted (numeric, min 0), unit_cost (optional numeric, min 0 — an explicit 0 is valid and preserved), to_delete (boolean, removes the line).\n\nitems[].lots (array, optional): lot/batch rows for newly found (POSITIVE variance) stock on a lot-tracked product — each row becomes its own FIFO layer. For lot-tracked products every supplied lot must carry batch_number and expiry_date. Fields: batch_number, expiry_date, manufacture_date, quantity, lot_notes.\n\nitems[].lot_allocation (array, optional): per-item FEFO override for a NEGATIVE variance (a consume — counted qty lower than the system snapshot) on a lot-tracked product. When supplied, the named FIFO layers are drawn down at finalize instead of automatic FEFO/FIFO; when omitted the consume falls back to automatic FEFO exactly as before. Each row is `{ fifo_layer_id (integer, must exist in fifo_layers), quantity (numeric, > 0) }`, and the allocation quantities must sum to abs(variance) (the snapshot − counted shortfall). The tenant setting `inventory.lot_override_policy` (off | warn | enforce) governs the override — under enforce an allocation selecting expired or non-FEFO (out-of-order) layers is rejected.\n\ndate_count (date, optional): re-dating a finalized (closed) stock take moves its initial positive inventory movement and FIFO cost-layer date; on the next accounting sync this also re-dates the journal entry (TxnDate). Initial counts cannot be re-dated.\n\nreallocate_usages (boolean, optional): when true AND the date changed, dispatches a tracked FIFO reallocation that replays historical consumption against the re-ordered layers so each past usage consumes the correct layers in FIFO order, recomputes COGS, and propagates it to documents and accounting. When dispatched, the response includes `reallocation_tracked_job_id` to follow via the tracked job log endpoints. Preview the impact first via the reallocation-preview endpoint.\n\nReturns 400 if: the stock take is closed and the request attempts to change quantities; an adjustment-mode item cannot be modified; the new (or current) date_count falls on or before the accounting lock date; or the reallocation would change COGS on a consumption dated inside a locked accounting period.\n\nResponse includes `deletable` (boolean) and `delete_blocked_reasons` (string[]).\n\n**Requires permission:** `inventory.count`\n\nEach item may carry `variance_reason` — a root-cause code for the count variance. One of: receiving_error, picking_error, damage, mislabel, shrinkage, unknown.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Updated notes for Q4 count\",\n  \"date_count\": \"2024-10-11\",\n  \"reallocate_usages\": true,\n  \"items\": [\n    {\n      \"product_id\": 55,\n      \"qty_counted\": 99,\n      \"snapshot_inventory\": 100,\n      \"unit_cost\": 12.5,\n      \"lots\": [\n        {\n          \"batch_number\": \"LOT-2026-0042\",\n          \"manufacture_date\": \"2026-01-04\",\n          \"expiry_date\": \"2026-07-04\",\n          \"quantity\": 98,\n          \"lot_notes\": \"Newly found lot\"\n        }\n      ]\n    },\n    {\n      \"product_id\": 56,\n      \"qty_counted\": 25,\n      \"snapshot_inventory\": 25\n    },\n    {\n      \"product_id\": 57,\n      \"qty_counted\": 40,\n      \"snapshot_inventory\": 45,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 7101,\n          \"quantity\": 3\n        },\n        {\n          \"fifo_layer_id\": 7102,\n          \"quantity\": 2\n        }\n      ],\n      \"variance_reason\": \"damage\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"notes\": \"Updated notes for Q4 count\",\n    \"status\": \"draft\",\n    \"deletable\": true,\n    \"delete_blocked_reasons\": [],\n    \"items\": [\n      {\n        \"id\": 103,\n        \"item_product_id\": 57,\n        \"item_sku\": \"PROD-57\",\n        \"warehouse_id\": 2,\n        \"snapshot_inventory\": 45,\n        \"qty_counted\": 40,\n        \"variance_reason\": \"damage\",\n        \"is_lot_tracked\": true,\n        \"lot_tracking_method\": \"fefo\",\n        \"lot_allocation\": [\n          {\n            \"fifo_layer_id\": 7101,\n            \"quantity\": 3\n          },\n          {\n            \"fifo_layer_id\": 7102,\n            \"quantity\": 2\n          }\n        ]\n      }\n    ],\n    \"updated_at\": \"2024-10-09T11:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Stock Take","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"43","description":"Stock take ID"}]},"description":"Delete a single stock take.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if the stock take has linked inventory adjustments or FIFO layers that prevent deletion.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/stock-takes/{stock_take}","host":["{{baseUrl}}"],"path":["api","stock-takes",":stock_take"],"variable":[{"key":"stock_take","value":"43","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"stock take 43 deleted successfully\"\n}"}]},{"name":"Search Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/search-products?q=PROD&warehouse_id=2&in_stock_only=0&limit=50","host":["{{baseUrl}}"],"path":["api","stock-takes","search-products"],"query":[{"key":"q","value":"PROD","description":"Optional. Search term (matches SKU, name, barcode).","disabled":true},{"key":"warehouse_id","value":"2","description":"Optional. Warehouse ID to load inventory data for.","disabled":true},{"key":"in_stock_only","value":"0","description":"Optional. 0=all products, 1=only products with stock in warehouse.","disabled":true},{"key":"limit","value":"50","description":"Optional. Max results (1-50, default 50).","disabled":true}]},"description":"Search products for adding to a stock take. Returns standard and kit products only (excludes archived).\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResults are ordered by exact SKU match, then SKU prefix, then barcode, then name.\n\nIf warehouse_id is provided, inventory levels for that warehouse are included."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/search-products?q=PROD&warehouse_id=2&in_stock_only=0&limit=50","host":["{{baseUrl}}"],"path":["api","stock-takes","search-products"],"query":[{"key":"q","value":"PROD","description":"Optional. Search term (matches SKU, name, barcode).","disabled":true},{"key":"warehouse_id","value":"2","description":"Optional. Warehouse ID to load inventory data for.","disabled":true},{"key":"in_stock_only","value":"0","description":"Optional. 0=all products, 1=only products with stock in warehouse.","disabled":true},{"key":"limit","value":"50","description":"Optional. Max results (1-50, default 50).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sku\": \"PROD-001\",\n      \"name\": \"Widget A\",\n      \"barcode\": \"123456789\",\n      \"type\": \"standard\",\n      \"unit_cost\": 12.5,\n      \"inventory_available\": 95,\n      \"inventory_allocated\": 5,\n      \"inventory_on_hold\": 0,\n      \"inventory_total\": 100\n    }\n  ]\n}"}]},{"name":"Resolve SKUs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/resolve-skus","host":["{{baseUrl}}"],"path":["api","stock-takes","resolve-skus"]},"description":"Bulk resolve a list of SKUs or barcodes to products in a single query. Used for importing large stock count sheets.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nMatches against both SKU and barcode columns (case-insensitive). Deduplicates results.\n\nMax 5000 SKUs per request.\n\nReturns found, not_found, and skipped (wrong product type) arrays.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"skus\": [\n    \"PROD-001\",\n    \"PROD-002\",\n    \"123456789\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/resolve-skus","host":["{{baseUrl}}"],"path":["api","stock-takes","resolve-skus"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"found\": [\n    {\n      \"id\": 55,\n      \"sku\": \"PROD-001\",\n      \"name\": \"Widget A\",\n      \"barcode\": \"111111111\",\n      \"type\": \"standard\",\n      \"unit_cost\": 12.5,\n      \"case_quantity\": 12,\n      \"input_sku\": \"PROD-001\",\n      \"is_lot_tracked\": true,\n      \"lot_tracking_method\": \"fifo\",\n      \"shelf_life_days\": 180,\n      \"near_expiry_threshold_days\": 60,\n      \"min_remaining_shelf_life_days\": 105\n    }\n  ],\n  \"not_found\": [\n    \"PROD-999\"\n  ],\n  \"skipped\": []\n}"}]},{"name":"Create Stock Take","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes","host":["{{baseUrl}}"],"path":["api","stock-takes"]},"description":"Create a new stock take.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nstatus: defaults to draft if not provided.\n\ndate_count: defaults to today if not provided.\n\nmode: full_count (default) or adjustment.\n\nis_initial_count: marks this as the first ever count for the warehouse.\n\ncondition: optional condition label (e.g., 'new', 'used').\n\nitems: optional array of stock take line items. Can be added later. Each item: product_id (required, must exist), qty_counted (numeric, min 0), unit_cost (optional numeric, min 0 — an explicit 0 is valid and preserved, it does not fall back to the existing cost).\n\nwarehouse_id must be a standard (non-virtual) warehouse.\n\nResponse includes `deletable` (boolean) and `delete_blocked_reasons` (string[]): a draft/open stock take is always deletable; a closed stock take is deletable only when none of its FIFO cost layers have been consumed (otherwise `deletable` is false and `delete_blocked_reasons` lists the blocking stock take items).\n\n**Requires permission:** `inventory.count`\n\n`is_blind` (optional boolean, default false): a blind cycle count hides the system on-hand for items that have not yet been counted — their `snapshot_inventory`, `snapshot_available`, `snapshot_reserved`, and `snapshot_committed_to_fulfillment` are returned as null so the counter records what they find without anchoring to the expected quantity; once an item is counted the snapshots are revealed for variance review.\n\nEach item may also carry `variance_reason` — a root-cause code for why the counted quantity differs from the system on-hand. One of: receiving_error, picking_error, damage, mislabel, shrinkage, unknown.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 2,\n  \"status\": \"draft\",\n  \"date_count\": \"2024-10-10\",\n  \"mode\": \"full_count\",\n  \"is_initial_count\": false,\n  \"is_blind\": false,\n  \"condition\": null,\n  \"notes\": \"Q4 annual count\",\n  \"items\": [\n    {\n      \"product_id\": 55,\n      \"qty_counted\": 98,\n      \"snapshot_inventory\": 100,\n      \"unit_cost\": 12.5,\n      \"lots\": [\n        {\n          \"batch_number\": \"LOT-2026-0042\",\n          \"manufacture_date\": \"2026-01-04\",\n          \"expiry_date\": \"2026-07-04\",\n          \"quantity\": 98,\n          \"lot_notes\": \"Newly found lot\"\n        }\n      ],\n      \"variance_reason\": \"shrinkage\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes","host":["{{baseUrl}}"],"path":["api","stock-takes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"date_count\": \"2024-10-10T00:00:00+00:00\",\n    \"is_blind\": false,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"mode\": \"full_count\",\n    \"status\": \"draft\",\n    \"deletable\": true,\n    \"delete_blocked_reasons\": [],\n    \"notes\": \"Q4 annual count\",\n    \"items\": [],\n    \"created_at\": \"2024-10-08T09:00:00+00:00\"\n  }\n}"}]},{"name":"Bulk Delete Stock Takes","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes","host":["{{baseUrl}}"],"path":["api","stock-takes"]},"description":"Bulk delete multiple stock takes.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nids: required unless apply_to_all is true.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/stock-takes","host":["{{baseUrl}}"],"path":["api","stock-takes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete completed\",\n  \"deleted_count\": 2\n}"}]},{"name":"Create Stock Take from Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/bulk-insert","host":["{{baseUrl}}"],"path":["api","stock-takes","bulk-insert"]},"description":"Create a new stock take and bulk-insert product IDs as line items in one operation.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nids: array of product IDs to add. Required unless filters is provided.\n\nfilters: alternatively provide list view filters to select products dynamically.\n\nmode: full_count (default) or adjustment.\n\nis_initial_count: optional boolean; forces full_count and flags the take as the warehouse's initial count.\n\nUnit cost: for adjustment mode, each item's unit_cost is pre-seeded from the product's best-available cost at the warehouse (FIFO / weighted-average / catalog unit cost, via GetBestAvailableCogs) so the Unit Cost column opens with a basis rather than blank; null when no cost exists. Overridable per row, and negative adjustments ignore it (cost is taken from consumed FIFO layers at finalization). Full counts are not seeded here — they capture cost at count initiation.\n\nReturns the new stock_take_id.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    55,\n    56,\n    57\n  ],\n  \"warehouse_id\": 2,\n  \"mode\": \"full_count\",\n  \"is_initial_count\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/bulk-insert","host":["{{baseUrl}}"],"path":["api","stock-takes","bulk-insert"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"stock take 44 created successfully\",\n  \"stock_take_id\": 44\n}"}]},{"name":"Check Initial Uniqueness","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/check-initial-uniqueness","host":["{{baseUrl}}"],"path":["api","stock-takes","check-initial-uniqueness"]},"description":"Check if an initial stock take already exists for a warehouse + condition combination.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 2,\n  \"condition\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/check-initial-uniqueness","host":["{{baseUrl}}"],"path":["api","stock-takes","check-initial-uniqueness"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"exists\": true,\n  \"stock_take_id\": 10\n}"}]},{"name":"Initiate Count","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/initiate","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","initiate"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Transition a stock take from Draft to Open status. Takes an inventory snapshot for all items.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nexclude_product_ids: optional array of product IDs to remove before initiating.\n\nis_integrity_fix: if true, marks as integrity fix count.\n\ndate_count: optional retroactive count date (Y-m-d, app timezone, must be today or earlier). Use it when the physical count was performed earlier than it is being entered - the resulting inventory movements, FIFO layers and accounting journal are dated to it (so a historical 'as of' inventory valuation reflects the count), while the snapshot cutoff for reconciling movements made during the count stays at the real initiate moment. Omit to date the count as of now.\n\nReturns 400 if stock take is in adjustment mode (use finalize-adjustment instead), if all items are excluded, or if date_count falls within a locked accounting period. Returns 422 if date_count is in the future.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"exclude_product_ids\": [],\n  \"is_integrity_fix\": false,\n  \"date_count\": \"2026-06-29\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/initiate","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","initiate"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"open\",\n    \"date_count\": \"2024-10-10T09:00:00+00:00\",\n    \"items\": [\n      {\n        \"id\": 101,\n        \"product_id\": 55,\n        \"snapshot_inventory\": 100,\n        \"qty_counted\": 100\n      }\n    ]\n  }\n}"}]},{"name":"Re-Snapshot Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/re-snapshot","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","re-snapshot"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Re-take inventory snapshot for an open stock take. Updates all items' snapshot_inventory to current levels.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/re-snapshot","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","re-snapshot"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"open\"\n  }\n}"}]},{"name":"Zero Out Counted Quantities","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/zero-out","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","zero-out"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Set all counted quantities to zero (or to allocated quantities). Only works for open, non-adjustment stock takes.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nmode values:\n- zero_all: set all items to 0\n- keep_submitted: keep quantities allocated to submitted fulfillments\n- keep_all_allocated: keep quantities reserved for all fulfillments\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"mode\": \"zero_all\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/zero-out","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","zero-out"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"open\",\n    \"items\": [\n      {\n        \"id\": 101,\n        \"qty_counted\": 0\n      }\n    ]\n  }\n}"}]},{"name":"Finalize Stock Take","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/finalize","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","finalize"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Finalize an open stock take. Creates inventory adjustments for all variances and transitions to Closed status.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if protected inventory conflicts exist, insufficient stock, or stock take is not open.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/finalize","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","finalize"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"closed\",\n    \"value_change\": -125,\n    \"variance_direction\": \"negative\",\n    \"updated_at\": \"2024-10-10T16:00:00+00:00\"\n  }\n}"}]},{"name":"Finalize Adjustment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/finalize-adjustment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","finalize-adjustment"],"variable":[{"key":"stockTake","value":"43","description":"Stock take ID (must be adjustment mode)"}]},"description":"Finalize an adjustment mode stock take (goes directly from Draft to Closed, bypassing Open status).\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if stock take is not in adjustment mode.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/finalize-adjustment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","finalize-adjustment"],"variable":[{"key":"stockTake","value":"43","description":"Stock take ID (must be adjustment mode)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"status\": \"closed\",\n    \"mode\": \"adjustment\",\n    \"updated_at\": \"2024-10-10T16:00:00+00:00\"\n  }\n}"}]},{"name":"Revert to Draft","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","revert-to-draft"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Revert an open stock take back to draft status.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","revert-to-draft"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"draft\",\n    \"updated_at\": \"2024-10-09T12:00:00+00:00\"\n  }\n}"}]},{"name":"Reverse Stock Take","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reverse","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reverse"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]},"description":"Reverse a closed stock take, undoing all inventory adjustments.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if reversal is not possible (e.g., FIFO layers already consumed).\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reverse","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reverse"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Stock take reversed successfully.\",\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"closed\"\n  }\n}"}]},{"name":"Get Reconciliation Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconciliation-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconciliation-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Get a preview of what reconciliation will do, including items with conflicts and open fulfillments.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconciliation-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconciliation-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"has_conflicts\": true,\n  \"items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"product_sku\": \"PROD-001\",\n      \"variance\": -2,\n      \"open_fulfillments\": [\n        {\n          \"fulfillment_id\": 500,\n          \"quantity\": 3\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Execute Reconciliation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconcile","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconcile"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Execute reconciliation for an open stock take, handling fulfillment conflicts and applying adjustments.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nfulfillment_ids_to_cancel: optional array of fulfillment IDs to cancel before reconciling.\n\nproceed_despite_failures: if true, continue even if some items fail.\n\nitem_actions: per-item action overrides.\n\nReturns 400 if protected inventory conflicts exist or insufficient inventory.\n\n**Requires permission:** `inventory.count`\n\ndowngraded_allocations: open Allocated reservations that were downgraded to Planned because the counted reduction exceeded the pool's unallocated stock (reconciliation treats the 3PL count as authoritative). Each entry is also written to the reconciliation logs with action `allocation_downgraded`.","body":{"mode":"raw","raw":"{\n  \"fulfillment_ids_to_cancel\": [\n    500\n  ],\n  \"proceed_despite_failures\": false,\n  \"item_actions\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"action\": \"adjust\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconcile","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconcile"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"stock_take_finalized\": true,\n  \"cancelled_fulfillments\": [\n    {\n      \"fulfillment_id\": 500,\n      \"sales_order_reference\": \"SO-1042\"\n    }\n  ],\n  \"failed_cancellations\": [],\n  \"finalization_error\": null,\n  \"total_value_change\": -125.5,\n  \"adjusted_items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"product_sku\": \"WIDGET-1\",\n      \"old_qty_counted\": 10,\n      \"new_qty_counted\": 8\n    }\n  ],\n  \"removed_items\": [],\n  \"backordered_items\": [\n    {\n      \"product_id\": 55,\n      \"product_sku\": \"WIDGET-1\",\n      \"backordered_lines\": 2\n    }\n  ],\n  \"downgraded_allocations\": [\n    {\n      \"allocation_id\": 9912,\n      \"product_id\": 55,\n      \"quantity\": 6,\n      \"link_type\": \"App\\\\Models\\\\SalesOrderLine\",\n      \"link_id\": 33412\n    }\n  ]\n}"}]},{"name":"Get Reconciliation Logs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconciliation-logs","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconciliation-logs"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Get reconciliation log entries for a stock take.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reconciliation-logs","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reconciliation-logs"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 1,\n    \"stock_take_id\": 42,\n    \"stock_take_item_id\": 101,\n    \"action\": \"adjusted\",\n    \"qty_adjusted\": -2,\n    \"created_at\": \"2024-10-10T16:00:00+00:00\"\n  }\n]"}]},{"name":"Cancel Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/cancel-fulfillment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","cancel-fulfillment"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Cancel a single fulfillment as part of reconciliation preparation. Called line-by-line before executeReconciliation.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 200 with success true/false, or 422 if cancellation fails.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"fulfillment_id\": 500\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/cancel-fulfillment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","cancel-fulfillment"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"fulfillment_id\": 500,\n  \"message\": \"Fulfillment cancelled successfully.\"\n}"}]},{"name":"Preview Adjustment Feasibility","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/adjustment-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","adjustment-preview"],"variable":[{"key":"stockTake","value":"43","description":"Stock take ID (must be adjustment mode)"}]},"description":"Get a feasibility preview for each item before finalizing an adjustment mode stock take.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if not an adjustment mode stock take."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/adjustment-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","adjustment-preview"],"variable":[{"key":"stockTake","value":"43","description":"Stock take ID (must be adjustment mode)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"stock_take_item_id\": 201,\n      \"product_sku\": \"PROD-005\",\n      \"adjustment_qty\": -5,\n      \"available_qty\": 20,\n      \"feasible\": true\n    }\n  ]\n}"}]},{"name":"Analyze Reversibility","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reverse-analysis","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reverse-analysis"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]},"description":"Analyze whether a closed stock take can be reversed. Shows which items have consumed FIFO layers.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reverse-analysis","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reverse-analysis"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"can_reverse\": true,\n  \"blocking_items\": [],\n  \"reversible_items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"product_sku\": \"PROD-001\"\n    }\n  ]\n}"}]},{"name":"Create Compensating Adjustment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/compensating-adjustment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","compensating-adjustment"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]},"description":"Create a compensating adjustment stock take for a closed stock take whose FIFO layers have been consumed.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nitems: optional array of item quantity overrides. If omitted, uses original variance quantities.\n\nReturns 400 if compensating adjustment cannot be created.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"adjustment_qty\": -2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/compensating-adjustment","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","compensating-adjustment"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Compensating adjustment created successfully.\",\n  \"data\": {\n    \"id\": 45,\n    \"mode\": \"adjustment\",\n    \"status\": \"draft\"\n  }\n}"}]},{"name":"Preview Cost Correction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/cost-correction-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","cost-correction-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]},"description":"Preview the impact of applying cost corrections to a closed stock take's FIFO layers.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"new_unit_cost\": 13\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/cost-correction-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","cost-correction-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"product_sku\": \"PROD-001\",\n      \"old_unit_cost\": 12.5,\n      \"new_unit_cost\": 13,\n      \"cost_difference\": 0.5,\n      \"affected_layers\": 3\n    }\n  ]\n}"}]},{"name":"Preview FIFO Reallocation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reallocation-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reallocation-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Dry-run the FIFO reallocation that re-dating this stock take to the proposed date would cause, without writing anything. Returns the impact summary: how many outbound usages would be reassigned to different cost layers, the net COGS delta, a per-product breakdown, and whether the change would touch a locked accounting period (in which case the actual re-date is blocked).\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody: date_count (date, required) — the proposed new count date.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"date_count\": \"2024-04-11\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/reallocation-preview","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","reallocation-preview"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"date_count\": \"2024-04-11\",\n    \"locked_period_blocked\": false,\n    \"locked_period_reasons\": [],\n    \"total_reassigned_usages\": 37,\n    \"net_cogs_delta\": 1284.5,\n    \"products\": [\n      {\n        \"product_id\": 55,\n        \"sku\": \"ABC-123\",\n        \"warehouse_id\": 1,\n        \"reassigned_usages\": 22,\n        \"cogs_delta\": 812,\n        \"has_fba_layers\": false\n      }\n    ]\n  }\n}"}]},{"name":"Apply Cost Correction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/apply-cost-correction","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","apply-cost-correction"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]},"description":"Apply cost corrections to a closed stock take's FIFO layers.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"stock_take_item_id\": 101,\n      \"new_unit_cost\": 13\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/apply-cost-correction","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","apply-cost-correction"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID (must be closed)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost corrections applied successfully.\",\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"closed\"\n  }\n}"}]},{"name":"Get FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/fifo-layers","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","fifo-layers"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Get FIFO inventory layers connected to this stock take's items.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/fifo-layers","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","fifo-layers"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 300,\n      \"product_id\": 55,\n      \"warehouse_id\": 2,\n      \"quantity\": 98,\n      \"unit_cost\": 12.5,\n      \"link_type\": \"App\\\\Models\\\\StockTakeItem\",\n      \"link_id\": 101,\n      \"created_at\": \"2024-10-10T16:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/inventory-movements","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","inventory-movements"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Get all inventory movements linked to this stock take.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/inventory-movements","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","inventory-movements"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2001,\n      \"product_id\": 55,\n      \"warehouse_id\": 2,\n      \"quantity\": -2,\n      \"movement_type\": \"stock_take_adjustment\",\n      \"link_type\": \"App\\\\Models\\\\StockTakeItem\",\n      \"link_id\": 101,\n      \"created_at\": \"2024-10-10T16:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Get During-Count Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/during-count-movements","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","during-count-movements"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Get inventory movements that occurred during the stock take counting period (after snapshot was taken), excluding movements belonging to this stock take itself.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/during-count-movements","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","during-count-movements"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2005,\n      \"product_id\": 55,\n      \"warehouse_id\": 2,\n      \"quantity\": 10,\n      \"movement_type\": \"purchase_order_receipt\",\n      \"created_at\": \"2024-10-10T12:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Product Cost Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/product-cost-options?product_id=55&warehouse_id=2","host":["{{baseUrl}}"],"path":["api","stock-takes","product-cost-options"],"query":[{"key":"product_id","value":"55","description":"Required. Product ID.","disabled":true},{"key":"warehouse_id","value":"2","description":"Required. Warehouse ID.","disabled":true}]},"description":"Get cost options for a product in a warehouse. Returns the best available COGS (derived from FIFO cost history) and the product's default unit cost. Both values are per stock unit and returned with up to 4 decimal places of precision — products stocked in small units (oz, g, ml) routinely have per-unit costs below $0.01.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/product-cost-options?product_id=55&warehouse_id=2","host":["{{baseUrl}}"],"path":["api","stock-takes","product-cost-options"],"query":[{"key":"product_id","value":"55","description":"Required. Product ID.","disabled":true},{"key":"warehouse_id","value":"2","description":"Required. Warehouse ID.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"best_available_cogs\": {\n    \"value\": 0.2344,\n    \"source\": \"oldest_active_fifo\",\n    \"available\": true\n  },\n  \"unit_cost\": {\n    \"value\": 0.23,\n    \"available\": true\n  }\n}"}]},{"name":"Get Inventory Start Date","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/inventory-start-date","host":["{{baseUrl}}"],"path":["api","stock-takes","inventory-start-date"]},"description":"Get the inventory start date from application settings. Used to validate initial count dates.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stock-takes/inventory-start-date","host":["{{baseUrl}}"],"path":["api","stock-takes","inventory-start-date"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"inventory_start_date\": \"2024-01-01\"\n}"}]},{"name":"Import Lines from CSV","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/import-lines","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","import-lines"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Import stock take lines from a previously uploaded CSV file. The CSV must have columns: sku or id (product identifier), and optionally qty_counted, snapshot_inventory, unit_cost.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nfile: path to an already uploaded file (not a direct upload).\n\nProducts matched by SKU or barcode. Duplicate products are summed. Unmatched SKUs generate warnings.\n\nReturns parsed line items (not yet saved — save via the update endpoint).\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"file\": \"uploads/stock_take_lines_20241010.csv\",\n  \"separator\": \",\",\n  \"escape\": \"\\\"\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/import-lines","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","import-lines"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 55,\n      \"sku\": \"PROD-001\",\n      \"name\": \"Widget A\",\n      \"qty_counted\": 98,\n      \"snapshot_inventory\": 0,\n      \"unit_cost\": null\n    }\n  ],\n  \"warnings\": [\n    {\n      \"code\": \"HAS_UNMAPPED_PRODUCTS\",\n      \"message\": \"2 of SKUs did not match any product\"\n    }\n  ]\n}"}]},{"name":"Archive Stock Take","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/archive","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","archive"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Archive a single stock take.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/archive","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","archive"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"stock take 42 archived successfully\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": \"2024-10-15T09:00:00+00:00\"\n  }\n}"}]},{"name":"Unarchive Stock Take","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/unarchived","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","unarchived"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]},"description":"Unarchive a single stock take.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stock-takes/{stockTake}/unarchived","host":["{{baseUrl}}"],"path":["api","stock-takes",":stockTake","unarchived"],"variable":[{"key":"stockTake","value":"42","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"stock take 42 unarchived successfully\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Stock Takes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/archive","host":["{{baseUrl}}"],"path":["api","stock-takes","archive"]},"description":"Bulk archive multiple stock takes.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nids: array of stock take IDs. Required unless apply_to_all is true.\n\napply_to_all: if true, archives all stock takes matching filters.\n\nfilters: optional filter conditions when apply_to_all is true.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    40,\n    41,\n    42\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stock-takes/archive","host":["{{baseUrl}}"],"path":["api","stock-takes","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk archive completed\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Stock Takes","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/unarchive","host":["{{baseUrl}}"],"path":["api","stock-takes","unarchive"]},"description":"Bulk unarchive multiple stock takes.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    40,\n    41\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stock-takes/unarchive","host":["{{baseUrl}}"],"path":["api","stock-takes","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk unarchive completed\"\n}"}]},{"name":"Check Deletable Stock Takes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stock-takes/deletable","host":["{{baseUrl}}"],"path":["api","stock-takes","deletable"]},"description":"Check whether stock takes can be deleted. Returns deletable status and reason for each.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `inventory.count`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stock-takes/deletable","host":["{{baseUrl}}"],"path":["api","stock-takes","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"deletable\": false,\n      \"reason\": \"Stock take has linked inventory movements\"\n    },\n    {\n      \"id\": 43,\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]}]},{"name":"Assemblies","item":[{"name":"List Assemblies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies?page=1&per_page=15&search=&archived=0&sort=id","host":["{{baseUrl}}"],"path":["api","assemblies"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"search","value":"","description":"Search string to filter assemblies","disabled":true},{"key":"archived","value":"0","description":"Include archived records: 0 = active only (default), 1 = archived only","disabled":true},{"key":"sort","value":"id","description":"Sort field. Prefix with - for descending. Allowed: id, action_date, created_at, updated_at","disabled":true}]},"description":"Returns a paginated list of inventory assemblies. Supports pagination, search, and archive filtering.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse fields:\n- id: Assembly ID\n- warehouse: Warehouse details {id, name}\n- action_date: Date of the assembly/disassembly action\n- action: 'assemble' or 'disassemble'\n- items: Assembly lines with product details\n- created_at: Creation timestamp\n- archived_at: Archive timestamp (null if not archived)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/assemblies?page=1&per_page=15&search=&archived=0&sort=id","host":["{{baseUrl}}"],"path":["api","assemblies"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"search","value":"","description":"Search string to filter assemblies","disabled":true},{"key":"archived","value":"0","description":"Include archived records: 0 = active only (default), 1 = archived only","disabled":true},{"key":"sort","value":"id","description":"Sort field. Prefix with - for descending. Allowed: id, action_date, created_at, updated_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"action_date\": \"2024-01-15\",\n      \"action\": \"assemble\",\n      \"items\": [\n        {\n          \"id\": 10,\n          \"product_id\": 100,\n          \"quantity\": 5,\n          \"product_type\": \"kit\"\n        }\n      ],\n      \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 57,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Create Assembly","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/assemblies","host":["{{baseUrl}}"],"path":["api","assemblies"]},"description":"Creates a new inventory assembly or disassembly record, adjusting inventory accordingly.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- action_date (date, required): Date of the assembly/disassembly action (e.g. '2024-01-15')\n- product_id (integer, required): ID of the kit product to assemble/disassemble\n- warehouse_id (integer, required): ID of the warehouse where the action takes place. Warehouse must have a default location unless warehouse_location_id is provided.\n- warehouse_location_id (integer, optional): ID of the warehouse location. If omitted, uses the warehouse's default location.\n- quantity (numeric, required): Quantity to assemble or disassemble. Must be non-zero.\n- action (string, required): Type of action — 'assemble' (build kits from components) or 'disassemble' (break kits into components)\n- component_lot_allocations (array, optional, ASSEMBLE only): FEFO suggest-with-override for lot-tracked components. Each entry is `{ product_id, lot_allocation: [{ fifo_layer_id, quantity }] }`. Omit to consume components by automatic FEFO/FIFO. When supplied, the allocation for each component must reconcile to that component's total consumption (its per-kit quantity × assembly quantity), reference active FIFO layers of that component product + the selected warehouse, and respect the tenant's lot-override policy (under `enforce`, expired or later-expiry FEFO picks are hard-blocked). Validation errors are returned per row, e.g. `component_lot_allocations.0.lot_allocation.1.fifo_layer_id`.","body":{"mode":"raw","raw":"{\n  \"action_date\": \"2024-01-15\",\n  \"product_id\": 100,\n  \"warehouse_id\": 1,\n  \"warehouse_location_id\": null,\n  \"quantity\": 5,\n  \"action\": \"assemble\",\n  \"component_lot_allocations\": [\n    {\n      \"product_id\": 201,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 901,\n          \"quantity\": 8\n        },\n        {\n          \"fifo_layer_id\": 902,\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/assemblies","host":["{{baseUrl}}"],"path":["api","assemblies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory assembled successfully.\",\n  \"data\": {\n    \"id\": 42,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"action_date\": \"2024-01-15\",\n    \"action\": \"assemble\",\n    \"items\": [\n      {\n        \"id\": 10,\n        \"product_id\": 100,\n        \"quantity\": 5,\n        \"product_type\": \"kit\"\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Delete Assemblies","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies","host":["{{baseUrl}}"],"path":["api","assemblies"]},"description":"Deletes multiple inventory assemblies and reverses their inventory movements.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required unless apply_to_all is true): Array of assembly IDs to delete\n- apply_to_all (boolean, optional): If true, deletes all assemblies matching the provided filters\n- filters (array, optional): Filter criteria when apply_to_all is true"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/assemblies","host":["{{baseUrl}}"],"path":["api","assemblies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 inventory assemblies deleted successfully.\"\n}"}]},{"name":"Get Assembly","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]},"description":"Returns the full details of a single inventory assembly, including assembly lines, inventory movements, and FIFO layer data.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse includes:\n- id, warehouse, action_date, action\n- items: Assembly lines with product details and primary image\n- inventory_impact: Grouped movements per line with FIFO layer data\n- created_at, updated_at, archived_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"action_date\": \"2024-01-15\",\n    \"action\": \"assemble\",\n    \"items\": [\n      {\n        \"id\": 10,\n        \"product_id\": 100,\n        \"quantity\": 5,\n        \"product_type\": \"kit\"\n      }\n    ],\n    \"inventory_impact\": [\n      {\n        \"line_id\": 10,\n        \"product_id\": 100,\n        \"product\": {\n          \"sku\": \"KIT-001\",\n          \"name\": \"Starter Kit\"\n        },\n        \"quantity\": 5,\n        \"product_type\": \"kit\",\n        \"movements\": [\n          {\n            \"id\": 201,\n            \"product_id\": 100,\n            \"warehouse_id\": 1,\n            \"warehouse\": {\n              \"name\": \"Main Warehouse\"\n            },\n            \"quantity_delta\": 5,\n            \"quantity_delta_reserved\": 0,\n            \"movement_date\": \"2024-01-15\",\n            \"inventory_status\": \"on_hand\",\n            \"layer\": {\n              \"id\": 55,\n              \"fifo_layer_date\": \"2024-01-15\",\n              \"original_quantity\": 5,\n              \"fulfilled_quantity\": 0,\n              \"available_quantity\": 5,\n              \"avg_cost\": 12.5,\n              \"total_cost\": 62.5,\n              \"link_type\": \"assembly\",\n              \"link_reference\": \"42\",\n              \"product\": {\n                \"sku\": \"KIT-001\",\n                \"name\": \"Starter Kit\"\n              },\n              \"warehouse\": {\n                \"name\": \"Main Warehouse\"\n              }\n            }\n          }\n        ]\n      }\n    ],\n    \"created_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:30:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Delete Assembly","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]},"description":"Deletes the specified inventory assembly and reverses its inventory movements.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nNote: Deletion reverses the inventory impact of the assembly (FIFO layers are unwound)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory assembly 42 deleted successfully.\"\n}"}]},{"name":"Check Assemblies Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/assemblies/deletable","host":["{{baseUrl}}"],"path":["api","assemblies","deletable"]},"description":"Checks whether the specified assemblies can be deleted. All inventory assemblies are deletable (deletion reverses inventory movements).\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of assembly IDs to check (min 1)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/assemblies/deletable","host":["{{baseUrl}}"],"path":["api","assemblies","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 43,\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Archive Assembly","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}/archive","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly","archive"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]},"description":"Archives the specified inventory assembly by setting its archived_at timestamp.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}/archive","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly","archive"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory assembly 42 archived successfully.\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": \"2024-01-15T10:30:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive Assembly","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}/unarchived","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly","unarchived"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]},"description":"Restores (unarchives) the specified inventory assembly by clearing its archived_at timestamp.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/assemblies/{assembly}/unarchived","host":["{{baseUrl}}"],"path":["api","assemblies",":assembly","unarchived"],"variable":[{"key":"assembly","value":"42","description":"Assembly ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inventory assembly 42 unarchived successfully.\",\n  \"data\": {\n    \"id\": 42,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Assemblies","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/assemblies/archive","host":["{{baseUrl}}"],"path":["api","assemblies","archive"]},"description":"Archives multiple inventory assemblies.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required unless apply_to_all is true): Array of assembly IDs to archive\n- apply_to_all (boolean, optional): If true, archives all assemblies matching the provided filters\n- filters (array, optional): Filter criteria when apply_to_all is true","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/assemblies/archive","host":["{{baseUrl}}"],"path":["api","assemblies","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 inventory assemblies archived successfully.\"\n}"}]},{"name":"Bulk Unarchive Assemblies","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/assemblies/unarchive","host":["{{baseUrl}}"],"path":["api","assemblies","unarchive"]},"description":"Restores (unarchives) multiple inventory assemblies.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required unless apply_to_all is true): Array of assembly IDs to unarchive\n- apply_to_all (boolean, optional): If true, unarchives all assemblies matching the provided filters\n- filters (array, optional): Filter criteria when apply_to_all is true","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/assemblies/unarchive","host":["{{baseUrl}}"],"path":["api","assemblies","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 inventory assemblies unarchived successfully.\"\n}"}]},{"name":"List Kit Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/browse-kits?warehouse_id=1&query=starter&limit=15","host":["{{baseUrl}}"],"path":["api","assemblies","browse-kits"],"query":[{"key":"warehouse_id","value":"1","description":"Warehouse ID to calculate inventory quantities for (optional). If omitted, qty_on_hand and qty_possible will be 0.","disabled":true},{"key":"query","value":"starter","description":"Search string to filter kit products by SKU or name","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 15)","disabled":true}]},"description":"Returns a paginated list of kit products with inventory availability data for the assembly form. Shows how many kits can currently be assembled based on available component stock.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse fields per kit:\n- id: Product ID\n- sku: Product SKU\n- name: Product name\n- qty_on_hand: Current assembled kit quantity in the warehouse\n- qty_possible: Maximum number of kits that can be assembled from available component stock"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/assemblies/browse-kits?warehouse_id=1&query=starter&limit=15","host":["{{baseUrl}}"],"path":["api","assemblies","browse-kits"],"query":[{"key":"warehouse_id","value":"1","description":"Warehouse ID to calculate inventory quantities for (optional). If omitted, qty_on_hand and qty_possible will be 0.","disabled":true},{"key":"query","value":"starter","description":"Search string to filter kit products by SKU or name","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 15)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 100,\n      \"sku\": \"KIT-001\",\n      \"name\": \"Starter Kit\",\n      \"qty_on_hand\": 12,\n      \"qty_possible\": 8\n    }\n  ],\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 18\n}"}]},{"name":"Get Kit & Component Availability","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/assemblies/inventory-data?product_id=100","host":["{{baseUrl}}"],"path":["api","assemblies","inventory-data"],"query":[{"key":"product_id","value":"100","description":"Kit product ID (required). Returns inventory data for this kit and all its component products.","disabled":true}]},"description":"Returns inventory availability data for a kit product and its components across all warehouses. Used in the assembly form to show per-warehouse stock levels.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nResponse:\n- kit_inventory: Map of warehouse_id => {warehouse_id, warehouse_name, quantity} for the kit product\n- component_inventory: Map of warehouse_id => {product_id: available_qty} for each component"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/assemblies/inventory-data?product_id=100","host":["{{baseUrl}}"],"path":["api","assemblies","inventory-data"],"query":[{"key":"product_id","value":"100","description":"Kit product ID (required). Returns inventory data for this kit and all its component products.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"kit_inventory\": {\n      \"1\": {\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"quantity\": 12\n      },\n      \"2\": {\n        \"warehouse_id\": 2,\n        \"warehouse_name\": \"East Warehouse\",\n        \"quantity\": 5\n      }\n    },\n    \"component_inventory\": {\n      \"1\": {\n        \"101\": 50,\n        \"102\": 30\n      },\n      \"2\": {\n        \"101\": 20,\n        \"102\": 10\n      }\n    }\n  }\n}"}]}]},{"name":"Initial Inventory","item":[{"name":"Import Initial Inventory (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/initial-inventory/import","host":["{{baseUrl}}"],"path":["api","initial-inventory","import"]},"description":"Imports initial inventory records from a CSV file using the DataImport system.\nAuthentication: Requires Bearer token.\nContent-Type: multipart/form-data\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe import first runs a preview/validation pass. If there are required field differences, the preview response is returned. Otherwise, the import is executed and records are created.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"import_type","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/initial-inventory/import","host":["{{baseUrl}}"],"path":["api","initial-inventory","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"imported\": 42,\n    \"failed\": 0,\n    \"errors\": []\n  },\n  \"message\": \"Import completed successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"List Initial Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/initial-inventory?page=1&limit=25&sort=id&search=","host":["{{baseUrl}}"],"path":["api","initial-inventory"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true},{"key":"sort","value":"id","description":"Sort field. Prefix with - for descending (e.g. -id)","disabled":true},{"key":"search","value":"","description":"Search across SKU, product name","disabled":true}]},"description":"Returns a paginated list of initial inventory records (FIFO layers representing opening stock).\nAuthentication: Requires Bearer token.\nUses standard list query parameters for filtering, sorting, and pagination.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/initial-inventory?page=1&limit=25&sort=id&search=","host":["{{baseUrl}}"],"path":["api","initial-inventory"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true},{"key":"sort","value":"id","description":"Sort field. Prefix with - for descending (e.g. -id)","disabled":true},{"key":"search","value":"","description":"Search across SKU, product name","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"quantity\": 200,\n      \"unit_cost\": 10,\n      \"fifo_layer_date\": \"2023-01-01\",\n      \"created_at\": \"2023-01-01T00:00:00Z\",\n      \"updated_at\": \"2023-01-01T00:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 25,\n  \"total\": 42\n}"}]},{"name":"Create Initial Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/initial-inventory","host":["{{baseUrl}}"],"path":["api","initial-inventory"]},"description":"Creates an initial inventory record (opening stock FIFO layer) for a product in a warehouse.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"warehouse_id\": 1,\n  \"quantity\": 200,\n  \"unit_cost\": 10,\n  \"fifo_layer_date\": \"2023-01-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/initial-inventory","host":["{{baseUrl}}"],"path":["api","initial-inventory"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"product_id\": 42,\n    \"warehouse_id\": 1,\n    \"quantity\": 200,\n    \"unit_cost\": 10,\n    \"fifo_layer_date\": \"2023-01-01\",\n    \"created_at\": \"2024-01-15T10:00:00Z\",\n    \"updated_at\": \"2024-01-15T10:00:00Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Initial Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]},"description":"Returns a single initial inventory record.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"product_name\": \"Blue Widget\",\n    \"warehouse_id\": 1,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"quantity\": 200,\n    \"unit_cost\": 10,\n    \"fifo_layer_date\": \"2023-01-01\",\n    \"created_at\": \"2023-01-01T00:00:00Z\",\n    \"updated_at\": \"2023-01-01T00:00:00Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Initial Inventory","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]},"description":"Updates an existing initial inventory record.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"quantity\": 250,\n  \"unit_cost\": 11\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"quantity\": 250,\n    \"unit_cost\": 11,\n    \"updated_at\": \"2024-01-16T09:00:00Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Initial Inventory","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]},"description":"Deletes an initial inventory record and reverses its associated FIFO layers.\nAuthentication: Requires Bearer token.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/initial-inventory/{id}","host":["{{baseUrl}}"],"path":["api","initial-inventory",":id"],"variable":[{"key":"id","value":"1","description":"Initial inventory record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventory record deleted successfully.\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Costing","item":[{"name":"List Cost Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entries","host":["{{baseUrl}}"],"path":["api","cost-entries"]},"description":"Returns a paginated list of cost entries, newest cost date first by default.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAllowed sorts: id, description, reference_number, status, cost_date, amount, amount_in_tenant_currency, created_at, updated_at, supplier_name, cost_entry_type_name, allocations_total, unallocated_total. Prefix with - for descending.\n\nfilter[search] matches description, reference number, ID, supplier name and cost entry type name. filter[source.is]=bill returns only entries created from bills; filter[source.is_not]=bill returns manual entries. filter[has_amortization.is]=true/false filters by presence of an amortization schedule.\n\nColumn filters accept operator suffixes in the form filter[column.operator], e.g. filter[name.contains]=main or filter[created_at.between]=2026-01-01,2026-06-30. Text operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of. Numeric operators: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty. Date operators: is, is_not, on_or_before, on_or_after, between, is_empty, is_not_empty.\n\nThe response includes an unfiltered_total field with the total number of cost entries regardless of filters.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-entries","host":["{{baseUrl}}"],"path":["api","cost-entries"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"supplier_id\": 3,\n      \"supplier_name\": \"Global Freight Co\",\n      \"reference_number\": \"FRT-2026-0142\",\n      \"description\": \"June ocean freight\",\n      \"cost_date\": \"2026-06-01\",\n      \"amount\": 2500,\n      \"amount_in_tenant_currency\": 2500,\n      \"currency_id\": 1,\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"nominal_code_id\": 15,\n      \"nominal_code_name\": \"Freight & Duty\",\n      \"cost_entry_type_id\": 2,\n      \"cost_entry_type\": {\n        \"id\": 2,\n        \"name\": \"Freight\"\n      },\n      \"status\": \"pending_allocation\",\n      \"bill_id\": null,\n      \"bill_line_id\": null,\n      \"source_type\": \"manual\",\n      \"source_description\": null,\n      \"source_link_type\": null,\n      \"source_id\": null,\n      \"source_label\": null,\n      \"source_period\": null,\n      \"reconciliation\": null,\n      \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:00:00.000000Z\",\n      \"totals\": {\n        \"allocated\": 1000,\n        \"unallocated\": 1500,\n        \"is_fully_allocated\": false\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"unfiltered_total\": 128\n}"}]},{"name":"Create Cost Entry","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries","host":["{{baseUrl}}"],"path":["api","cost-entries"]},"description":"Creates a cost entry.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields: description, cost_date (Y-m-d), amount (in the entry's currency) and amount_in_tenant_currency.\n\nOptional fields: cost_entry_type_id, status (draft, pending_allocation, partially_allocated or allocated; default draft), supplier_id, reference_number, currency_id, currency_rate, nominal_code_id, bill_id and bill_line_id (link the entry to a bill), source_type, source_id and source_period (identify an originating document and the period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"description\": \"June ocean freight\",\n  \"cost_date\": \"2026-06-01\",\n  \"amount\": 2500,\n  \"amount_in_tenant_currency\": 2500,\n  \"cost_entry_type_id\": 2,\n  \"status\": \"pending_allocation\",\n  \"supplier_id\": 3,\n  \"reference_number\": \"FRT-2026-0142\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"nominal_code_id\": 15\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries","host":["{{baseUrl}}"],"path":["api","cost-entries"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Global Freight Co\",\n    \"reference_number\": \"FRT-2026-0142\",\n    \"description\": \"June ocean freight\",\n    \"cost_date\": \"2026-06-01\",\n    \"amount\": 2500,\n    \"amount_in_tenant_currency\": 2500,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"nominal_code_id\": 15,\n    \"nominal_code_name\": \"Freight & Duty\",\n    \"cost_entry_type_id\": 2,\n    \"cost_entry_type\": {\n      \"id\": 2,\n      \"name\": \"Freight\"\n    },\n    \"status\": \"pending_allocation\",\n    \"bill_id\": null,\n    \"bill_line_id\": null,\n    \"source_type\": \"manual\",\n    \"source_description\": null,\n    \"source_link_type\": null,\n    \"source_id\": null,\n    \"source_label\": null,\n    \"source_period\": null,\n    \"reconciliation\": null,\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"totals\": {\n      \"allocated\": 1000,\n      \"unallocated\": 1500,\n      \"is_fully_allocated\": false\n    }\n  }\n}"}]},{"name":"Get Cost Entry","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Returns a cost entry with its allocations and amortization schedule (including periods and the resolved allocation target).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe totals object reports the allocated amount, the remaining unallocated amount and whether the entry is fully allocated. For entries auto-generated from a source document, source_type is \"source\" and the source_* fields identify the origin record; manual entries have source_type \"manual\". The reconciliation field holds settlement reconciliation results ({actual_amount, variance, variance_pct, settlement_report_ids, reconciled_at}) or null.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Global Freight Co\",\n    \"reference_number\": \"FRT-2026-0142\",\n    \"description\": \"June ocean freight\",\n    \"cost_date\": \"2026-06-01\",\n    \"amount\": 2500,\n    \"amount_in_tenant_currency\": 2500,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"nominal_code_id\": 15,\n    \"nominal_code_name\": \"Freight & Duty\",\n    \"cost_entry_type_id\": 2,\n    \"cost_entry_type\": {\n      \"id\": 2,\n      \"name\": \"Freight\"\n    },\n    \"status\": \"pending_allocation\",\n    \"bill_id\": null,\n    \"bill_line_id\": null,\n    \"source_type\": \"manual\",\n    \"source_description\": null,\n    \"source_link_type\": null,\n    \"source_id\": null,\n    \"source_label\": null,\n    \"source_period\": null,\n    \"reconciliation\": null,\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"totals\": {\n      \"allocated\": 1000,\n      \"unallocated\": 1500,\n      \"is_fully_allocated\": false\n    },\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ],\n    \"amortization_schedule\": {\n      \"id\": 7,\n      \"cost_entry_id\": 42,\n      \"start_date\": \"2026-07-01\",\n      \"end_date\": \"2027-06-30\",\n      \"total_periods\": 12,\n      \"frequency\": \"monthly\",\n      \"method\": \"straight_line\",\n      \"total_amount\": 2500,\n      \"amount_per_period\": 208.33,\n      \"is_fully_processed\": false,\n      \"pending_periods_count\": 12,\n      \"processed_periods_count\": 0,\n      \"allocation_config\": {\n        \"allocatable_type\": \"product\",\n        \"allocatable_id\": 101,\n        \"allocatable_name\": \"Widget\",\n        \"proration_strategy\": \"specific_line\"\n      },\n      \"created_at\": \"2026-06-01T10:10:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:10:00.000000Z\",\n      \"periods\": [\n        {\n          \"id\": 601,\n          \"period_number\": 1,\n          \"period_start\": \"2026-07-01\",\n          \"period_end\": \"2026-07-31\",\n          \"amount\": 208.33,\n          \"is_processed\": false\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Update Cost Entry","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Updates a cost entry. All fields are optional; only provided fields are changed.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: description, cost_date, amount, amount_in_tenant_currency, cost_entry_type_id, status (draft, pending_allocation, partially_allocated, allocated), supplier_id, reference_number, currency_id, currency_rate and nominal_code_id.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"description\": \"June ocean freight (revised)\",\n  \"amount\": 2650,\n  \"amount_in_tenant_currency\": 2650\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"supplier_id\": 3,\n    \"supplier_name\": \"Global Freight Co\",\n    \"reference_number\": \"FRT-2026-0142\",\n    \"description\": \"June ocean freight\",\n    \"cost_date\": \"2026-06-01\",\n    \"amount\": 2500,\n    \"amount_in_tenant_currency\": 2500,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"nominal_code_id\": 15,\n    \"nominal_code_name\": \"Freight & Duty\",\n    \"cost_entry_type_id\": 2,\n    \"cost_entry_type\": {\n      \"id\": 2,\n      \"name\": \"Freight\"\n    },\n    \"status\": \"pending_allocation\",\n    \"bill_id\": null,\n    \"bill_line_id\": null,\n    \"source_type\": \"manual\",\n    \"source_description\": null,\n    \"source_link_type\": null,\n    \"source_id\": null,\n    \"source_label\": null,\n    \"source_period\": null,\n    \"reconciliation\": null,\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"totals\": {\n      \"allocated\": 1000,\n      \"unallocated\": 1500,\n      \"is_fully_allocated\": false\n    }\n  }\n}"}]},{"name":"Delete Cost Entry","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Deletes a cost entry and its allocations.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost entry deleted successfully\"\n}"}]},{"name":"List Cost Entry Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocations","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocations"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Returns all allocations recorded against the cost entry, including the allocated target (product, brand, supplier, sales channel or sales order line) and any amortization linkage.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocations","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocations"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"cost_entry_id\": 42,\n      \"allocatable_type\": \"App\\\\Models\\\\Product\",\n      \"allocatable_type_label\": \"Product\",\n      \"allocatable_id\": 101,\n      \"allocatable\": {\n        \"id\": 101,\n        \"name\": \"Widget\",\n        \"sku\": \"WIDGET-001\"\n      },\n      \"allocation_date\": \"2026-06-01\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"amount\": 1000,\n      \"amount_in_tenant_currency\": 1000,\n      \"proration_strategy\": \"specific_line\",\n      \"proration_weight\": null,\n      \"amortization_period_id\": null,\n      \"is_amortized\": false,\n      \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Delete Cost Entry Allocations","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocations","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocations"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Deletes all allocations for the cost entry, returning its full amount to unallocated.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocations","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocations"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 3 allocations\"\n}"}]},{"name":"Create Amortization Schedule","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/amortization-schedule","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","amortization-schedule"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Creates an amortization schedule for a cost entry, spreading its amount across future periods. Each period, when processed, allocates its share to the configured target. A cost entry can have only one schedule.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields: start_date (Y-m-d), periods (1-120), frequency (daily, weekly, monthly, quarterly, annually), method (straight_line, front_loaded, back_loaded), allocatable_type (product, brand, supplier or sales_channel) and allocatable_id.\n\nOptional: proration_strategy (default specific_line).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"start_date\": \"2026-07-01\",\n  \"periods\": 12,\n  \"frequency\": \"monthly\",\n  \"method\": \"straight_line\",\n  \"allocatable_type\": \"product\",\n  \"allocatable_id\": 101,\n  \"proration_strategy\": \"specific_line\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/amortization-schedule","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","amortization-schedule"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"cost_entry_id\": 42,\n    \"start_date\": \"2026-07-01\",\n    \"end_date\": \"2027-06-30\",\n    \"total_periods\": 12,\n    \"frequency\": \"monthly\",\n    \"method\": \"straight_line\",\n    \"total_amount\": 2500,\n    \"amount_per_period\": 208.33,\n    \"is_fully_processed\": false,\n    \"pending_periods_count\": 12,\n    \"processed_periods_count\": 0,\n    \"allocation_config\": {\n      \"allocatable_type\": \"product\",\n      \"allocatable_id\": 101,\n      \"allocatable_name\": \"Widget\",\n      \"proration_strategy\": \"specific_line\"\n    },\n    \"created_at\": \"2026-06-01T10:10:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:10:00.000000Z\",\n    \"periods\": [\n      {\n        \"id\": 601,\n        \"period_number\": 1,\n        \"period_start\": \"2026-07-01\",\n        \"period_end\": \"2026-07-31\",\n        \"amount\": 208.33,\n        \"is_processed\": false\n      }\n    ]\n  }\n}"}]},{"name":"List Cost Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-allocations","host":["{{baseUrl}}"],"path":["api","cost-allocations"]},"description":"Returns a paginated list of cost allocations. A cost allocation assigns part (or all) of a cost entry's amount to a target entity - a product, brand, supplier, sales channel or sales order line - for landed cost and profitability reporting.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach allocation includes the target type, a human-readable type label, a summary of the target entity (allocatable), the allocated amount in the cost entry's currency and in the account currency (amount_in_tenant_currency), the proration strategy that produced it, and whether it was generated by an amortization schedule (is_amortized).\n\nFiltering uses plain query parameters (not the filter[...] syntax used elsewhere in this API): cost_entry_id, allocatable_type, allocatable_id, date_from, date_to and proration_strategy - see each parameter's description. Results are always sorted by allocation date, newest first; there is no sort parameter.\n\nPagination: page (default 1) and per_page (default 15, max 100).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-allocations","host":["{{baseUrl}}"],"path":["api","cost-allocations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"cost_entry_id\": 42,\n      \"allocatable_type\": \"App\\\\Models\\\\Product\",\n      \"allocatable_type_label\": \"Product\",\n      \"allocatable_id\": 101,\n      \"allocatable\": {\n        \"id\": 101,\n        \"name\": \"Widget\",\n        \"sku\": \"WIDGET-001\"\n      },\n      \"allocation_date\": \"2026-06-01\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"amount\": 1000,\n      \"amount_in_tenant_currency\": 1000,\n      \"proration_strategy\": \"manual\",\n      \"proration_weight\": null,\n      \"amortization_period_id\": null,\n      \"is_amortized\": false,\n      \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n    },\n    {\n      \"id\": 91,\n      \"cost_entry_id\": 45,\n      \"allocatable_type\": \"App\\\\Models\\\\Supplier\",\n      \"allocatable_type_label\": \"Supplier\",\n      \"allocatable_id\": 3,\n      \"allocatable\": {\n        \"id\": 3,\n        \"name\": \"Global Freight Co\"\n      },\n      \"allocation_date\": \"2026-05-15\",\n      \"period_start\": null,\n      \"period_end\": null,\n      \"amount\": 450,\n      \"amount_in_tenant_currency\": 450,\n      \"proration_strategy\": \"cost_based\",\n      \"proration_weight\": 0.45,\n      \"amortization_period_id\": null,\n      \"is_amortized\": false,\n      \"created_at\": \"2026-05-15T08:20:00.000000Z\",\n      \"updated_at\": \"2026-05-15T08:20:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/cost-allocations?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/cost-allocations?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}{{domain}}/api/cost-allocations?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/cost-allocations\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Create Cost Allocation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-allocations","host":["{{baseUrl}}"],"path":["api","cost-allocations"]},"description":"Creates a single cost allocation directly, assigning part (or all) of a cost entry's amount to a target entity. This is the low-level create: the caller supplies both currency amounts and the proration metadata explicitly. For most integrations the allocate endpoints under /api/cost-entries/{cost_entry}/allocate/... are simpler - they compute the account-currency amount and proration weights automatically.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- cost_entry_id (required, integer): ID of the cost entry to allocate from. Unknown IDs return 404.\n- allocatable_type (required, string): fully qualified target type. One of: App\\Models\\Product, App\\Models\\ProductBrand, App\\Models\\Supplier, App\\Models\\SalesChannel, App\\Models\\SalesOrderLine.\n- allocatable_id (required, integer): ID of the target entity.\n- allocation_date (required, date YYYY-MM-DD): ledger date of the allocation.\n- amount (required, number): amount to allocate, in the cost entry's currency.\n- amount_in_tenant_currency (required, number): the same amount expressed in the account currency.\n- proration_strategy (required, string): one of revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual. Use manual for a direct allocation.\n- period_start, period_end (optional, date YYYY-MM-DD): the period the cost applies to.\n- proration_weight (optional, number): the weight used when the allocation is part of a prorated distribution.\n- amortization_period_id (optional, integer): links the allocation to an amortization period. Leave null for manual allocations - amortization-linked allocations are normally created by the amortization processor.\n\nThe allocated amount is validated against the cost entry's remaining unallocated amount (taking into account amounts reserved by a pending amortization schedule); exceeding it returns 422. Creating an allocation also recalculates the parent cost entry's allocation status (pending_allocation, partially_allocated or allocated).\n\nNote that this endpoint returns HTTP 200 (not 201) on success.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).","body":{"mode":"raw","raw":"{\n  \"cost_entry_id\": 42,\n  \"allocatable_type\": \"App\\\\Models\\\\Product\",\n  \"allocatable_id\": 101,\n  \"allocation_date\": \"2026-06-01\",\n  \"amount\": 1000,\n  \"amount_in_tenant_currency\": 1000,\n  \"proration_strategy\": \"manual\",\n  \"period_start\": \"2026-06-01\",\n  \"period_end\": \"2026-06-30\",\n  \"proration_weight\": null,\n  \"amortization_period_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-allocations","host":["{{baseUrl}}"],"path":["api","cost-allocations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"manual\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Get Cost Allocation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-allocations/{costAllocation}","host":["{{baseUrl}}"],"path":["api","cost-allocations",":costAllocation"],"variable":[{"key":"costAllocation","value":"88","description":"Cost allocation ID"}]},"description":"Returns a single cost allocation by ID, including a summary of the target entity (allocatable). The summary fields depend on the target type: products include name and sku; brands, suppliers and sales channels include name; sales order lines include sales_order_id, product_id, product_name and quantity. amount is in the parent cost entry's currency and amount_in_tenant_currency is the equivalent in the account currency.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-allocations/{costAllocation}","host":["{{baseUrl}}"],"path":["api","cost-allocations",":costAllocation"],"variable":[{"key":"costAllocation","value":"88","description":"Cost allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"manual\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Delete Cost Allocation","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/cost-allocations/{costAllocation}","host":["{{baseUrl}}"],"path":["api","cost-allocations",":costAllocation"],"variable":[{"key":"costAllocation","value":"88","description":"Cost allocation ID"}]},"description":"Deletes a cost allocation and recalculates the parent cost entry's allocation status, freeing the amount to be allocated again.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAllocations that were created by an amortization schedule cannot be deleted individually - the request fails with HTTP 422. Delete the amortization schedule instead (DELETE /api/amortization-schedules/{amortization_schedule}).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/cost-allocations/{costAllocation}","host":["{{baseUrl}}"],"path":["api","cost-allocations",":costAllocation"],"variable":[{"key":"costAllocation","value":"88","description":"Cost allocation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Allocation deleted successfully\"\n}"}]},{"name":"Allocate Cost Entry to Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/product/{product}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","product",":product"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"product","value":"101","description":"Product ID"}]},"description":"Allocates part of a cost entry to a specific product. The allocation feeds into landed cost and profitability reporting.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: amount (required, the amount to allocate), allocation_date (the ledger date for the allocation, defaults to today), period_start and period_end (optional period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 1000,\n  \"allocation_date\": \"2026-06-15\",\n  \"period_start\": \"2026-06-01\",\n  \"period_end\": \"2026-06-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/product/{product}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","product",":product"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"product","value":"101","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"specific_line\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Allocate Cost Entry to Brand","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/brand/{brand}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","brand",":brand"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"brand","value":"7","description":"Product brand ID"}]},"description":"Allocates part of a cost entry to a product brand.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: amount (required, the amount to allocate), allocation_date (the ledger date for the allocation, defaults to today), period_start and period_end (optional period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/brand/{brand}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","brand",":brand"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"brand","value":"7","description":"Product brand ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"specific_line\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Allocate Cost Entry to Supplier","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/supplier/{supplier}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","supplier",":supplier"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"supplier","value":"3","description":"Supplier ID"}]},"description":"Allocates part of a cost entry to a supplier.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: amount (required, the amount to allocate), allocation_date (the ledger date for the allocation, defaults to today), period_start and period_end (optional period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/supplier/{supplier}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","supplier",":supplier"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"supplier","value":"3","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"specific_line\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Allocate Cost Entry to Sales Channel","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-channel/{salesChannel}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-channel",":salesChannel"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesChannel","value":"2","description":"Sales channel ID"}]},"description":"Allocates part of a cost entry to a sales channel.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: amount (required, the amount to allocate), allocation_date (the ledger date for the allocation, defaults to today), period_start and period_end (optional period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 750,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-channel/{salesChannel}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-channel",":salesChannel"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesChannel","value":"2","description":"Sales channel ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"specific_line\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Allocate Cost Entry to Sales Order Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-order-line/{salesOrderLine}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-order-line",":salesOrderLine"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesOrderLine","value":"5501","description":"Sales order line ID"}]},"description":"Allocates part of a cost entry to a specific sales order line.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: amount (required, the amount to allocate), allocation_date (the ledger date for the allocation, defaults to today), period_start and period_end (optional period the cost applies to).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 120,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-order-line/{salesOrderLine}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-order-line",":salesOrderLine"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesOrderLine","value":"5501","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"cost_entry_id\": 42,\n    \"allocatable_type\": \"App\\\\Models\\\\Product\",\n    \"allocatable_type_label\": \"Product\",\n    \"allocatable_id\": 101,\n    \"allocatable\": {\n      \"id\": 101,\n      \"name\": \"Widget\",\n      \"sku\": \"WIDGET-001\"\n    },\n    \"allocation_date\": \"2026-06-01\",\n    \"period_start\": \"2026-06-01\",\n    \"period_end\": \"2026-06-30\",\n    \"amount\": 1000,\n    \"amount_in_tenant_currency\": 1000,\n    \"proration_strategy\": \"specific_line\",\n    \"proration_weight\": null,\n    \"amortization_period_id\": null,\n    \"is_amortized\": false,\n    \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Allocate Cost Entry by Proration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/proration","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","proration"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]},"description":"Allocates a cost entry across a custom list of products, splitting the amount by the chosen proration strategy.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired fields: strategy (straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual) and items (array of {product_id, quantity, revenue, cost, weight, volume} - the strategy determines which measure drives each product's share).\n\nOptional: amount (defaults to the entry's unallocated amount), allocation_date (defaults to today), period_start, period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"quantity_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\",\n  \"items\": [\n    {\n      \"product_id\": 101,\n      \"quantity\": 100,\n      \"revenue\": 0,\n      \"cost\": 0,\n      \"weight\": 0,\n      \"volume\": 0\n    },\n    {\n      \"product_id\": 102,\n      \"quantity\": 50,\n      \"revenue\": 0,\n      \"cost\": 0,\n      \"weight\": 0,\n      \"volume\": 0\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/proration","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","proration"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"cost_entry_id\": 42,\n      \"allocatable_type\": \"App\\\\Models\\\\Product\",\n      \"allocatable_type_label\": \"Product\",\n      \"allocatable_id\": 101,\n      \"allocatable\": {\n        \"id\": 101,\n        \"name\": \"Widget\",\n        \"sku\": \"WIDGET-001\"\n      },\n      \"allocation_date\": \"2026-06-01\",\n      \"period_start\": \"2026-06-01\",\n      \"period_end\": \"2026-06-30\",\n      \"amount\": 1000,\n      \"amount_in_tenant_currency\": 1000,\n      \"proration_strategy\": \"specific_line\",\n      \"proration_weight\": null,\n      \"amortization_period_id\": null,\n      \"is_amortized\": false,\n      \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Allocate Cost Entry to Purchase Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/purchase-order/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","purchase-order",":purchaseOrder"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"purchaseOrder","value":"88","description":"Purchase order ID"}]},"description":"Allocates the cost entry across the lines of a purchase order, creating one allocation per product using the chosen proration strategy (default cost_based).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: strategy (optional proration strategy: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual), amount (optional - defaults to the cost entry's unallocated amount), allocation_date (defaults to today), period_start and period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"cost_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/purchase-order/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","purchase-order",":purchaseOrder"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"purchaseOrder","value":"88","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Allocated to 3 products from the lines of a purchase order\",\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Allocate Cost Entry to Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-order/{salesOrder}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-order",":salesOrder"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesOrder","value":"1204","description":"Sales order ID"}]},"description":"Allocates the cost entry across the lines of a sales order, creating one allocation per product using the chosen proration strategy (default revenue_based).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: strategy (optional proration strategy: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual), amount (optional - defaults to the cost entry's unallocated amount), allocation_date (defaults to today), period_start and period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"revenue_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/sales-order/{salesOrder}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","sales-order",":salesOrder"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"salesOrder","value":"1204","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Allocated to 3 products from the lines of a sales order\",\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Allocate Cost Entry to Warehouse Transfer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/warehouse-transfer/{warehouseTransfer}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","warehouse-transfer",":warehouseTransfer"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"warehouseTransfer","value":"512","description":"Warehouse transfer ID"}]},"description":"Allocates the cost entry across the lines of a warehouse transfer, creating one allocation per product using the chosen proration strategy (default quantity_based).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: strategy (optional proration strategy: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual), amount (optional - defaults to the cost entry's unallocated amount), allocation_date (defaults to today), period_start and period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"quantity_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/warehouse-transfer/{warehouseTransfer}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","warehouse-transfer",":warehouseTransfer"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"warehouseTransfer","value":"512","description":"Warehouse transfer ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Allocated to 3 products from the lines of a warehouse transfer\",\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Allocate Cost Entry to Inventory Assembly","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/inventory-assembly/{inventoryAssembly}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","inventory-assembly",":inventoryAssembly"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"inventoryAssembly","value":"33","description":"Inventory assembly ID"}]},"description":"Allocates the cost entry across the component lines of an inventory assembly, creating one allocation per product using the chosen proration strategy (default cost_based).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: strategy (optional proration strategy: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual), amount (optional - defaults to the cost entry's unallocated amount), allocation_date (defaults to today), period_start and period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"cost_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/inventory-assembly/{inventoryAssembly}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","inventory-assembly",":inventoryAssembly"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"inventoryAssembly","value":"33","description":"Inventory assembly ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Allocated to 3 products from the component lines of an inventory assembly\",\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Allocate Cost Entry to Stock Take","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/stock-take/{stockTake}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","stock-take",":stockTake"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"stockTake","value":"19","description":"Stock take ID"}]},"description":"Allocates the cost entry across the items of a stock take, creating one allocation per product using the chosen proration strategy (default quantity_based).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: strategy (optional proration strategy: straight_line, front_loaded, back_loaded, revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual), amount (optional - defaults to the cost entry's unallocated amount), allocation_date (defaults to today), period_start and period_end.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"strategy\": \"quantity_based\",\n  \"amount\": 1500,\n  \"allocation_date\": \"2026-06-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entries/{costEntry}/allocate/stock-take/{stockTake}","host":["{{baseUrl}}"],"path":["api","cost-entries",":costEntry","allocate","stock-take",":stockTake"],"variable":[{"key":"costEntry","value":"42","description":"Cost entry ID"},{"key":"stockTake","value":"19","description":"Stock take ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Allocated to 3 products from the items of a stock take\",\n    \"allocations\": [\n      {\n        \"id\": 88,\n        \"cost_entry_id\": 42,\n        \"allocatable_type\": \"App\\\\Models\\\\Product\",\n        \"allocatable_type_label\": \"Product\",\n        \"allocatable_id\": 101,\n        \"allocatable\": {\n          \"id\": 101,\n          \"name\": \"Widget\",\n          \"sku\": \"WIDGET-001\"\n        },\n        \"allocation_date\": \"2026-06-01\",\n        \"period_start\": \"2026-06-01\",\n        \"period_end\": \"2026-06-30\",\n        \"amount\": 1000,\n        \"amount_in_tenant_currency\": 1000,\n        \"proration_strategy\": \"specific_line\",\n        \"proration_weight\": null,\n        \"amortization_period_id\": null,\n        \"is_amortized\": false,\n        \"created_at\": \"2026-06-01T10:05:00.000000Z\",\n        \"updated_at\": \"2026-06-01T10:05:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"List Cost Entry Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entry-types","host":["{{baseUrl}}"],"path":["api","cost-entry-types"]},"description":"Returns all cost entry types, ordered alphabetically by name. Cost entry types are user-defined categories used to classify cost entries (for example Freight, Duty, Warehousing) for landed cost and profitability tracking.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis endpoint is not paginated and accepts no filter or sort parameters - the complete list is always returned.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-entry-types","host":["{{baseUrl}}"],"path":["api","cost-entry-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Duty\",\n      \"created_at\": \"2026-05-12T09:31:00.000000Z\",\n      \"updated_at\": \"2026-05-12T09:31:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Freight\",\n      \"created_at\": \"2026-05-12T09:30:00.000000Z\",\n      \"updated_at\": \"2026-05-12T09:30:00.000000Z\"\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Warehousing\",\n      \"created_at\": \"2026-05-20T14:05:00.000000Z\",\n      \"updated_at\": \"2026-05-20T14:05:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Cost Entry Type","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entry-types","host":["{{baseUrl}}"],"path":["api","cost-entry-types"]},"description":"Creates a new cost entry type.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- name (required, string, max 100 characters): display name of the category, e.g. \"Freight\", \"Duty\" or \"Warehousing\".\n\nReturns the created cost entry type. Note that this endpoint returns HTTP 200 (not 201) on success.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).","body":{"mode":"raw","raw":"{\n  \"name\": \"Freight\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cost-entry-types","host":["{{baseUrl}}"],"path":["api","cost-entry-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Freight\",\n    \"created_at\": \"2026-05-12T09:30:00.000000Z\",\n    \"updated_at\": \"2026-05-12T09:30:00.000000Z\"\n  }\n}"}]},{"name":"Get Cost Entry Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"2","description":"Cost entry type ID"}]},"description":"Returns a single cost entry type by ID.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"2","description":"Cost entry type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Freight\",\n    \"created_at\": \"2026-05-12T09:30:00.000000Z\",\n    \"updated_at\": \"2026-05-12T09:30:00.000000Z\"\n  }\n}"}]},{"name":"Update Cost Entry Type","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"2","description":"Cost entry type ID"}]},"description":"Updates the name of an existing cost entry type. Cost entries already assigned to the type keep their assignment and reflect the new name.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields:\n- name (required, string, max 100 characters): the new display name.\n\nReturns the updated cost entry type.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write).","body":{"mode":"raw","raw":"{\n  \"name\": \"Ocean Freight\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"2","description":"Cost entry type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Ocean Freight\",\n    \"created_at\": \"2026-05-12T09:30:00.000000Z\",\n    \"updated_at\": \"2026-06-15T11:42:00.000000Z\"\n  }\n}"}]},{"name":"Delete Cost Entry Type","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"5","description":"Cost entry type ID"}]},"description":"Deletes a cost entry type.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA type that is currently assigned to one or more cost entries cannot be deleted - the request fails with HTTP 422. Reassign or delete the cost entries using the type first.\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders` (read/write)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/cost-entry-types/{costEntryType}","host":["{{baseUrl}}"],"path":["api","cost-entry-types",":costEntryType"],"variable":[{"key":"costEntryType","value":"5","description":"Cost entry type ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost entry type deleted successfully.\"\n}"}]},{"name":"Get FIFO Layer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single FIFO layer by ID with related product and warehouse data.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFor layers produced by an outsourced manufacturing order, `origin.outsourced_purchase_order` carries the backing purchase order (`id`, `purchase_order_number`) the goods physically arrived through — the layer itself stays linked to the manufacturing output for production genealogy."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"product_id\": 10,\n    \"fifo_layer_date\": \"2024-01-15\",\n    \"sku\": \"PROD-A-001\",\n    \"product_name\": \"Product A\",\n    \"product_barcode\": \"123456789\",\n    \"batch_number\": \"LOT-2026-0042\",\n    \"manufacture_date\": \"2026-01-04T00:00:00.000000Z\",\n    \"expiry_date\": \"2026-07-04T00:00:00.000000Z\",\n    \"lot_notes\": \"Original shipped lot\",\n    \"days_to_expiry\": 18,\n    \"original_quantity\": 100,\n    \"fulfilled_quantity\": 40,\n    \"avg_cost\": 5.5,\n    \"total_cost\": 550,\n    \"origin\": {\n      \"link_type\": \"purchase_order\",\n      \"link_id\": 42,\n      \"name\": \"PO-2024-001\",\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"reference\": \"PO-2024-001\",\n      \"manufacturing_order\": null\n    },\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"is_fba\": false,\n    \"is_consignment\": false,\n    \"condition\": \"new\",\n    \"integration_unique_id\": null,\n    \"allocated_quantity\": 20,\n    \"available_quantity\": 60,\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Archive FIFO Layer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/archive","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a single FIFO layer. Only fully utilized layers (available_quantity === 0) can be archived.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/archive","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"fifo layer 1 archived successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"available_quantity\": 0,\n    \"archived_at\": \"2024-06-01T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive FIFO Layer","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a previously archived FIFO layer.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"fifo layer 1 unarchived successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive FIFO Layers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fifo-layers/archive","host":["{{baseUrl}}"],"path":["api","fifo-layers","archive"]},"description":"Archives multiple FIFO layers by ID. Only fully utilized layers are archived; partially available layers are skipped.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of FIFO layer IDs to archive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fifo-layers/archive","host":["{{baseUrl}}"],"path":["api","fifo-layers","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 of 3 fifo layers archived successfully.\"\n}"}]},{"name":"Bulk Unarchive FIFO Layers","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fifo-layers/unarchive","host":["{{baseUrl}}"],"path":["api","fifo-layers","unarchive"]},"description":"Unarchives multiple FIFO layers by ID.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of FIFO layer IDs to unarchive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fifo-layers/unarchive","host":["{{baseUrl}}"],"path":["api","fifo-layers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 of 3 fifo layers unarchived successfully.\"\n}"}]},{"name":"Check FIFO Layers Archivable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fifo-layers/archivable","host":["{{baseUrl}}"],"path":["api","fifo-layers","archivable"]},"description":"Checks whether each specified FIFO layer can be archived (i.e., available_quantity === 0). Returns a per-layer result with archivable flag and reason.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of FIFO layer IDs to check (min 1, must exist)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fifo-layers/archivable","host":["{{baseUrl}}"],"path":["api","fifo-layers","archivable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"archivable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"archivable\": false,\n      \"reason\": {\n        \"unfulfilledQuantity\": \"fifo layer 2 cannot be archived because it is not fully fulfilled.\"\n      }\n    }\n  ]\n}"}]},{"name":"Get FIFO Layer Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/inventory-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a paginated list of inventory movements linked to a specific FIFO layer.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/inventory-movements?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 100,\n      \"inventory_movement_date\": \"2024-01-15\",\n      \"product_id\": 10,\n      \"type\": {\n        \"name\": \"purchase_receipt\",\n        \"link_type\": \"purchase_order\",\n        \"link_id\": 42,\n        \"parent_link_id\": null,\n        \"detail_link_id\": null,\n        \"manufacturing_order\": null\n      },\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": 100,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"layer\": {\n        \"fifo_layer_id\": 1,\n        \"name\": \"PO-2024-001\"\n      },\n      \"fifo_layer_id\": 1,\n      \"reference\": \"PO-2024-001\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get FIFO Layer Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/activity-log?per_page=15&filter[search]=archive","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"archive","description":"Search in causer name, properties, event, or subject_type","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a paginated activity log for a specific FIFO layer. Shows who changed the layer and what was changed.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/activity-log?per_page=15&filter[search]=archive","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"archive","description":"Search in causer name, properties, event, or subject_type","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 500,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"FifoLayer\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"archived_at\": \"2024-06-01 12:00:00\"\n        },\n        \"old\": {\n          \"archived_at\": null\n        }\n      },\n      \"causer_name\": \"Dev User\",\n      \"created_at\": \"2024-06-01T12:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Recalculate Total Costs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fifo-layers/recalculate-total-costs","host":["{{baseUrl}}"],"path":["api","fifo-layers","recalculate-total-costs"]},"description":"Recalculates the total_cost field for the specified FIFO layers. Useful after manual avg_cost corrections.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of FIFO layer IDs to recalculate (min 1, must exist)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fifo-layers/recalculate-total-costs","host":["{{baseUrl}}"],"path":["api","fifo-layers","recalculate-total-costs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"Get FIFO Layer Parents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/parents","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","parents"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns the immediate (depth-1) parent FIFO layers consumed to produce the given output layer, with the aggregated quantity consumed from each parent. Used by the FIFO Layer detail page's 'Consumed From' panel to render the upstream lots that were assembled into this batch.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFor standard MO output layers, parents are resolved by walking inventory_movements where movement.fifo_layer_id points at a consumption (component) movement and the resulting upstream FIFO layer is the parent. For Simple Mode (assemble/disassemble) outputs, the same walk works because the consumption movements link back to component FIFO layers identically.\n\nReturns an empty `data` array for raw layers (e.g. purchase receipts) with no upstream consumption movements.\n\nResults are sorted: most recently produced parents first, then by largest quantity consumed.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fifo-layers/{id}/parents","host":["{{baseUrl}}"],"path":["api","fifo-layers",":id","parents"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"parent-3\",\n      \"fifo_layer_id\": 3,\n      \"entity_type\": \"purchase_order\",\n      \"reference\": \"PO-2024-014\",\n      \"batch_number\": \"LBL-2024-014\",\n      \"product_id\": 51,\n      \"product_name\": \"Adhesive Label 60x40\",\n      \"sku\": \"LBL-60x40\",\n      \"manufacture_date\": \"2024-05-01\",\n      \"fifo_layer_date\": \"2024-05-12\",\n      \"quantity_consumed\": 2,\n      \"lot_notes\": \"Original shipped lot\"\n    },\n    {\n      \"id\": \"parent-2\",\n      \"fifo_layer_id\": 2,\n      \"entity_type\": \"purchase_order\",\n      \"reference\": \"PO-2024-011\",\n      \"batch_number\": \"POUCH-2024-011\",\n      \"product_id\": 47,\n      \"product_name\": \"Empty 250g Pouch\",\n      \"sku\": \"POUCH-250\",\n      \"manufacture_date\": \"2024-04-28\",\n      \"fifo_layer_date\": \"2024-05-10\",\n      \"quantity_consumed\": 2,\n      \"lot_notes\": \"Original shipped lot\"\n    }\n  ]\n}"}]},{"name":"List FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fifo-layers?page=1&limit=15&sort=fifo_layer_date&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"fifo_layer_date","description":"Sort field. Prefix with - for descending (e.g. -fifo_layer_date). Allowed: id, fifo_layer_date, avg_cost, total_cost, original_quantity, fulfilled_quantity, created_at, updated_at","disabled":true},{"key":"search","value":"","description":"Search term across SKU, product name, reference","disabled":true},{"key":"archived","value":"0","description":"0 = exclude archived, 1 = include archived","disabled":true},{"key":"included[]","value":"","description":"Column names to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Column names to exclude from response","disabled":true}]},"description":"Returns a paginated list of FIFO layers. Supports filtering, sorting, and column inclusion/exclusion.\n\nAuthentication: Requires Bearer token.\n\nAllowed sorts: id, fifo_layer_date, avg_cost, total_cost, original_quantity, fulfilled_quantity, created_at, updated_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fifo-layers?page=1&limit=15&sort=fifo_layer_date&search=&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"limit","value":"15","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"fifo_layer_date","description":"Sort field. Prefix with - for descending (e.g. -fifo_layer_date). Allowed: id, fifo_layer_date, avg_cost, total_cost, original_quantity, fulfilled_quantity, created_at, updated_at","disabled":true},{"key":"search","value":"","description":"Search term across SKU, product name, reference","disabled":true},{"key":"archived","value":"0","description":"0 = exclude archived, 1 = include archived","disabled":true},{"key":"included[]","value":"","description":"Column names to include in response","disabled":true},{"key":"excluded[]","value":"","description":"Column names to exclude from response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"product_id\": 10,\n      \"fifo_layer_date\": \"2024-01-15\",\n      \"sku\": \"PROD-A-001\",\n      \"product_name\": \"Product A\",\n      \"product_barcode\": \"123456789\",\n      \"original_quantity\": 100,\n      \"fulfilled_quantity\": 40,\n      \"avg_cost\": 5.5,\n      \"total_cost\": 550,\n      \"origin\": {\n        \"link_type\": \"purchase_order\",\n        \"link_id\": 42,\n        \"name\": \"PO-2024-001\",\n        \"parent_link_id\": null,\n        \"detail_link_id\": null,\n        \"reference\": \"PO-2024-001\",\n        \"manufacturing_order\": null\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_fba\": false,\n      \"condition\": \"new\",\n      \"integration_unique_id\": null,\n      \"allocated_quantity\": 20,\n      \"available_quantity\": 60,\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"List SKU COGS Health","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health?page=1&per_page=50&sort_by=sku&sort_direction=asc&search=WIDGET&variation_min=5&variation_max=50","host":["{{baseUrl}}"],"path":["api","cogs","sku-health"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"50","description":"Items per page (default: 50)","disabled":true},{"key":"sort_by","value":"sku","description":"Sort field. Options: sku, product_name, unit_cost, variation_pct, total_quantity","disabled":true},{"key":"sort_direction","value":"asc","description":"Sort direction: asc or desc","disabled":true},{"key":"search","value":"WIDGET","description":"Search by SKU or product name","disabled":true},{"key":"variation_min","value":"5","description":"Minimum COGS variation percentage filter","disabled":true},{"key":"variation_max","value":"50","description":"Maximum COGS variation percentage filter","disabled":true}]},"description":"Returns paginated SKU COGS health metrics. Each item includes unit cost, initial COGS, statistics (min/max/median/avg/variation), and inventory totals.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort fields: sku, product_name, unit_cost, variation_pct, total_quantity (default: sku asc)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health?page=1&per_page=50&sort_by=sku&sort_direction=asc&search=WIDGET&variation_min=5&variation_max=50","host":["{{baseUrl}}"],"path":["api","cogs","sku-health"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"50","description":"Items per page (default: 50)","disabled":true},{"key":"sort_by","value":"sku","description":"Sort field. Options: sku, product_name, unit_cost, variation_pct, total_quantity","disabled":true},{"key":"sort_direction","value":"asc","description":"Sort direction: asc or desc","disabled":true},{"key":"search","value":"WIDGET","description":"Search by SKU or product name","disabled":true},{"key":"variation_min","value":"5","description":"Minimum COGS variation percentage filter","disabled":true},{"key":"variation_max","value":"50","description":"Maximum COGS variation percentage filter","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"product_id\": 101,\n      \"sku\": \"WIDGET-RED-L\",\n      \"product_name\": \"Red Widget Large\",\n      \"unit_cost\": 12.5,\n      \"initial_cogs\": 12,\n      \"cogs_statistics\": {\n        \"min\": 10,\n        \"max\": 15,\n        \"median\": 12.5,\n        \"avg\": 12.33,\n        \"variation_pct\": 16.67\n      },\n      \"inventory\": {\n        \"total_quantity\": 500,\n        \"total_value\": 6250,\n        \"active_layer_count\": 3\n      }\n    }\n  ],\n  \"per_page\": 50,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Search SKU COGS Health","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health","host":["{{baseUrl}}"],"path":["api","cogs","sku-health"]},"description":"Returns the same paginated per-SKU COGS health table as the GET version of this endpoint, but accepts its parameters in a JSON request body. Each row aggregates a product's cost-of-goods statistics (min, max, median, average, and percentage variation) across its active FIFO cost layers, alongside current inventory totals.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUnlike the other advanced list endpoints, this one does not accept a `filter_groups` tree. It reads a small, fixed set of fields:\n- `search`: matches against SKU or product name.\n- `variation_min` / `variation_max`: bound the COGS variation percentage.\n- `sort_by`: column to sort by (defaults to `sku`).\n- `sort_direction`: `asc` or `desc` (defaults to `asc`).\n- `page` / `per_page`: pagination (per_page defaults to 50).","body":{"mode":"raw","raw":"{\n  \"search\": \"WIDGET\",\n  \"variation_min\": 15,\n  \"variation_max\": 100,\n  \"sort_by\": \"variation_pct\",\n  \"sort_direction\": \"desc\",\n  \"page\": 1,\n  \"per_page\": 50\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs/sku-health","host":["{{baseUrl}}"],"path":["api","cogs","sku-health"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 3312,\n      \"sku\": \"WIDGET-BLUE-01\",\n      \"product_name\": \"Blue Widget\",\n      \"unit_cost\": 13.75,\n      \"initial_cogs\": 12.5,\n      \"cogs_statistics\": {\n        \"min\": 11.2,\n        \"max\": 15.9,\n        \"median\": 13.4,\n        \"avg\": 13.62,\n        \"variation_pct\": 34.8\n      },\n      \"inventory\": {\n        \"total_quantity\": 240,\n        \"total_value\": 3268.8,\n        \"active_layer_count\": 5\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 50,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 3,\n  \"total\": 118,\n  \"next_page_url\": \"https://api.example.com/api/cogs/sku-health?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Get SKU COGS Health Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/summary?search=WIDGET&variation_min=5&variation_max=50","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","summary"],"query":[{"key":"search","value":"WIDGET","description":"Filter by SKU or product name","disabled":true},{"key":"variation_min","value":"5","description":"Minimum variation % filter","disabled":true},{"key":"variation_max","value":"50","description":"Maximum variation % filter","disabled":true}]},"description":"Returns aggregate summary statistics for the COGS health dashboard — totals across all SKUs matching the given filters.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/summary?search=WIDGET&variation_min=5&variation_max=50","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","summary"],"query":[{"key":"search","value":"WIDGET","description":"Filter by SKU or product name","disabled":true},{"key":"variation_min","value":"5","description":"Minimum variation % filter","disabled":true},{"key":"variation_max","value":"50","description":"Maximum variation % filter","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_products\": 120,\n    \"products_with_variation\": 35,\n    \"avg_variation_pct\": 8.42,\n    \"max_variation_pct\": 52.1,\n    \"total_inventory_value\": 485320.75,\n    \"products_at_risk\": 12\n  }\n}"}]},{"name":"Get SKU COGS Health Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns detailed COGS health metrics for a specific product by product ID.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Scope:** The top-level metrics (`cogs_avg`, `cogs_min`, `cogs_max`, `cogs_median`, `variation_pct`, `total_quantity`, `total_value`, `active_layer_count`, `init_cogs`) cover the **warehouse FIFO ledger only**. Amazon FBA stock — which uses a separate WAC ledger and has no `warehouse_id` — is intentionally excluded so this matches the cache-backed `inventory_avg_cost` displayed on the product Overview page.\n\n**Amazon FBA inventory** (if the product has any) is returned as a separate `amazon_summary` object with its own quantity-weighted average, min/max cost, layer count, and integration instance count. `amazon_summary` is `null` when the product has no Amazon FBA stock.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_id\": 101,\n    \"sku\": \"WIDGET-RED-L\",\n    \"product_name\": \"Red Widget Large\",\n    \"unit_cost\": 12.5,\n    \"init_cogs\": 12,\n    \"cogs_min\": 10,\n    \"cogs_max\": 15,\n    \"cogs_median\": 12.5,\n    \"cogs_avg\": 12.33,\n    \"cogs_stddev\": 1.85,\n    \"variation_pct\": 16.67,\n    \"total_quantity\": 500,\n    \"total_value\": 6250,\n    \"active_layer_count\": 3,\n    \"amazon_summary\": {\n      \"total_quantity\": 1010,\n      \"total_value\": 1304.92,\n      \"cogs_avg\": 1.292,\n      \"cogs_min\": 1.15,\n      \"cogs_max\": 1.42,\n      \"active_layer_count\": 4,\n      \"integration_instance_count\": 1\n    }\n  }\n}"}]},{"name":"Get All Value Sources","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/value-sources?page=1&per_page=50&sort_by=sku&sort_direction=asc&search=WIDGET","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","value-sources"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"50","description":"Items per page (default: 50)","disabled":true},{"key":"sort_by","value":"sku","description":"Sort field","disabled":true},{"key":"sort_direction","value":"asc","description":"Sort direction: asc or desc","disabled":true},{"key":"search","value":"WIDGET","description":"Search by SKU or product name","disabled":true}]},"description":"Returns paginated COGS value sources across all products.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/value-sources?page=1&per_page=50&sort_by=sku&sort_direction=asc&search=WIDGET","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","value-sources"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"50","description":"Items per page (default: 50)","disabled":true},{"key":"sort_by","value":"sku","description":"Sort field","disabled":true},{"key":"sort_direction","value":"asc","description":"Sort direction: asc or desc","disabled":true},{"key":"search","value":"WIDGET","description":"Search by SKU or product name","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"product_id\": 101,\n      \"sku\": \"WIDGET-RED-L\",\n      \"product_name\": \"Red Widget Large\",\n      \"value_source\": \"purchase_order\",\n      \"unit_cost\": 12.5\n    }\n  ],\n  \"per_page\": 50,\n  \"total\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Get Warehouse Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/warehouse-breakdown","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","warehouse-breakdown"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns the COGS warehouse breakdown for a specific product, showing how inventory and cost is distributed across warehouses.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/warehouse-breakdown","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","warehouse-breakdown"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"total_quantity\": 300,\n      \"total_value\": 3750,\n      \"avg_cost\": 12.5,\n      \"active_layer_count\": 2\n    },\n    {\n      \"warehouse_id\": 2,\n      \"warehouse_name\": \"Secondary Warehouse\",\n      \"total_quantity\": 200,\n      \"total_value\": 2500,\n      \"avg_cost\": 12.5,\n      \"active_layer_count\": 1\n    }\n  ]\n}"}]},{"name":"Get Initial Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/initial-inventory","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","initial-inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns the initial inventory breakdown by warehouse for a specific product.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/initial-inventory","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","initial-inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"quantity\": 200,\n      \"unit_cost\": 12,\n      \"total_value\": 2400\n    }\n  ]\n}"}]},{"name":"Get FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/fifo-layers?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","fifo-layers"],"query":[{"key":"warehouse_id","value":"1","description":"Optional: filter by warehouse ID","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns current active FIFO layers for a specific product, optionally filtered by warehouse.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/fifo-layers?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","fifo-layers"],"query":[{"key":"warehouse_id","value":"1","description":"Optional: filter by warehouse ID","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"fifo_layer_date\": \"2024-01-15T00:00:00.000000Z\",\n      \"original_quantity\": 100,\n      \"remaining_quantity\": 75,\n      \"unit_cost\": 12.5,\n      \"total_value\": 937.5,\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderReceiving\",\n      \"link_id\": 201\n    }\n  ]\n}"}]},{"name":"Get FIFO Layers Timeline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/fifo-layers-timeline?page=1&per_page=20&warehouse_id=1&warehouse_type=main","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","fifo-layers-timeline"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true},{"key":"warehouse_id","value":"1","description":"Optional: filter by warehouse ID","disabled":true},{"key":"warehouse_type","value":"main","description":"Optional: filter by warehouse type","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns paginated FIFO layer parent records (timeline) for a specific product. Used to show the historical sequence of inventory additions.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/fifo-layers-timeline?page=1&per_page=20&warehouse_id=1&warehouse_type=main","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","fifo-layers-timeline"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true},{"key":"warehouse_id","value":"1","description":"Optional: filter by warehouse ID","disabled":true},{"key":"warehouse_type","value":"main","description":"Optional: filter by warehouse type","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 501,\n      \"fifo_layer_date\": \"2024-01-15T00:00:00.000000Z\",\n      \"original_quantity\": 100,\n      \"unit_cost\": 12.5\n    },\n    {\n      \"id\": 502,\n      \"fifo_layer_date\": \"2024-02-01T00:00:00.000000Z\",\n      \"original_quantity\": 50,\n      \"unit_cost\": 13\n    }\n  ],\n  \"per_page\": 20,\n  \"total\": 2,\n  \"last_page\": 1\n}"}]},{"name":"Get Layer Consumptions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/layers/{id2}/consumptions?page=1&per_page=20&layer_type=regular","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","layers",":id2","consumptions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true},{"key":"layer_type","value":"regular","description":"Layer type filter (default: regular)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Returns paginated consumption records for a specific FIFO layer. Shows how the layer's quantity was consumed over time.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/layers/{id2}/consumptions?page=1&per_page=20&layer_type=regular","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","layers",":id2","consumptions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true},{"key":"layer_type","value":"regular","description":"Layer type filter (default: regular)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"quantity_consumed\": 10,\n      \"unit_cost\": 12.5,\n      \"consumed_at\": \"2024-01-20T14:30:00.000000Z\",\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 301\n    }\n  ],\n  \"per_page\": 20,\n  \"total\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Get Consumption Timeline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/consumption-timeline?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","consumption-timeline"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns paginated consumption timeline for a specific product — all historical consumption events in chronological order.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/consumption-timeline?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","consumption-timeline"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"20","description":"Items per page (default: 20)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"consumed_at\": \"2024-01-20T14:30:00.000000Z\",\n      \"quantity\": 10,\n      \"unit_cost\": 12.5,\n      \"total_cost\": 125\n    }\n  ],\n  \"per_page\": 20,\n  \"total\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Recalculate SKU COGS","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/recalculate","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","recalculate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Queues a COGS recalculation for all FIFO layers of a specific product as a background job. The request returns immediately with a `tracked_job_log_id` you can use to track progress; the updated costs land once the job completes. Returns a message only (no `tracked_job_log_id`) when the product has no FIFO layers to recalculate.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/{id}/recalculate","host":["{{baseUrl}}"],"path":["api","cogs","sku-health",":id","recalculate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"COGS recalculation started. Use the returned tracked_job_log_id to track progress.\"\n}"}]},{"name":"Export SKU COGS Health","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs/sku-health/export","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","export"]},"description":"Export SKU COGS health metrics as spreadsheet-ready JSON rows. Unlike file-download exports, this endpoint returns the rows in the JSON response body (keyed by column heading) so the caller can save them as CSV/XLSX. Returns up to 10,000 products.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach row reports the cost-of-goods-sold consistency for one product: initial COGS, current unit cost, and the min / max / median / average COGS across its active cost layers, plus the variation percentage between layers. `Valuation Method` is WAC when the product carries Amazon FBA stock (valued on a weighted-average ledger), otherwise FIFO. Monetary values are formatted strings with thousands separators.\n\nFilters (all optional):\n- `search` — matches product SKU or product name (partial match).\n- `variation_min` / `variation_max` — only products whose COGS variation percentage is within the given bounds.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs/sku-health/export","host":["{{baseUrl}}"],"path":["api","cogs","sku-health","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"data\": [\n      {\n        \"SKU\": \"WIDGET-001\",\n        \"Product Name\": \"Blue Widget\",\n        \"Valuation Method\": \"FIFO\",\n        \"Init COGS\": \"10.00\",\n        \"Unit Cost\": \"12.50\",\n        \"Variation %\": \"18.25\",\n        \"Low COGS\": \"10.00\",\n        \"High COGS\": \"14.75\",\n        \"Median COGS\": \"12.20\",\n        \"Avg COGS\": \"12.35\",\n        \"Total Qty\": 240,\n        \"Total Value\": \"2,964.00\",\n        \"Active Layers\": 3\n      },\n      {\n        \"SKU\": \"GADGET-002\",\n        \"Product Name\": \"Red Gadget\",\n        \"Valuation Method\": \"WAC\",\n        \"Init COGS\": \"22.00\",\n        \"Unit Cost\": \"21.40\",\n        \"Variation %\": \"4.10\",\n        \"Low COGS\": \"21.00\",\n        \"High COGS\": \"22.60\",\n        \"Median COGS\": \"21.40\",\n        \"Avg COGS\": \"21.55\",\n        \"Total Qty\": 88,\n        \"Total Value\": \"1,896.40\",\n        \"Active Layers\": 2\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Inventory Revaluations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation","host":["{{baseUrl}}"],"path":["api","cogs-revaluation"]},"description":"List the inventory revaluation ledger (paginated). Every FIFO-layer cost change writes one dated row here.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token (PAT).\n\n**Methods:** GET (query params) or POST (same params in the JSON body — use POST when a large `filter_groups` tree exceeds URL limits).\n\n**Search** — `filter[search]` spans: ID (exact), FIFO Layer ID (exact), product SKU, product name, warehouse name, and reason notes.\n\n**Flat filters** — every column below also supports operator-suffixed variants (e.g. `filter[new_unit_cost.greater_than]`, `filter[effective_at.between]`, `filter[reason.is_one_of]`):\n- Text (`reason`, `cogs_source`, `reason_notes`, `sku`, `product_name`): contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty\n- Numeric (`id`, `fifo_layer_id`, `old_unit_cost`, `new_unit_cost`, `units_on_hand_at_time`, `product_id`, `warehouse_id`, `warehouse`): is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty\n- Datetime (`effective_at`, `posted_at`, `created_at`): is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, days_ago, past_days, is_empty, is_not_empty (timezone-aware)\n- Legacy: `filter[effective_from]` / `filter[effective_to]` (date bounds on effective_at, kept for backward compatibility)\n\n**Grouped filters** — `filter_groups` accepts a base64-encoded JSON tree with AND/OR conjunctions and nested groups (the Advanced Filters modal format):\n```json\n{\n  \"conjunction\": \"and\",\n  \"children\": [\n    {\"type\": \"condition\", \"condition\": {\"column\": \"reason\", \"operator\": \"is\", \"value\": \"landed_cost_added\"}},\n    {\"type\": \"group\", \"group\": {\"conjunction\": \"or\", \"children\": [...]}}\n  ]\n}\n```\nVia POST, `filter_groups` may be sent as a plain (non-encoded) JSON object in the body. Unregistered columns return 400.\n\n**Reason values:** landed_cost_added, vendor_invoice_correction, market_value_adjustment, system_error, other.\n\n**Allowed sorts:** id, effective_at, posted_at, new_unit_cost, old_unit_cost, reason, cogs_source, created_at, product (by product SKU), warehouse (by warehouse name). Prefix with `-` for DESC. Default: `-effective_at`.\n\n**Pagination:** `page` + `per_page` (default 10).\n\n**Cross-links:** each row carries `link_reference`, `link_type_label`, `link_route` pointing at the FIFO layer detail page. `effective_at` is the value date (drives the valuation report); `posted_at` is the booking date."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation","host":["{{baseUrl}}"],"path":["api","cogs-revaluation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"fifo_layer_id\": 501,\n      \"reason\": \"landed_cost_added\",\n      \"reason_label\": \"Landed Cost Added\",\n      \"reason_notes\": \"Freight + duties allocated from customs invoice CI-4471\",\n      \"cogs_source\": \"manual\",\n      \"cost_version_before\": 2,\n      \"cost_version_after\": 3,\n      \"old_unit_cost\": 10,\n      \"new_unit_cost\": 12.33,\n      \"unit_cost_delta\": 2.33,\n      \"old_total_cost\": 1000,\n      \"new_total_cost\": 1233,\n      \"total_cost_delta\": 233,\n      \"units_on_hand_at_time\": 80,\n      \"units_consumed_at_time\": 20,\n      \"effective_at\": \"2026-05-01T00:00:00.000000Z\",\n      \"posted_at\": \"2026-05-01T00:00:00.000000Z\",\n      \"created_at\": \"2026-05-01T14:22:10.000000Z\",\n      \"user\": {\n        \"id\": 7,\n        \"name\": \"Jane Operator\"\n      },\n      \"fifo_layer\": {\n        \"id\": 501,\n        \"fifo_layer_date\": \"2026-03-15T00:00:00.000000Z\",\n        \"original_quantity\": 100,\n        \"available_quantity\": 80,\n        \"avg_cost\": 12.33,\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrderReceiving\",\n        \"link_id\": 3120,\n        \"link_reference\": \"PO-10044\"\n      },\n      \"product\": {\n        \"id\": 101,\n        \"sku\": \"WIDGET-RED-L\",\n        \"name\": \"Red Widget Large\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"link_reference\": \"PO-10044\",\n      \"link_type_label\": \"FIFO Layer\",\n      \"link_route\": \"/inventory/fifo-layers/501\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/cogs-revaluation?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/cogs-revaluation?page=5\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/cogs-revaluation?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/cogs-revaluation\"\n}"}]},{"name":"Search COGS Revaluations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation","host":["{{baseUrl}}"],"path":["api","cogs-revaluation"]},"description":"Returns the same paginated inventory revaluation ledger as the GET version of this endpoint, but accepts filters as a JSON request body instead of the query string. Use this POST variant when the filter set is too large or too complex to fit in a URL (for example, deeply nested AND/OR filter groups or long lists of values).\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nProvide advanced filters under `filter_groups`, a tree of conditions combined with a `conjunction` of `and` or `or`. Each condition names a `column`, an `operator`, and a `value`.\n\nText columns (`reason`, `cogs_source`, `reason_notes`, `sku`, `product_name`) accept: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of, is_not_one_of.\nNumeric and date columns (`id`, `fifo_layer_id`, `old_unit_cost`, `new_unit_cost`, `units_on_hand_at_time`, `product_id`, `warehouse_id`, `effective_at`, `posted_at`, `created_at`) accept: is, is_not, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, is_empty, is_not_empty.\n\nSortable columns (via `sort`, prefix with `-` for descending): id, effective_at, posted_at, new_unit_cost, old_unit_cost, reason, cogs_source, created_at, product, warehouse. Results default to `-effective_at`. The legacy `effective_from` / `effective_to` date-range filters remain supported.","body":{"mode":"raw","raw":"{\n  \"per_page\": 25,\n  \"page\": 1,\n  \"sort\": \"-effective_at\",\n  \"filter_groups\": {\n    \"conjunction\": \"and\",\n    \"children\": [\n      {\n        \"type\": \"condition\",\n        \"condition\": {\n          \"column\": \"reason\",\n          \"operator\": \"is\",\n          \"value\": \"recalculation\"\n        }\n      },\n      {\n        \"type\": \"group\",\n        \"group\": {\n          \"conjunction\": \"or\",\n          \"children\": [\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"new_unit_cost\",\n                \"operator\": \"greater_than\",\n                \"value\": 10\n              }\n            },\n            {\n              \"type\": \"condition\",\n              \"condition\": {\n                \"column\": \"sku\",\n                \"operator\": \"contains\",\n                \"value\": \"WIDGET\"\n              }\n            }\n          ]\n        }\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation","host":["{{baseUrl}}"],"path":["api","cogs-revaluation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"fifo_layer_id\": 90312,\n      \"reason\": \"recalculation\",\n      \"reason_label\": \"Recalculation\",\n      \"reason_notes\": \"COGS rebuild after supplier price correction\",\n      \"cogs_source\": \"fifo\",\n      \"cost_version_before\": 3,\n      \"cost_version_after\": 4,\n      \"old_unit_cost\": 12.5,\n      \"new_unit_cost\": 13.75,\n      \"unit_cost_delta\": 1.25,\n      \"old_total_cost\": 250,\n      \"new_total_cost\": 275,\n      \"total_cost_delta\": 25,\n      \"units_on_hand_at_time\": 20,\n      \"units_consumed_at_time\": 0,\n      \"effective_at\": \"2026-06-30T14:02:11.000000Z\",\n      \"posted_at\": \"2026-06-30T14:02:12.000000Z\",\n      \"created_at\": \"2026-06-30T14:02:12.000000Z\",\n      \"user\": {\n        \"id\": 7,\n        \"name\": \"Jane Doe\"\n      },\n      \"fifo_layer\": {\n        \"id\": 90312,\n        \"fifo_layer_date\": \"2026-05-01T00:00:00.000000Z\",\n        \"original_quantity\": 20,\n        \"available_quantity\": 20,\n        \"avg_cost\": 13.75,\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceiptLine\",\n        \"link_id\": 55210,\n        \"link_reference\": \"PO-1042\"\n      },\n      \"product\": {\n        \"id\": 3312,\n        \"sku\": \"WIDGET-BLUE-01\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"link_reference\": \"PO-1042\",\n      \"link_type_label\": \"FIFO Layer\",\n      \"link_route\": \"/inventory/fifo-layers/90312\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 25,\n  \"from\": 1,\n  \"to\": 1,\n  \"last_page\": 6,\n  \"total\": 138,\n  \"next_page_url\": \"https://api.example.com/api/cogs-revaluation?page=2\",\n  \"prev_page_url\": null\n}"}]},{"name":"Get Variation by Product Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/variation-by-product?variation_threshold=5","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","variation-by-product"],"query":[{"key":"variation_threshold","value":"5","description":"Minimum variation % to include a product (numeric, min 5, default 5)","disabled":true}]},"description":"Returns a report of products whose COGS varies significantly across FIFO layers. Products with cost variation above the threshold are flagged for revaluation review.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- variation_threshold (optional): Minimum variation % to include, numeric, min 5, default 5"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/variation-by-product?variation_threshold=5","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","variation-by-product"],"query":[{"key":"variation_threshold","value":"5","description":"Minimum variation % to include a product (numeric, min 5, default 5)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"product_id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"avg_cost\": 12.5,\n      \"min_cost\": 8,\n      \"max_cost\": 18.75,\n      \"variation_percentage\": 85,\n      \"layer_count\": 5\n    },\n    {\n      \"product_id\": 78,\n      \"sku\": \"GADGET-XL\",\n      \"name\": \"XL Gadget\",\n      \"avg_cost\": 45,\n      \"min_cost\": 38,\n      \"max_cost\": 55,\n      \"variation_percentage\": 36.8,\n      \"layer_count\": 3\n    }\n  ]\n}"}]},{"name":"Get Product COGS Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/product-report/{id}?outlier_threshold=5","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","product-report",":id"],"query":[{"key":"outlier_threshold","value":"5","description":"Outlier detection threshold % (numeric, min 5, max 100, default 5)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a detailed COGS report for a specific product, including all FIFO layers and their costs.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- product: Product ID\n\nQuery params:\n- outlier_threshold (optional): Percentage threshold for detecting cost outliers (5-100, default 5)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/product-report/{id}?outlier_threshold=5","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","product-report",":id"],"query":[{"key":"outlier_threshold","value":"5","description":"Outlier detection threshold % (numeric, min 5, max 100, default 5)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"name\": \"Blue Widget\",\n    \"avg_cost\": 12.5,\n    \"outlier_threshold\": 5,\n    \"fifo_layers\": [\n      {\n        \"id\": 101,\n        \"fifo_layer_date\": \"2024-01-15T00:00:00.000000Z\",\n        \"unit_cost\": 8,\n        \"original_quantity\": 500,\n        \"remaining_quantity\": 200,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"is_outlier\": true\n      }\n    ]\n  }\n}"}]},{"name":"Get FIFO Layer COGS Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/fifo-report/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","fifo-report",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a detailed COGS report for a specific FIFO layer including cost history and revaluation events.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- fifoLayer: FIFO Layer ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/fifo-report/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","fifo-report",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"fifo_layer_id\": 101,\n    \"product_id\": 42,\n    \"sku\": \"WIDGET-001\",\n    \"unit_cost\": 12.5,\n    \"original_quantity\": 500,\n    \"remaining_quantity\": 200,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"fifo_layer_date\": \"2024-01-15T00:00:00.000000Z\",\n    \"revaluations\": [\n      {\n        \"id\": 55,\n        \"old_unit_cost\": 8,\n        \"new_unit_cost\": 12.5,\n        \"reason\": \"purchase_cost_update\",\n        \"posted_at\": \"2024-03-01T09:00:00.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Bulk FIFO Layer COGS Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/bulk-fifo-report?ids[]=101","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","bulk-fifo-report"],"query":[{"key":"ids[]","value":"101","description":"FIFO Layer IDs (required array, min 1)","disabled":true}]},"description":"Returns COGS reports for multiple FIFO layers in a single request.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- ids (required): Array of FIFO Layer IDs"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/bulk-fifo-report?ids[]=101","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","bulk-fifo-report"],"query":[{"key":"ids[]","value":"101","description":"FIFO Layer IDs (required array, min 1)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"fifo_layer_id\": 101,\n      \"unit_cost\": 12.5,\n      \"product_sku\": \"WIDGET-001\",\n      \"original_quantity\": 500\n    },\n    {\n      \"fifo_layer_id\": 102,\n      \"unit_cost\": 9.75,\n      \"product_sku\": \"GADGET-XL\",\n      \"original_quantity\": 250\n    }\n  ]\n}"}]},{"name":"Revalue FIFO Layer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/{id}/revalue","host":["{{baseUrl}}"],"path":["api","cogs-revaluation",":id","revalue"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Revalues a single FIFO layer to a new unit cost, creating an InventoryRevaluation record.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields (CreateInventoryRevaluationData):\n- cogs_source (required, CogsSourceEnum): the source for the new cost (e.g., purchase_order)\n- new_unit_cost (required, float): the new per-unit cost\n- reason (optional, InventoryRevaluationReasonEnum): reason for revaluation\n- reason_notes (optional, string): free-text notes\n- effective_at (optional, date-only YYYY-MM-DD or ISO 8601 datetime): date the cost change takes effect; drives the point-in-time valuation overlay and the GL revaluation period. Defaults to now(). If it falls inside a locked accounting period it is moved forward to the first open day.\n- posted_at (optional, date-only YYYY-MM-DD or ISO 8601 datetime): GL posting timestamp. Defaults to now().\n- old_unit_cost (optional, float): explicit prior per-unit cost; defaults to the layer's current average cost.\n- old_total_cost (optional, float): explicit prior total cost for the layer.\n- new_total_cost (optional, float): explicit new total cost for the layer.","body":{"mode":"raw","raw":"{\n  \"cogs_source\": \"purchase_order\",\n  \"new_unit_cost\": 12.33,\n  \"reason\": \"manual_adjustment\",\n  \"reason_notes\": \"Correcting cost based on updated supplier invoice\",\n  \"effective_at\": \"2026-04-01\",\n  \"posted_at\": \"2024-06-01T00:00:00Z\",\n  \"old_unit_cost\": 10,\n  \"old_total_cost\": 1000,\n  \"new_total_cost\": 1233\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/{id}/revalue","host":["{{baseUrl}}"],"path":["api","cogs-revaluation",":id","revalue"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"success\"\n}"}]},{"name":"Bulk Revalue FIFO Layers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/bulk-revalue","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","bulk-revalue"]},"description":"Revalues multiple FIFO layers in a single request.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- layerDataItems (required): Array of layer revaluation items\n  - layerDataItems.*.fifo_layer_id: FIFO Layer ID\n  - layerDataItems.*.cogs_source: Source of the cost value\n  - layerDataItems.*.new_unit_cost: New unit cost as float\n  - layerDataItems.*.effective_at (optional, date-only YYYY-MM-DD or ISO 8601 datetime): Date the cost change takes effect (per item); defaults to now(), moved to the first open day if the period is locked\n  - layerDataItems.*.posted_at (optional): GL posting timestamp (per item); defaults to now()\n  - layerDataItems.*.old_unit_cost (optional): Explicit prior per-unit cost (per item)\n  - layerDataItems.*.old_total_cost (optional): Explicit prior total cost (per item)\n  - layerDataItems.*.new_total_cost (optional): Explicit new total cost (per item)\n- reason (required): Reason enum value applied to all items\n- reason_notes (optional): Free-text explanation","body":{"mode":"raw","raw":"{\n  \"layerDataItems\": [\n    {\n      \"fifo_layer_id\": 101,\n      \"cogs_source\": \"purchase_order\",\n      \"new_unit_cost\": 14.99,\n      \"effective_at\": \"2026-04-01\",\n      \"old_unit_cost\": 12\n    },\n    {\n      \"fifo_layer_id\": 102,\n      \"cogs_source\": \"manual\",\n      \"new_unit_cost\": 22.5\n    }\n  ],\n  \"reason\": \"purchase_cost_update\",\n  \"reason_notes\": \"Quarterly cost reconciliation\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/bulk-revalue","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","bulk-revalue"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"Rebuild COGS for Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Rebuilds COGS (recalculates FIFO layer costs from source documents) for a single product. This is a synchronous operation.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- product: Product ID"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"COGS rebuilt successfully\"\n}"}]},{"name":"Rebuild COGS for Multiple Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs-bulk","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs-bulk"]},"description":"Rebuilds COGS for multiple specific products synchronously. Returns per-product success/failure summary.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- product_ids (required): Array of product IDs (min 1, must exist in products table)","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    42,\n    78,\n    99\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs-bulk","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs-bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Successfully rebuilt COGS for 3 products\",\n  \"data\": {\n    \"product_count\": 3,\n    \"failed_count\": 0,\n    \"errors\": []\n  }\n}"}]},{"name":"Start Tracked COGS Rebuild","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs-tracked","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs-tracked"]},"description":"Starts a background tracked COGS rebuild job for all products (or a filtered subset). Returns a tracked_job_id to poll for progress.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- last_rebuilt_before (optional): Only rebuild products rebuilt before this date\n- product_ids (optional): Array of specific product IDs to rebuild. If omitted, rebuilds all products","body":{"mode":"raw","raw":"{\n  \"last_rebuilt_before\": \"2024-01-01\",\n  \"product_ids\": [\n    42,\n    78\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/rebuild-cogs-tracked","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","rebuild-cogs-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Tracked COGS rebuild started successfully\",\n  \"data\": {\n    \"tracked_job_id\": 1234\n  }\n}"}]},{"name":"Get Tracked Job Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/tracked-job/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","tracked-job",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Polls the status and progress of a tracked COGS rebuild job.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- trackedJobId: Tracked job log ID from startTrackedRebuild response"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/tracked-job/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","tracked-job",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1234,\n    \"status\": \"processing\",\n    \"progress_percentage\": 65.5,\n    \"total_items\": 200,\n    \"processed_items\": 131,\n    \"messages\": null,\n    \"results\": {\n      \"batch_ids\": [\n        \"abc-123\",\n        \"def-456\"\n      ]\n    },\n    \"batch_progress\": {\n      \"total_jobs\": 20,\n      \"pending_jobs\": 7,\n      \"processed_jobs\": 13,\n      \"failed_jobs\": 0,\n      \"finished\": false,\n      \"cancelled\": false,\n      \"progress_percentage\": 65,\n      \"chunks_count\": 2\n    },\n    \"created_at\": \"2024-06-15T10:00:00.000000Z\",\n    \"attempted_at\": \"2024-06-15T10:00:05.000000Z\",\n    \"completed_at\": null\n  }\n}"}]},{"name":"Get Unified Tracking Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/unified-tracking/{id}?since=2024-06-15T10:00:00Z&limit=50","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","unified-tracking",":id"],"query":[{"key":"since","value":"2024-06-15T10:00:00Z","description":"Show recently rebuilt products since this datetime (default: 1 hour ago)","disabled":true},{"key":"limit","value":"50","description":"Max recently rebuilt products to return (integer 1-1000, default 100)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns combined job status, recently rebuilt products, FIFO layer changes, and failed products in a single call. Replaces polling multiple endpoints.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- trackedJobId: Tracked job log ID\n\nQuery params:\n- since (optional): Show products rebuilt after this datetime (default: 1 hour ago)\n- limit (optional): Max recently rebuilt products to return (1-1000, default 100)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/unified-tracking/{id}?since=2024-06-15T10:00:00Z&limit=50","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","unified-tracking",":id"],"query":[{"key":"since","value":"2024-06-15T10:00:00Z","description":"Show recently rebuilt products since this datetime (default: 1 hour ago)","disabled":true},{"key":"limit","value":"50","description":"Max recently rebuilt products to return (integer 1-1000, default 100)","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"job_status\": {\n      \"id\": 1234,\n      \"status\": \"processing\",\n      \"progress_percentage\": 65.5,\n      \"total_items\": 200,\n      \"processed_items\": 131,\n      \"results\": {\n        \"batch_ids\": [\n          \"abc-123\"\n        ]\n      },\n      \"batch_progress\": {\n        \"total_jobs\": 20,\n        \"processed_jobs\": 13,\n        \"finished\": false\n      },\n      \"created_at\": \"2024-06-15T10:00:00.000000Z\",\n      \"attempted_at\": \"2024-06-15T10:00:05.000000Z\",\n      \"completed_at\": null\n    },\n    \"recently_rebuilt_products\": [\n      {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Blue Widget\",\n        \"last_rebuilt_cogs_at\": \"2024-06-15T10:05:00.000000Z\"\n      }\n    ],\n    \"fifo_layer_changes\": [\n      {\n        \"fifo_layer_id\": 101,\n        \"product_sku\": \"WIDGET-001\",\n        \"product_name\": \"Blue Widget\",\n        \"warehouse_name\": \"Main Warehouse\",\n        \"before_cost\": 8,\n        \"after_cost\": 12.5,\n        \"cost_difference\": 4.5,\n        \"cost_change_percentage\": 56.25,\n        \"changed_at\": \"2024-06-15T10:05:00.000000Z\",\n        \"reason\": \"rebuild\",\n        \"cogs_source\": \"purchase_order\"\n      }\n    ],\n    \"failed_products\": []\n  }\n}"}]},{"name":"Cancel Tracked Rebuild","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/cancel-tracked-rebuild/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","cancel-tracked-rebuild",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Cancels a running tracked COGS rebuild job. Cancels all associated batch jobs and marks the tracked job as cancelled.\n\n**Required scope: `inventory:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- trackedJobId: Tracked job log ID\n\nNote: Returns 400 if the job is already completed, failed, or cancelled."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/cancel-tracked-rebuild/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","cancel-tracked-rebuild",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Job cancelled successfully - 2 batch(es) cancelled\"\n}"}]},{"name":"Get Recently Rebuilt Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/recently-rebuilt-products?since=2024-06-01&limit=100","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","recently-rebuilt-products"],"query":[{"key":"since","value":"2024-06-01","description":"Only return products rebuilt after this datetime (ISO 8601, default: 1 hour ago)","disabled":true},{"key":"limit","value":"100","description":"Max records to return (integer, 1-1000, default 100)","disabled":true}]},"description":"Returns a list of products that have had their COGS rebuilt recently. Used for monitoring rebuild progress.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- since (optional): Datetime filter — only return products rebuilt after this time (default: 1 hour ago)\n- limit (optional): Max records to return, integer 1-1000, default 100"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/recently-rebuilt-products?since=2024-06-01&limit=100","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","recently-rebuilt-products"],"query":[{"key":"since","value":"2024-06-01","description":"Only return products rebuilt after this datetime (ISO 8601, default: 1 hour ago)","disabled":true},{"key":"limit","value":"100","description":"Max records to return (integer, 1-1000, default 100)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"last_rebuilt_cogs_at\": \"2024-06-15T14:30:00.000000Z\"\n    },\n    {\n      \"id\": 78,\n      \"sku\": \"GADGET-XL\",\n      \"name\": \"XL Gadget\",\n      \"last_rebuilt_cogs_at\": \"2024-06-15T14:28:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Export FIFO Layer Changes CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cogs-revaluation/export-fifo-changes/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","export-fifo-changes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Exports FIFO layer cost changes from a tracked rebuild job as a CSV file download.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- trackedJobId: Tracked job log ID\n\nResponse: CSV file download (Content-Type: text/csv)\nColumns: Changed At, Product SKU, Product Name, Warehouse, FIFO Layer ID, FIFO Layer Date, Before Cost, After Cost, Cost Difference, Cost Change %, Original Quantity, Link Type, Revaluation ID, Drawer Reference, Reason, COGS Source"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cogs-revaluation/export-fifo-changes/{id}","host":["{{baseUrl}}"],"path":["api","cogs-revaluation","export-fifo-changes",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"\"Changed At\",\"Product SKU\",\"Product Name\",\"Warehouse\",\"FIFO Layer ID\",\"FIFO Layer Date\",\"Before Cost\",\"After Cost\",\"Cost Difference\",\"Cost Change %\",\"Original Quantity\",\"Link Type\",\"Revaluation ID\",\"Drawer Reference\",\"Reason\",\"COGS Source\"\n\"2024-06-15T10:05:00.000000Z\",\"WIDGET-001\",\"Blue Widget\",\"Main Warehouse\",\"101\",\"2024-01-15T00:00:00.000000Z\",\"8\",\"12.5\",\"4.5\",\"56.25%\",\"500\",\"Purchase Order Receiving\",\"55\",\"PO-2024-0042\",\"rebuild\",\"purchase_order\""}]}]},{"name":"Product Pro Forma","item":[{"name":"Get Pro Forma Context","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/context","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","context"]},"description":"Full Pro Forma Analyzer bootstrap payload.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns one channel tab per connected sales-channel family (Amazon, Shopify, eBay, ...) plus a `custom` tab. Each tab includes:\n- `instances` — sync-active integration instances of that family\n- `listing` (includes `product_listing_id`) — the product's listing prefill (price, is_fba, listing_sku, asin) when product_id is given\n- `fee_defaults` — engine-resolved default fee lines (rate cards, instance settings, listing overrides) with provenance `source`\n- `supports_live_fees` — true for Amazon (use POST /amazon-fees)\n- `fulfillment_options` — `[\"fba\", \"fbm\"]` for Amazon, empty otherwise\n- `history` — 12-month realized actuals on that channel including returns economics (`avg_refund_pct`, `recovery_rate_pct`; both null when no returns); null when no orders\n\nAlso returns the product's per-unit `cogs_breakdown` from open FIFO layers (falls back to a single average-cost line) and its saved `proforma_assumptions`. The `product` object includes `default_price` — the price at the product default pricing tier, used as the selling-price fallback when a channel has no listing price (null when no default-tier price is set).\n\nChannel families with no sync-active instance are excluded unless the product has order history there, in which case the tab is kept with an \"(inactive)\" label.\n\nRequires Bearer token (products scope)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/context","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","context"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 1,\n      \"sku\": \"GSS342\",\n      \"name\": \"Grow Light Panel GSS342\",\n      \"average_cost\": 70,\n      \"default_price\": 129.99\n    },\n    \"cogs_breakdown\": [\n      {\n        \"cost_category_id\": 1,\n        \"name\": \"Base Product\",\n        \"amount\": 70,\n        \"source\": \"fifo\"\n      },\n      {\n        \"cost_category_id\": 3,\n        \"name\": \"Freight\",\n        \"amount\": 4.25,\n        \"source\": \"fifo\"\n      }\n    ],\n    \"channels\": [\n      {\n        \"integration_type\": \"amazon\",\n        \"label\": \"Amazon\",\n        \"instances\": [\n          {\n            \"integration_instance_id\": 4,\n            \"name\": \"Amazon US\",\n            \"sales_channel_id\": 2\n          }\n        ],\n        \"listing\": {\n          \"product_listing_id\": 42,\n          \"price\": 99.99,\n          \"is_fba\": true,\n          \"listing_sku\": \"GSS342-FBA\",\n          \"asin\": \"B08XYZ1234\"\n        },\n        \"fee_defaults\": [\n          {\n            \"key\": \"referral_fee\",\n            \"label\": \"Referral fee\",\n            \"fee_basis\": \"percent_of_price\",\n            \"percent\": 15,\n            \"fixed_amount\": null,\n            \"source\": \"rate_card\",\n            \"rate_card_version\": \"2026-01\",\n            \"metadata\": null\n          },\n          {\n            \"key\": \"fba_fulfillment\",\n            \"label\": \"FBA fulfillment fee\",\n            \"fee_basis\": \"fixed_per_unit\",\n            \"percent\": null,\n            \"fixed_amount\": 6.92,\n            \"source\": \"rate_card\",\n            \"rate_card_version\": \"2026-01\",\n            \"metadata\": {\n              \"size_tiers\": \"standard\"\n            }\n          }\n        ],\n        \"supports_live_fees\": true,\n        \"fulfillment_options\": [\n          \"fba\",\n          \"fbm\"\n        ],\n        \"history\": {\n          \"orders\": 312,\n          \"units\": 340,\n          \"avg_unit_revenue\": 98.45,\n          \"avg_unit_cogs\": 70,\n          \"avg_unit_shipping\": 1.12,\n          \"avg_unit_fees\": 21.6,\n          \"avg_margin_pct\": 8.42,\n          \"return_rate_pct\": 2.35,\n          \"avg_refund_pct\": 96.5,\n          \"recovery_rate_pct\": 41.2,\n          \"period\": \"12m\"\n        }\n      },\n      {\n        \"integration_type\": \"custom\",\n        \"label\": \"Custom\",\n        \"instances\": [],\n        \"listing\": null,\n        \"fee_defaults\": [],\n        \"supports_live_fees\": false,\n        \"fulfillment_options\": [],\n        \"history\": null\n      }\n    ],\n    \"proforma_assumptions\": {\n      \"shipping_cost\": 4.5,\n      \"landed_cost_percentage\": 6,\n      \"marketplace_cost_percentage\": null\n    }\n  }\n}"}]},{"name":"Get Amazon Fee Estimate (Live)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/amazon-fees","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","amazon-fees"]},"description":"Live Amazon SP-API Product Fees v0 estimate for a price/fulfillment combination.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `integration_instance_id` (required, integer) — Amazon integration instance\n- `id_type` (required, string) — `sku` (existing listing, seller SKU) or `asin` (catalog item)\n- `id_value` (required, string, max 255) — the seller SKU or ASIN\n- `price` (required, numeric, min 0.01) — listing price to estimate fees at\n- `is_amazon_fulfilled` (required, boolean) — true = FBA (sends OptionalFulfillmentProgram FBA_CORE), false = FBM\n- `refresh` (optional, boolean) — bypass the 24h cache and force a live SP-API call\n\nResults are cached for 24 hours on the exact parameter tuple; `cached` + `fetched_at` in the response indicate provenance. Amazon SP-API rate limit is 1 rps — keep `refresh` use sparing. The endpoint is throttled to 30 requests/minute (`throttle:30,1,pro-forma-amazon-fees`); exceeding it returns 429 Too Many Requests.\n\nWhen Amazon is unreachable or rejects the request, returns 422 with an `IntegrationApiError` error so the client can fall back to rate-card defaults.\n\nRequires Bearer token (products scope).","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 4,\n  \"id_type\": \"sku\",\n  \"id_value\": \"GSS342-FBA\",\n  \"price\": 99.99,\n  \"is_amazon_fulfilled\": true,\n  \"refresh\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/amazon-fees","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","amazon-fees"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 4,\n    \"id_type\": \"sku\",\n    \"id_value\": \"GSS342-FBA\",\n    \"price\": 99.99,\n    \"is_amazon_fulfilled\": true,\n    \"total_fees_estimate\": 21.92,\n    \"fee_details\": [\n      {\n        \"fee_type\": \"ReferralFee\",\n        \"amount\": 15,\n        \"included\": []\n      },\n      {\n        \"fee_type\": \"FBAFees\",\n        \"amount\": 6.92,\n        \"included\": [\n          {\n            \"fee_type\": \"FBAPerUnitFulfillmentFee\",\n            \"amount\": 6.92,\n            \"included\": []\n          }\n        ]\n      }\n    ],\n    \"fetched_at\": \"2026-06-10T18:24:11.000000Z\",\n    \"cached\": false\n  }\n}"}]},{"name":"Get Channel Sales History (Pro Forma)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/history?product_id=1&sales_channel_ids[]=2","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","history"],"query":[{"key":"product_id","value":"1","description":"Required. Product to aggregate actuals for.","disabled":true},{"key":"sales_channel_ids[]","value":"2","description":"Required (min 1). Sales channel ids to scope to. Repeat for multiple.","disabled":true}]},"description":"Historical realized actuals for one product on a set of sales channels — the \"pro forma vs. actuals\" comparison.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nMetrics (per the period):\n- `orders` — distinct order count (drafts and cancelled excluded)\n- `units` — total units sold\n- `avg_unit_revenue` / `avg_unit_cogs` / `avg_unit_fees` — per-unit averages from sales order line financials (fees = allocated settlement/channel costs)\n- `avg_unit_shipping` — fulfillment costs prorated to the product by quantity share\n- `avg_margin_pct` — profit / revenue * 100\n- `return_rate_pct` — quantity-weighted share of lines with credits or returned COGS\n- `avg_refund_pct` — refund $ as % of gross revenue over returned lines (null when the period has no returns)\n- `recovery_rate_pct` — COGS recovered (restocked) as % of COGS over returned lines (null when the period has no returns)\n\n`data` is null when the product has no qualifying orders in the period.\n\nRequires Bearer token (products scope)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/history?product_id=1&sales_channel_ids[]=2","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","history"],"query":[{"key":"product_id","value":"1","description":"Required. Product to aggregate actuals for.","disabled":true},{"key":"sales_channel_ids[]","value":"2","description":"Required (min 1). Sales channel ids to scope to. Repeat for multiple.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders\": 312,\n    \"units\": 340,\n    \"avg_unit_revenue\": 98.45,\n    \"avg_unit_cogs\": 70,\n    \"avg_unit_shipping\": 1.12,\n    \"avg_unit_fees\": 21.6,\n    \"avg_margin_pct\": 8.42,\n    \"return_rate_pct\": 2.35,\n    \"avg_refund_pct\": 96.5,\n    \"recovery_rate_pct\": 41.2,\n    \"period\": \"12m\"\n  }\n}"}]},{"name":"List Active Rate Cards","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/rate-cards","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","rate-cards"]},"description":"Active (latest effective) rate-card rows for every channel type, keyed by channel_type. Default-category rows only — category-specific variants are resolved server-side into the context fee defaults.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUsed by the frontend calculator as offline fee defaults and for the \"rates as of\" provenance chip (`version` / `effective_from`).\n\nRequires Bearer token (products scope)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/rate-cards","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","rate-cards"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"amazon\": [\n      {\n        \"id\": 1,\n        \"channel_type\": \"amazon\",\n        \"version\": \"2026-01\",\n        \"effective_from\": \"2026-01-15\",\n        \"fee_key\": \"referral_fee\",\n        \"label\": \"Referral fee\",\n        \"fee_basis\": \"percent_of_price\",\n        \"category\": \"default\",\n        \"percent\": 15,\n        \"fixed_amount\": null,\n        \"metadata\": {\n          \"minimum_per_item\": 0.3\n        }\n      },\n      {\n        \"id\": 2,\n        \"channel_type\": \"amazon\",\n        \"version\": \"2026-01\",\n        \"effective_from\": \"2026-01-15\",\n        \"fee_key\": \"fba_fulfillment\",\n        \"label\": \"FBA fulfillment fee\",\n        \"fee_basis\": \"fixed_per_unit\",\n        \"category\": \"default\",\n        \"percent\": null,\n        \"fixed_amount\": 6.92,\n        \"metadata\": {\n          \"size_tiers\": \"standard\"\n        }\n      }\n    ],\n    \"ebay\": [\n      {\n        \"id\": 5,\n        \"channel_type\": \"ebay\",\n        \"version\": \"2026-01\",\n        \"effective_from\": \"2026-01-15\",\n        \"fee_key\": \"final_value_fee\",\n        \"label\": \"Final value fee\",\n        \"fee_basis\": \"percent_of_price\",\n        \"category\": \"default\",\n        \"percent\": 13.6,\n        \"fixed_amount\": null,\n        \"metadata\": null\n      }\n    ]\n  }\n}"}]},{"name":"List Scenarios","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios"]},"description":"The authenticated user's saved what-if scenarios, newest first. Scenarios are strictly per-user — other users' scenarios are never returned.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`product_id` null on a scenario = hypothetical product (manual profile stored in `inputs.manual_profile`).\n\nRequires Bearer token (products scope)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Amazon FBA at $99.99\",\n      \"channel_type\": \"amazon\",\n      \"product_id\": 1,\n      \"integration_instance_id\": 4,\n      \"inputs\": {\n        \"price\": 99.99,\n        \"fulfillment\": \"fba\",\n        \"fee_overrides\": {\n          \"referral_fee\": {\n            \"percent\": 15\n          }\n        },\n        \"shipping_cost\": 0\n      },\n      \"outputs\": {\n        \"net_profit\": 8.29,\n        \"margin_pct\": 8.29,\n        \"roi_pct\": 11.84,\n        \"breakeven_price\": 91.7\n      },\n      \"rate_card_version\": \"2026-01\",\n      \"created_at\": \"2026-06-10T18:24:11.000000Z\",\n      \"updated_at\": \"2026-06-10T18:24:11.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Scenario","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios"]},"description":"Save a what-if scenario snapshot for the authenticated user.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `name` (required, string, max 255)\n- `channel_type` (required, string, max 50) — e.g. amazon, shopify, ebay, custom\n- `product_id` (optional, nullable, integer, exists:products) — null for hypothetical products (store the manual profile in `inputs.manual_profile`)\n- `integration_instance_id` (optional, nullable, integer, exists:integration_instances)\n- `inputs` (required, object) — full input snapshot: prices, fee overrides, advanced levers, manual_profile\n- `outputs` (required, object) — computed metrics snapshot: net_profit, margin_pct, roi_pct, breakeven_price, ...\n- `rate_card_version` (optional, nullable, string, max 50) — rate-card version used, enables \"superseded rates\" prompts\n\nRequires Bearer token (products scope).","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon FBA at $99.99\",\n  \"channel_type\": \"amazon\",\n  \"product_id\": 1,\n  \"integration_instance_id\": 4,\n  \"inputs\": {\n    \"price\": 99.99,\n    \"fulfillment\": \"fba\",\n    \"fee_overrides\": {\n      \"referral_fee\": {\n        \"percent\": 15\n      }\n    },\n    \"shipping_cost\": 0\n  },\n  \"outputs\": {\n    \"net_profit\": 8.29,\n    \"margin_pct\": 8.29,\n    \"roi_pct\": 11.84,\n    \"breakeven_price\": 91.7\n  },\n  \"rate_card_version\": \"2026-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon FBA at $99.99\",\n    \"channel_type\": \"amazon\",\n    \"product_id\": 1,\n    \"integration_instance_id\": 4,\n    \"inputs\": {\n      \"price\": 99.99,\n      \"fulfillment\": \"fba\",\n      \"fee_overrides\": {\n        \"referral_fee\": {\n          \"percent\": 15\n        }\n      },\n      \"shipping_cost\": 0\n    },\n    \"outputs\": {\n      \"net_profit\": 8.29,\n      \"margin_pct\": 8.29,\n      \"roi_pct\": 11.84,\n      \"breakeven_price\": 91.7\n    },\n    \"rate_card_version\": \"2026-01\",\n    \"created_at\": \"2026-06-10T18:24:11.000000Z\",\n    \"updated_at\": \"2026-06-10T18:24:11.000000Z\"\n  },\n  \"message\": \"Scenario saved\"\n}"}]},{"name":"Update Scenario","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios/{scenarioId}","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios",":scenarioId"],"variable":[{"key":"scenarioId","value":"3","description":"Scenario id (must belong to the authenticated user)"}]},"description":"Partially update a saved scenario. All fields optional (`sometimes`): name, channel_type, product_id, integration_instance_id, inputs, outputs, rate_card_version.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`inputs` and `outputs`, when present, are FULL snapshots — last write wins, no deep merge.\n\nReturns 404 when the scenario does not exist or belongs to another user.\n\nRequires Bearer token (products scope).","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon FBA at $109.99\",\n  \"inputs\": {\n    \"price\": 109.99,\n    \"fulfillment\": \"fba\"\n  },\n  \"outputs\": {\n    \"net_profit\": 14.8,\n    \"margin_pct\": 13.46\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios/{scenarioId}","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios",":scenarioId"],"variable":[{"key":"scenarioId","value":"3","description":"Scenario id (must belong to the authenticated user)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon FBA at $109.99\",\n    \"channel_type\": \"amazon\",\n    \"product_id\": 1,\n    \"integration_instance_id\": 4,\n    \"inputs\": {\n      \"price\": 109.99,\n      \"fulfillment\": \"fba\"\n    },\n    \"outputs\": {\n      \"net_profit\": 14.8,\n      \"margin_pct\": 13.46\n    },\n    \"rate_card_version\": \"2026-01\",\n    \"created_at\": \"2026-06-10T18:24:11.000000Z\",\n    \"updated_at\": \"2026-06-10T18:24:11.000000Z\"\n  },\n  \"message\": \"Scenario updated\"\n}"}]},{"name":"Delete Scenario","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios/{scenarioId}","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios",":scenarioId"],"variable":[{"key":"scenarioId","value":"3","description":"Scenario id (must belong to the authenticated user)"}]},"description":"Delete a saved scenario. Returns 404 when the scenario does not exist or belongs to another user.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token (products scope)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/scenarios/{scenarioId}","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","scenarios",":scenarioId"],"variable":[{"key":"scenarioId","value":"3","description":"Scenario id (must belong to the authenticated user)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Scenario deleted\"\n}"}]},{"name":"Update Product Assumptions","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pro-forma/products/{productId}/assumptions","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","products",":productId","assumptions"],"variable":[{"key":"productId","value":"1","description":"Product id"}]},"description":"Persist product-level pro forma assumptions used as analyzer defaults, plus optional per-listing marketplace fee overrides.\n\n**Required scope: `products:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional/nullable):\n- `proforma_shipping_cost` (numeric, min 0) — default outbound shipping cost per unit\n- `proforma_landed_cost_percentage` (numeric, 0-100) — landed cost uplift percent\n- `proforma_marketplace_cost_percentage` (numeric, 0-100) — marketplace fee override percent (beats rate cards; listing-level value beats this)\n- `listings` (array, optional) — per-listing marketplace fee overrides\n- `listings.*.product_listing_id` (integer, required with listings, must exist) — listing to override; silently ignored if the listing does not belong to this product\n- `listings.*.proforma_marketplace_cost_percentage` (numeric|null, 0-100) — listing-level marketplace fee override percent (null clears the override)\n\nRequires Bearer token (products scope).","body":{"mode":"raw","raw":"{\n  \"proforma_shipping_cost\": 4.5,\n  \"proforma_landed_cost_percentage\": 6,\n  \"proforma_marketplace_cost_percentage\": 14,\n  \"listings\": [\n    {\n      \"product_listing_id\": 42,\n      \"proforma_marketplace_cost_percentage\": 14.5\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/pro-forma/products/{productId}/assumptions","host":["{{baseUrl}}"],"path":["api","v2","pro-forma","products",":productId","assumptions"],"variable":[{"key":"productId","value":"1","description":"Product id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipping_cost\": 4.5,\n    \"landed_cost_percentage\": 6,\n    \"marketplace_cost_percentage\": 14\n  },\n  \"message\": \"Pro forma assumptions updated\"\n}"}]}]},{"name":"Merchandise Planning","item":[{"name":"List Merchandise Plans","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans"]},"description":"Paginated Open-to-Buy plan grid. Each row carries its live OTB breakdown (otb_value, committed_value, effective_otb_value, otb_remaining_value, status) computed on read.\n\nEffective budget = min(computed OTB, budget_cap_value) when a manual cash cap is set; otb_remaining_value = effective budget − committed.\n\nRequires a Bearer token with the `inventory` read/write scope (middleware: scope.rw:inventory)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"retail_period_id\": 5,\n      \"node_type\": \"category\",\n      \"node_id\": 1,\n      \"planned_sales_value\": 80000,\n      \"planned_sales_units\": 1600,\n      \"planned_markdown_value\": 2000,\n      \"planned_eop_value\": 30000,\n      \"planned_eop_units\": 600,\n      \"bop_value\": 25000,\n      \"bop_units\": 500,\n      \"otb_value\": 87000,\n      \"otb_units\": 1700,\n      \"on_order_value\": 0,\n      \"committed_value\": 0,\n      \"budget_cap_value\": 30000,\n      \"effective_otb_value\": 30000,\n      \"otb_remaining_value\": 30000,\n      \"status\": \"under_budget\",\n      \"budget_enforced\": false,\n      \"retail_period\": {\n        \"id\": 5,\n        \"name\": \"Fall 2026\",\n        \"type\": \"season\",\n        \"start_date\": \"2026-08-01\",\n        \"end_date\": \"2026-10-31\"\n      },\n      \"created_at\": \"2026-06-22T14:03:11.000000Z\",\n      \"updated_at\": \"2026-06-22T14:09:52.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Merchandise Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans"]},"description":"Create a plan row for a node/period and compute its initial OTB.\n\nFields:\n- retail_period_id (required, integer, exists)\n- node_type (required, enum: category | brand | department | product)\n- node_id (required, integer >= 0)\n- planned_sales_value (optional, numeric >= 0)\n- planned_sales_units (optional, integer >= 0)\n- planned_markdown_value (optional, numeric >= 0)\n- planned_eop_value (optional, numeric >= 0)\n- planned_eop_units (optional, integer >= 0)\n- budget_enforced (optional, boolean) — enforce the OTB guardrail on forecast buys\n- budget_cap_value (optional, nullable, numeric >= 0) — manual cash ceiling; effective budget = min(computed OTB, this)\n\nRequires the `inventory` read/write scope.","body":{"mode":"raw","raw":"{\n  \"retail_period_id\": 5,\n  \"node_type\": \"category\",\n  \"node_id\": 1,\n  \"planned_sales_value\": 80000,\n  \"planned_sales_units\": 1600,\n  \"planned_markdown_value\": 2000,\n  \"planned_eop_value\": 30000,\n  \"planned_eop_units\": 600,\n  \"budget_enforced\": false,\n  \"budget_cap_value\": 30000\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"retail_period_id\": 5,\n    \"node_type\": \"category\",\n    \"node_id\": 1,\n    \"planned_sales_value\": 80000,\n    \"planned_sales_units\": 1600,\n    \"planned_markdown_value\": 2000,\n    \"planned_eop_value\": 30000,\n    \"planned_eop_units\": 600,\n    \"bop_value\": 25000,\n    \"bop_units\": 500,\n    \"otb_value\": 87000,\n    \"otb_units\": 1700,\n    \"on_order_value\": 0,\n    \"committed_value\": 0,\n    \"budget_cap_value\": 30000,\n    \"effective_otb_value\": 30000,\n    \"otb_remaining_value\": 30000,\n    \"status\": \"under_budget\",\n    \"budget_enforced\": false,\n    \"retail_period\": {\n      \"id\": 5,\n      \"name\": \"Fall 2026\",\n      \"type\": \"season\",\n      \"start_date\": \"2026-08-01\",\n      \"end_date\": \"2026-10-31\"\n    },\n    \"created_at\": \"2026-06-22T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-22T14:09:52.000000Z\"\n  }\n}"}]},{"name":"Seed Plan From Forecast / Last Year","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/seed","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans","seed"]},"description":"Seed a period's grid in bulk from a forecast or last-year actuals. Each incoming node row upserts a plan and gets its OTB computed.\n\nFields:\n- retail_period_id (required, integer, exists)\n- source (required, one of: forecast, last_year)\n- rows (required, array, min 1)\n  - rows.*.node_type (required, enum: category | brand | department | product)\n  - rows.*.node_id (required, integer >= 0)\n  - rows.*.planned_sales_value (optional, numeric >= 0)\n  - rows.*.planned_sales_units (optional, integer >= 0)\n  - rows.*.planned_markdown_value (optional, numeric >= 0)\n  - rows.*.planned_eop_value (optional, numeric >= 0)\n  - rows.*.planned_eop_units (optional, integer >= 0)\n\nRequires the `inventory` read/write scope.","body":{"mode":"raw","raw":"{\n  \"retail_period_id\": 5,\n  \"source\": \"forecast\",\n  \"rows\": [\n    {\n      \"node_type\": \"category\",\n      \"node_id\": 1,\n      \"planned_sales_value\": 80000,\n      \"planned_sales_units\": 1600,\n      \"planned_markdown_value\": 2000,\n      \"planned_eop_value\": 30000,\n      \"planned_eop_units\": 600\n    },\n    {\n      \"node_type\": \"category\",\n      \"node_id\": 2,\n      \"planned_sales_value\": 45000,\n      \"planned_sales_units\": 900,\n      \"planned_markdown_value\": 1000,\n      \"planned_eop_value\": 18000,\n      \"planned_eop_units\": 360\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/seed","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans","seed"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"retail_period_id\": 5,\n      \"node_type\": \"category\",\n      \"node_id\": 1,\n      \"planned_sales_value\": 80000,\n      \"planned_sales_units\": 1600,\n      \"planned_markdown_value\": 2000,\n      \"planned_eop_value\": 30000,\n      \"planned_eop_units\": 600,\n      \"bop_value\": 25000,\n      \"bop_units\": 500,\n      \"otb_value\": 87000,\n      \"otb_units\": 1700,\n      \"on_order_value\": 0,\n      \"committed_value\": 0,\n      \"budget_cap_value\": 30000,\n      \"effective_otb_value\": 30000,\n      \"otb_remaining_value\": 30000,\n      \"status\": \"under_budget\",\n      \"budget_enforced\": false,\n      \"retail_period\": {\n        \"id\": 5,\n        \"name\": \"Fall 2026\",\n        \"type\": \"season\",\n        \"start_date\": \"2026-08-01\",\n        \"end_date\": \"2026-10-31\"\n      },\n      \"created_at\": \"2026-06-22T14:03:11.000000Z\",\n      \"updated_at\": \"2026-06-22T14:09:52.000000Z\"\n    }\n  ]\n}"}]},{"name":"Get Merchandise Plan","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]},"description":"Show a single plan row with its live OTB breakdown (including budget_cap_value, effective_otb_value, otb_remaining_value).\n\nRequires the `inventory` read/write scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"retail_period_id\": 5,\n    \"node_type\": \"category\",\n    \"node_id\": 1,\n    \"planned_sales_value\": 80000,\n    \"planned_sales_units\": 1600,\n    \"planned_markdown_value\": 2000,\n    \"planned_eop_value\": 30000,\n    \"planned_eop_units\": 600,\n    \"bop_value\": 25000,\n    \"bop_units\": 500,\n    \"otb_value\": 87000,\n    \"otb_units\": 1700,\n    \"on_order_value\": 0,\n    \"committed_value\": 0,\n    \"budget_cap_value\": 30000,\n    \"effective_otb_value\": 30000,\n    \"otb_remaining_value\": 30000,\n    \"status\": \"under_budget\",\n    \"budget_enforced\": false,\n    \"retail_period\": {\n      \"id\": 5,\n      \"name\": \"Fall 2026\",\n      \"type\": \"season\",\n      \"start_date\": \"2026-08-01\",\n      \"end_date\": \"2026-10-31\"\n    },\n    \"created_at\": \"2026-06-22T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-22T14:09:52.000000Z\"\n  }\n}"}]},{"name":"Update Merchandise Plan (cell save / cash cap)","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]},"description":"Update editable plan cell(s) — a debounced save — and recompute OTB. PATCH only the changed fields.\n\nFields (all optional / 'sometimes'):\n- planned_sales_value (numeric >= 0)\n- planned_sales_units (integer >= 0)\n- planned_markdown_value (numeric >= 0)\n- planned_eop_value (numeric >= 0)\n- planned_eop_units (integer >= 0)\n- budget_enforced (boolean)\n- budget_cap_value (nullable, numeric >= 0) — set a manual cash ceiling; pass null to clear it (back to the full computed OTB)\n\nWhen a cash cap below the computed OTB is set, effective_otb_value and otb_remaining_value drop to the cap.\n\nRequires the `inventory` read/write scope.","body":{"mode":"raw","raw":"{\n  \"planned_sales_value\": 80000,\n  \"planned_eop_value\": 30000,\n  \"budget_enforced\": false,\n  \"budget_cap_value\": 30000\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"retail_period_id\": 5,\n    \"node_type\": \"category\",\n    \"node_id\": 1,\n    \"planned_sales_value\": 80000,\n    \"planned_sales_units\": 1600,\n    \"planned_markdown_value\": 2000,\n    \"planned_eop_value\": 30000,\n    \"planned_eop_units\": 600,\n    \"bop_value\": 25000,\n    \"bop_units\": 500,\n    \"otb_value\": 87000,\n    \"otb_units\": 1700,\n    \"on_order_value\": 0,\n    \"committed_value\": 0,\n    \"budget_cap_value\": 30000,\n    \"effective_otb_value\": 30000,\n    \"otb_remaining_value\": 30000,\n    \"status\": \"under_budget\",\n    \"budget_enforced\": false,\n    \"retail_period\": {\n      \"id\": 5,\n      \"name\": \"Fall 2026\",\n      \"type\": \"season\",\n      \"start_date\": \"2026-08-01\",\n      \"end_date\": \"2026-10-31\"\n    },\n    \"created_at\": \"2026-06-22T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-22T14:09:52.000000Z\"\n  }\n}"}]},{"name":"Get OTB Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}/otb","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan","otb"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]},"description":"Live OTB + remaining + committed breakdown for a plan row.\n\nReturns: otb_value, otb_units, bop_value, bop_units, on_order_value, committed_value, budget_cap_value (nullable), effective_otb_value (= min(otb_value, cap)), otb_remaining_value (= effective − committed), and status (under_budget | near_budget | over_budget).\n\nRequires the `inventory` read/write scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/open-to-buy/merchandise-plans/{merchandisePlan}/otb","host":["{{baseUrl}}"],"path":["api","open-to-buy","merchandise-plans",":merchandisePlan","otb"],"variable":[{"key":"merchandisePlan","value":"1","description":"Merchandise plan id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"otb_value\": 87000,\n    \"otb_units\": 1700,\n    \"bop_value\": 25000,\n    \"bop_units\": 500,\n    \"on_order_value\": 0,\n    \"committed_value\": 0,\n    \"budget_cap_value\": 30000,\n    \"effective_otb_value\": 30000,\n    \"otb_remaining_value\": 30000,\n    \"status\": \"under_budget\"\n  }\n}"}]}]},{"name":"Serial Numbers","item":[{"name":"List Serial Numbers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/serial-numbers","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers"]},"description":"Paginated list of individual serial numbers across all products, with their lifecycle status and current location/order. Filter by product, status, or warehouse, and search the serial value."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/serial-numbers","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 91,\n      \"serial\": \"SN-100482\",\n      \"status\": \"in_stock\",\n      \"status_label\": \"In Stock\",\n      \"product\": {\n        \"id\": 2,\n        \"sku\": \"WIDGET-SN\",\n        \"name\": \"Serialized Widget\",\n        \"link_route\": \"/products/2\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"received_at\": \"2026-07-19T10:00:00.000000Z\",\n      \"shipped_at\": null,\n      \"current_order\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Get Serial Number","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/{serialNumber}","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers",":serialNumber"],"variable":[{"key":"serialNumber","value":"91","description":"Serial number id"}]},"description":"A single serial's full detail plus its genealogy timeline (received → allocated → committed → shipped → returned/scrapped/quarantined), each event cross-linked to its source document, order and customer."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/{serialNumber}","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers",":serialNumber"],"variable":[{"key":"serialNumber","value":"91","description":"Serial number id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 91,\n    \"serial\": \"SN-100482\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"product\": {\n      \"id\": 2,\n      \"sku\": \"WIDGET-SN\",\n      \"name\": \"Serialized Widget\",\n      \"link_route\": \"/products/2\"\n    },\n    \"warehouse\": null,\n    \"received_at\": \"2026-07-19T10:00:00.000000Z\",\n    \"shipped_at\": \"2026-07-21T09:00:00.000000Z\",\n    \"current_order\": {\n      \"number\": \"SO-1234\",\n      \"link_route\": \"/orders/sales-orders/33\"\n    },\n    \"warranty_start_at\": \"2026-07-21\",\n    \"warranty_registration_ref\": null,\n    \"disposition_reason\": null,\n    \"timeline\": [\n      {\n        \"event\": \"received\",\n        \"at\": \"2026-07-19T10:00:00.000000Z\",\n        \"movement_id\": 10,\n        \"link_reference\": \"PO-4501\",\n        \"link_route\": \"/orders/purchase-orders/9\"\n      },\n      {\n        \"event\": \"shipped\",\n        \"at\": \"2026-07-21T09:00:00.000000Z\",\n        \"movement_id\": 55,\n        \"sales_order_number\": \"SO-1234\",\n        \"customer_name\": \"Acme Corporation\",\n        \"link_route\": \"/orders/sales-orders/33\"\n      }\n    ]\n  }\n}"}]},{"name":"List Product Serial Numbers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/products/{product}/serial-numbers","host":["{{baseUrl}}"],"path":["api","v2","products",":product","serial-numbers"],"variable":[{"key":"product","value":"2","description":"Product id"}]},"description":"The serials for a single product (per-product tab). Same filters/sorts as the global list."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/products/{product}/serial-numbers","host":["{{baseUrl}}"],"path":["api","v2","products",":product","serial-numbers"],"variable":[{"key":"product","value":"2","description":"Product id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 91,\n      \"serial\": \"SN-100482\",\n      \"status\": \"in_stock\",\n      \"status_label\": \"In Stock\",\n      \"product\": {\n        \"id\": 2,\n        \"sku\": \"WIDGET-SN\",\n        \"name\": \"Serialized Widget\",\n        \"link_route\": \"/products/2\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"received_at\": \"2026-07-19T10:00:00.000000Z\",\n      \"shipped_at\": null,\n      \"current_order\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Quarantine Serial Numbers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/quarantine","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","quarantine"]},"description":"Hold one or more serials (recall / damage / inspection). Quarantined serials are excluded from availability and cannot be allocated or shipped until released.\n\nBody: serial_number_ids (required array of ids), reason (optional).","body":{"mode":"raw","raw":"{\n  \"serial_number_ids\": [\n    91,\n    92\n  ],\n  \"reason\": \"Recall batch 2026-07\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/quarantine","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","quarantine"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"quarantined\": 2\n  }\n}"}]},{"name":"Release Serial Numbers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/release","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","release"]},"description":"Release quarantined serials back to in-stock. Body: serial_number_ids (required array).","body":{"mode":"raw","raw":"{\n  \"serial_number_ids\": [\n    91,\n    92\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/release","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","release"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"released\": 2\n  }\n}"}]},{"name":"Serial Recall Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/recall-impact?product_id=2","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","recall-impact"],"query":[{"key":"product_id","value":"2","description":"Required. Product to assess.","disabled":true}]},"description":"For a product (optionally narrowed to one receiving movement), list the shipped serials with the orders/customers they went to — the affected-customer list for a recall."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/serial-numbers/recall-impact?product_id=2","host":["{{baseUrl}}"],"path":["api","v2","serial-numbers","recall-impact"],"query":[{"key":"product_id","value":"2","description":"Required. Product to assess.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"serial\": \"SN-100482\",\n      \"sales_order_number\": \"SO-1234\",\n      \"customer_name\": \"Acme Corporation\",\n      \"shipped_at\": \"2026-07-21\"\n    }\n  ]\n}"}]}]},{"name":"Landed Cost Breakdown","item":[{"name":"Generate Landed Cost Breakdown Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/reporting/landed-cost-breakdown","host":["{{baseUrl}}"],"path":["api","reporting","landed-cost-breakdown"]},"description":"Dispatch a filtered, hierarchically-grouped report (brand > product) restricted to a specific sales channel and warehouse. Returns a `tracked_job_log_id`; fetch the payload from the result endpoint once the job completes.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nDemonstrates hierarchical grouping combined with filtering — useful for drilling into specific segments of the business.","body":{"mode":"raw","raw":"{\n  \"date_from\": \"2025-01-01\",\n  \"date_to\": \"2025-12-31\",\n  \"group_by\": [\n    \"brand\",\n    \"product\"\n  ],\n  \"sales_channel_ids\": [\n    1\n  ],\n  \"warehouse_ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Generated Report Result","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/landed-cost-breakdown/result/{trackedJobLog}","host":["{{baseUrl}}"],"path":["api","reporting","landed-cost-breakdown","result",":trackedJobLog"],"variable":[{"key":"trackedJobLog","value":"4821","description":"The tracked_job_log_id returned by the generate endpoint."}]},"description":"Fetch the generated landed cost breakdown payload for a completed generation job. Call this once the tracked job (from the generate endpoint) reaches `completed`.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Response structure:**\n- `group_by` — the grouping dimensions used.\n- `date_range` — `{ from, to }` for the report.\n- `categories` — the cost categories present in the report (`id`, `name`, `is_system`).\n- `groups` — hierarchical breakdown by the grouping dimensions, each with `totals` and nested `children`.\n- `grand_totals` — aggregate totals across all groups.\n\n**Status codes:**\n- `200` — payload returned.\n- `403` — the authenticated user did not generate this report.\n- `404` — the report is not ready yet (job still running) or the cached payload has expired (~1 hour TTL). Regenerate.\n\n**Authentication:** Requires a bearer token. Scoped to the user who generated the report."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/reporting/landed-cost-breakdown/result/{trackedJobLog}","host":["{{baseUrl}}"],"path":["api","reporting","landed-cost-breakdown","result",":trackedJobLog"],"variable":[{"key":"trackedJobLog","value":"4821","description":"The tracked_job_log_id returned by the generate endpoint."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"group_by\": [\n    \"sales_channel\"\n  ],\n  \"date_range\": {\n    \"from\": \"2025-01-01\",\n    \"to\": \"2025-12-31\"\n  },\n  \"categories\": [\n    {\n      \"id\": 1,\n      \"name\": \"Base Product Cost\",\n      \"is_system\": true\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Freight\",\n      \"is_system\": true\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Customs Duty\",\n      \"is_system\": true\n    }\n  ],\n  \"groups\": [\n    {\n      \"key\": \"Amazon US\",\n      \"totals\": {\n        \"quantity_sold\": 1250,\n        \"base_product\": 45230,\n        \"freight\": 8540.25,\n        \"customs_duty\": 2150,\n        \"brokerage\": 425,\n        \"insurance\": 312.5,\n        \"handling\": 625,\n        \"taxes\": 4523,\n        \"other_costs\": 180.75,\n        \"total_landed_cost\": 61986.5\n      },\n      \"children\": []\n    },\n    {\n      \"key\": \"Shopify\",\n      \"totals\": {\n        \"quantity_sold\": 850,\n        \"base_product\": 28750,\n        \"freight\": 4250,\n        \"customs_duty\": 0,\n        \"brokerage\": 0,\n        \"insurance\": 187.5,\n        \"handling\": 425,\n        \"taxes\": 2875,\n        \"other_costs\": 95.25,\n        \"total_landed_cost\": 36582.75\n      },\n      \"children\": []\n    }\n  ],\n  \"grand_totals\": {\n    \"quantity_sold\": 2100,\n    \"base_product\": 73980,\n    \"freight\": 12790.25,\n    \"customs_duty\": 2150,\n    \"brokerage\": 425,\n    \"insurance\": 500,\n    \"handling\": 1050,\n    \"taxes\": 7398,\n    \"other_costs\": 276,\n    \"total_landed_cost\": 98569.25\n  }\n}"}]},{"name":"Export Landed Cost Breakdown (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/reporting/landed-cost-breakdown/export?date_from=2025-01-01&date_to=2025-12-31&group_by[]=sales_channel","host":["{{baseUrl}}"],"path":["api","reporting","landed-cost-breakdown","export"],"query":[{"key":"date_from","value":"2025-01-01","description":"Start date for the report","disabled":true},{"key":"date_to","value":"2025-12-31","description":"End date for the report","disabled":true},{"key":"group_by[]","value":"sales_channel","description":"First grouping level","disabled":true}]},"description":"Export a detailed breakdown with multiple grouping levels as CSV. The CSV includes a column for each grouping dimension (Sales Channel, Brand, Product) followed by all cost breakdown columns. Ideal for pivot-table analysis in a spreadsheet.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}}]},{"name":"Loyalty","item":[{"name":"Get Loyalty Balance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]},"description":"The customer's current loyalty points balance and its dollar redemption value, plus whether the loyalty program is enabled.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: authenticated user (no extra permission required for read).\n\nReturns 200 with `{ data: { customer_id, points_balance, redemption_value, program_enabled } }`:\n- `points_balance` (integer) — the running sum of the customer's loyalty ledger.\n- `redemption_value` (float) — the dollar value of that balance at the current redemption rate.\n- `program_enabled` (boolean) — whether the loyalty program is active for the tenant."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"customer_id\": 842,\n    \"points_balance\": 1250,\n    \"redemption_value\": 12.5,\n    \"program_enabled\": true\n  }\n}"}]},{"name":"Get Loyalty History","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty","history"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]},"description":"Paginated loyalty ledger history for a customer, newest first. Each entry records a signed points movement, the resulting balance, why it was written, and who created it.\n\n**Required scope: `customers:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: authenticated user (no extra permission required for read).\n\nEntry `type` values: `earn`, `redemption`, `adjustment`, `expiry`, `reversal`. `is_earn` is true when the entry adds points (points > 0).\n\nPagination: `per_page` (default 10), `page` (default 1). Response includes standard Laravel pagination metadata."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty/history","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty","history"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"customer_id\": 842,\n      \"reference\": \"LP-000512\",\n      \"points\": -300,\n      \"balance_after\": 1250,\n      \"type\": \"redemption\",\n      \"type_label\": \"Redeemed\",\n      \"is_earn\": false,\n      \"notes\": null,\n      \"expires_at\": null,\n      \"source_type\": \"App\\\\Models\\\\PosTransaction\",\n      \"source_id\": 1001,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T15:10:00+00:00\"\n    },\n    {\n      \"id\": 508,\n      \"customer_id\": 842,\n      \"reference\": \"LP-000508\",\n      \"points\": 50,\n      \"balance_after\": 1550,\n      \"type\": \"earn\",\n      \"type_label\": \"Earned\",\n      \"is_earn\": true,\n      \"notes\": null,\n      \"expires_at\": \"2027-07-06T00:00:00+00:00\",\n      \"source_type\": \"App\\\\Models\\\\PosTransaction\",\n      \"source_id\": 998,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:45:00+00:00\"\n    },\n    {\n      \"id\": 500,\n      \"customer_id\": 842,\n      \"reference\": \"LP-000500\",\n      \"points\": 500,\n      \"balance_after\": 1500,\n      \"type\": \"adjustment\",\n      \"type_label\": \"Adjustment\",\n      \"is_earn\": true,\n      \"notes\": \"Goodwill points for a delayed order.\",\n      \"expires_at\": null,\n      \"source_type\": null,\n      \"source_id\": null,\n      \"created_by_user_id\": 7,\n      \"created_by_name\": \"Jane Cashier\",\n      \"created_at\": \"2026-07-06T14:30:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/customers/842/loyalty/history?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/customers/842/loyalty/history?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/customers/842/loyalty/history\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 3\n}"}]},{"name":"Adjust Loyalty Points","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty/adjust","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty","adjust"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]},"description":"Manually add or remove loyalty points for a customer. Writes a signed `adjustment` ledger entry — a positive `points` value adds, a negative value removes.\n\n**Required scope: `customers:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `customers.update`.\n\nRequest body fields:\n- `points` (integer, required, `not_in:0`) — signed points to apply. Positive adds, negative removes. Error message when 0: \"The points adjustment must be non-zero.\"\n- `notes` (string, nullable, max 2000) — internal note for the adjustment.\n\nA negative adjustment that would drive the balance below zero is rejected with 422 (`InsufficientLoyaltyPointsException`).\n\nReturns 201 with `{ data: <ledger entry>, points_balance: <int>, message: \"Loyalty points adjusted.\" }`.","body":{"mode":"raw","raw":"{\n  \"points\": 500,\n  \"notes\": \"Goodwill points for a delayed order.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/customers/{customer}/loyalty/adjust","host":["{{baseUrl}}"],"path":["api","customers",":customer","loyalty","adjust"],"variable":[{"key":"customer","value":"842","description":"The customer id."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"customer_id\": 842,\n    \"reference\": \"LP-000500\",\n    \"points\": 500,\n    \"balance_after\": 1500,\n    \"type\": \"adjustment\",\n    \"type_label\": \"Adjustment\",\n    \"is_earn\": true,\n    \"notes\": \"Goodwill points for a delayed order.\",\n    \"expires_at\": null,\n    \"source_type\": null,\n    \"source_id\": null,\n    \"created_by_user_id\": 7,\n    \"created_by_name\": \"Jane Cashier\",\n    \"created_at\": \"2026-07-06T14:30:00+00:00\"\n  },\n  \"points_balance\": 1500,\n  \"message\": \"Loyalty points adjusted.\"\n}"}]},{"name":"Get Loyalty Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/loyalty/settings","host":["{{baseUrl}}"],"path":["api","loyalty","settings"]},"description":"The tenant's loyalty program configuration.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `pos.operate`.\n\nReturns 200 with `{ data: { enabled, points_per_dollar, redemption_value_per_point, min_redemption_points } }`:\n- `enabled` (boolean) — whether the program is active (default false).\n- `points_per_dollar` (float) — points earned per $1 of sale total before tax (default 1.0).\n- `redemption_value_per_point` (float) — dollar value of one point when redeemed (default 0.01).\n- `min_redemption_points` (integer) — minimum points a customer must hold before any can be redeemed (default 0)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/loyalty/settings","host":["{{baseUrl}}"],"path":["api","loyalty","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"points_per_dollar\": 1,\n    \"redemption_value_per_point\": 0.01,\n    \"min_redemption_points\": 100\n  }\n}"}]},{"name":"Update Loyalty Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/loyalty/settings","host":["{{baseUrl}}"],"path":["api","loyalty","settings"]},"description":"Update the tenant's loyalty program configuration. All fields are required and fully replace the stored settings.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (PAT).\nPermission: `pos.manage`.\n\nRequest body fields (all required):\n- `enabled` (boolean, required) — whether the program is active.\n- `points_per_dollar` (numeric, required, min 0) — points earned per $1 of sale total before tax.\n- `redemption_value_per_point` (numeric, required, min 0) — dollar value of one point when redeemed.\n- `min_redemption_points` (integer, required, min 0) — minimum points required before redemption.\n\nReturns 200 with `{ data: { ...settings }, message: \"Loyalty settings updated.\" }`.","body":{"mode":"raw","raw":"{\n  \"enabled\": true,\n  \"points_per_dollar\": 1,\n  \"redemption_value_per_point\": 0.01,\n  \"min_redemption_points\": 100\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/loyalty/settings","host":["{{baseUrl}}"],"path":["api","loyalty","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"points_per_dollar\": 1,\n    \"redemption_value_per_point\": 0.01,\n    \"min_redemption_points\": 100\n  },\n  \"message\": \"Loyalty settings updated.\"\n}"}]}]},{"name":"OAuth","item":[{"name":"OAuth Callback","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/x-www-form-urlencoded"}],"url":{"raw":"{{baseUrl}}/api/magento2/oauth/callback","host":["{{baseUrl}}"],"path":["api","magento2","oauth","callback"]},"description":"**Public, unauthenticated endpoint** — Magento Admin POSTs the OAuth 1.0a activation payload here when the merchant clicks **Activate** on a Magento Integration.\n\n**Flow on success:**\n1. We immediately return `200 { success: true, oauth_verifier: ... }` so Magento marks the integration Active.\n2. We then asynchronously POST to `{store_base_url}/oauth/token/request` to get a temporary request token, and `{store_base_url}/oauth/token/access` (with the verifier) to upgrade it into the permanent access token + secret. This deferred-exchange pattern (via `fastcgi_finish_request()` or `register_shutdown_function`) avoids deadlocking Magento's PHP-FPM worker pool — Magento's own Laminas HTTP client expects to read our response before it can serve our outbound OAuth calls.\n3. Structured outcomes (success/failure + last-4-of-token) are logged to `laravel.log` so install operations can be debugged.\n\n**Body parameters** (form-urlencoded, as Magento Admin POSTs):\n- `oauth_consumer_key` (required, string) — Magento Integration consumer key.\n- `oauth_consumer_secret` (required, string) — Magento Integration consumer secret.\n- `oauth_verifier` (required, string) — one-time verifier for the token exchange.\n- `store_base_url` (required, string) — Magento storefront URL.\n\n**Behavior:**\n- If any field is missing, the endpoint still returns HTTP 200 (so Magento Admin doesn't surface a misleading 'post to consumer failed' error) but with `success: false` and a message; the OAuth exchange is skipped.\n- The endpoint never throws — exchange failures are logged but not propagated to the response (Magento has already left the conversation by then).\n\n**Authentication:** None — this is a public webhook. CSRF is bypassed by the wildcard `*/callback` rule in `bootstrap/app.php`.","body":{"mode":"raw","raw":"{\n  \"oauth_consumer_key\": \"abc123def456ghi789jkl012\",\n  \"oauth_consumer_secret\": \"mno345pqr678stu901vwx234\",\n  \"oauth_verifier\": \"yz567abc890def123ghi456\",\n  \"store_base_url\": \"https://shop.example.com\"\n}","options":{"raw":{"language":"text"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/oauth/callback","host":["{{baseUrl}}"],"path":["api","magento2","oauth","callback"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"oauth_verifier\": \"yz567abc890def123ghi456\"\n}"}]}]},{"name":"Transactions","item":[{"name":"List Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Paginated UNION of invoices + credit memos. Each row carries a `type` discriminator and a `magento_admin_url` deep-link that points at the correct admin section (invoice vs credit memo) on the storefront.\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer) — Magento 2 IntegrationInstance ID.\n\n**Notes:**\n- Implementation uses an in-memory merge of the two Eloquent queries (suitable for typical merchant volumes). For high-volume tenants the repository will swap to `DB::query()->fromSub(...->unionAll(...))` without changing the API contract.\n- The order is eager-loaded so the cell renderer doesn't N+1.\n- Sort is fixed at `magento_created_at DESC` for now (the merged paginator doesn't yet honour Spatie's `sort` param)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 803,\n      \"integration_instance_id\": 42,\n      \"magento_entity_id\": 5034,\n      \"magento_increment_id\": \"1000005034\",\n      \"type\": \"invoice\",\n      \"state\": \"paid\",\n      \"grand_total\": 198.45,\n      \"currency\": \"USD\",\n      \"payment_method\": \"stripe_payments\",\n      \"order_id\": 921,\n      \"order\": {\n        \"id\": 921,\n        \"magento_entity_id\": 700912,\n        \"magento_increment_id\": \"100000921\",\n        \"customer_email\": \"buyer@example.com\"\n      },\n      \"is_pushed_to_accounting\": false,\n      \"pushed_to_accounting_at\": null,\n      \"is_reconciled\": false,\n      \"reconciled_at\": null,\n      \"accounting_sync_enabled\": true,\n      \"magento_admin_url\": \"https://shop.example.com/admin/sales/invoice/view/invoice_id/5034\",\n      \"magento_created_at\": \"2026-06-10T18:01:11+00:00\",\n      \"magento_updated_at\": null,\n      \"created_at\": \"2026-06-10T18:02:01+00:00\",\n      \"updated_at\": \"2026-06-10T18:02:01+00:00\"\n    }\n  ],\n  \"first_page_url\": \"...?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-io-test/api/magento2/integration-instances/42/transactions\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Transaction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]},"description":"Single transaction detail. The `{txn}` id can refer to either a `magento2_invoices.id` or a `magento2_credit_memos.id`; the `type` query string disambiguates.\n\nAdds (vs the list row): extended order context (subtotals, tax, discounts, shipping), `fees[]`, `total_fees` / `total_fee_tax`, and `raw_magento_payload` (the exact body Magento returned).\n\n**Error responses:**\n- `404` — id does not exist for the supplied `type` in this instance.\n- `401` — caller is not authenticated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 803,\n    \"integration_instance_id\": 42,\n    \"magento_entity_id\": 5034,\n    \"magento_increment_id\": \"1000005034\",\n    \"type\": \"invoice\",\n    \"state\": \"paid\",\n    \"grand_total\": 198.45,\n    \"currency\": \"USD\",\n    \"payment_method\": \"stripe_payments\",\n    \"order_id\": 921,\n    \"order\": {\n      \"id\": 921,\n      \"magento_entity_id\": 700912,\n      \"magento_increment_id\": \"100000921\",\n      \"customer_email\": \"buyer@example.com\"\n    },\n    \"is_pushed_to_accounting\": false,\n    \"pushed_to_accounting_at\": null,\n    \"is_reconciled\": false,\n    \"reconciled_at\": null,\n    \"accounting_sync_enabled\": true,\n    \"magento_admin_url\": \"https://shop.example.com/admin/sales/invoice/view/invoice_id/5034\",\n    \"magento_created_at\": \"2026-06-10T18:01:11+00:00\",\n    \"magento_updated_at\": null,\n    \"created_at\": \"2026-06-10T18:02:01+00:00\",\n    \"updated_at\": \"2026-06-10T18:02:01+00:00\",\n    \"fees\": [],\n    \"total_fees\": 0,\n    \"total_fee_tax\": 0,\n    \"raw_magento_payload\": {\n      \"entity_id\": 5034,\n      \"increment_id\": \"1000005034\",\n      \"grand_total\": 198.45\n    }\n  }\n}"}]},{"name":"Get Transaction Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Aggregated dropdown options for the transactions filter panel — currencies (pulled live from the linked orders), per-type counts, and per-state counts. Empty / never-synced instances surface empty lists."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/filter-options","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions","filter-options"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currencies\": [\n      \"USD\",\n      \"EUR\"\n    ],\n    \"types\": [\n      {\n        \"value\": \"invoice\",\n        \"label\": \"Invoice\",\n        \"count\": 38\n      },\n      {\n        \"value\": \"credit_memo\",\n        \"label\": \"Credit Memo\",\n        \"count\": 4\n      }\n    ],\n    \"states\": [\n      {\n        \"value\": \"paid\",\n        \"label\": \"Paid\",\n        \"count\": 32\n      },\n      {\n        \"value\": \"open\",\n        \"label\": \"Open\",\n        \"count\": 6\n      },\n      {\n        \"value\": \"refunded\",\n        \"label\": \"Refunded\",\n        \"count\": 4\n      }\n    ]\n  }\n}"}]},{"name":"Refresh Transactions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Dispatch the tracked job that refreshes invoices + credit memos for the instance. Returns the `tracked_job_log_id` so the frontend can pivot the global JobProgressTray to it. Job name prefix is `Refresh Magento 2 Transactions: ` — the page's `lastCompletedJob` watcher matches on this prefix.\n\nPhase 2C scope: dispatch harness only — the actual `/V1/invoices` + `/V1/creditmemo` walking lands in Phase 2D."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 91901\n  },\n  \"message\": \"Transaction sync queued.\"\n}"}]},{"name":"Refresh Single Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/refresh?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","refresh"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]},"description":"Re-fetch a single transaction from Magento — typically used when the merchant reconciled / captured / refunded the row in Magento admin and wants SKU.io to pick up the change without a full refresh.\n\nCurrently a no-op stub (Phase 2C) — the row's `updated_at` is touched so downstream watchers see activity. Real refresh lands in Phase 2D."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/refresh?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","refresh"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 803,\n    \"integration_instance_id\": 42,\n    \"magento_entity_id\": 5034,\n    \"magento_increment_id\": \"1000005034\",\n    \"type\": \"invoice\",\n    \"state\": \"paid\",\n    \"grand_total\": 198.45,\n    \"currency\": \"USD\",\n    \"payment_method\": \"stripe_payments\",\n    \"order_id\": 921,\n    \"order\": {\n      \"id\": 921,\n      \"magento_entity_id\": 700912,\n      \"magento_increment_id\": \"100000921\",\n      \"customer_email\": \"buyer@example.com\"\n    },\n    \"is_pushed_to_accounting\": false,\n    \"pushed_to_accounting_at\": null,\n    \"is_reconciled\": false,\n    \"reconciled_at\": null,\n    \"accounting_sync_enabled\": true,\n    \"magento_admin_url\": \"https://shop.example.com/admin/sales/invoice/view/invoice_id/5034\",\n    \"magento_created_at\": \"2026-06-10T18:01:11+00:00\",\n    \"magento_updated_at\": null,\n    \"created_at\": \"2026-06-10T18:02:01+00:00\",\n    \"updated_at\": \"2026-06-10T18:02:01+00:00\",\n    \"fees\": [],\n    \"total_fees\": 0,\n    \"total_fee_tax\": 0,\n    \"raw_magento_payload\": {\n      \"entity_id\": 5034,\n      \"increment_id\": \"1000005034\",\n      \"grand_total\": 198.45\n    }\n  },\n  \"message\": \"Transaction refresh queued.\"\n}"}]},{"name":"Push Transaction to Accounting","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/push-to-accounting?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","push-to-accounting"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]},"description":"Push the transaction to the configured accounting integration (QuickBooks Online / Xero / etc.). Synchronous — returns the updated row inline. Repeated calls overwrite `pushed_to_accounting_at` so the UI can show 'pushed N minutes ago' deterministically.\n\nPhase 2C scope: timestamps the row only. Phase 2D will wire the real accounting-connector dispatch."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/push-to-accounting?type=invoice","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","push-to-accounting"],"query":[{"key":"type","value":"invoice","description":"Discriminator — one of: invoice, credit_memo. Default: invoice.","disabled":true}],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 803,\n    \"integration_instance_id\": 42,\n    \"magento_entity_id\": 5034,\n    \"magento_increment_id\": \"1000005034\",\n    \"type\": \"invoice\",\n    \"state\": \"paid\",\n    \"grand_total\": 198.45,\n    \"currency\": \"USD\",\n    \"payment_method\": \"stripe_payments\",\n    \"order_id\": 921,\n    \"order\": {\n      \"id\": 921,\n      \"magento_entity_id\": 700912,\n      \"magento_increment_id\": \"100000921\",\n      \"customer_email\": \"buyer@example.com\"\n    },\n    \"is_pushed_to_accounting\": true,\n    \"pushed_to_accounting_at\": \"2026-06-16T07:30:00+00:00\",\n    \"is_reconciled\": false,\n    \"reconciled_at\": null,\n    \"accounting_sync_enabled\": true,\n    \"magento_admin_url\": \"https://shop.example.com/admin/sales/invoice/view/invoice_id/5034\",\n    \"magento_created_at\": \"2026-06-10T18:01:11+00:00\",\n    \"magento_updated_at\": null,\n    \"created_at\": \"2026-06-10T18:02:01+00:00\",\n    \"updated_at\": \"2026-06-10T18:02:01+00:00\",\n    \"fees\": [],\n    \"total_fees\": 0,\n    \"total_fee_tax\": 0,\n    \"raw_magento_payload\": {\n      \"entity_id\": 5034,\n      \"increment_id\": \"1000005034\",\n      \"grand_total\": 198.45\n    }\n  },\n  \"message\": \"Transaction pushed to accounting.\"\n}"}]},{"name":"Toggle Reconciliation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/reconcile","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","reconcile"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]},"description":"Toggle the manual reconciliation flag on the transaction. The note is optional and persists alongside the timestamp; setting `is_reconciled: false` clears both fields.\n\n**Body params:**\n- `is_reconciled` (required, boolean) — true to set, false to clear.\n- `note` (optional, string, max 1000) — free-text reconciliation note.\n- `type` (optional, string) — discriminator. One of: invoice, credit_memo. Default: invoice.\n\n**Error responses:**\n- `404` — id does not exist for the supplied `type` in this instance.\n- `422` — body validation failed.","body":{"mode":"raw","raw":"{\n  \"is_reconciled\": true,\n  \"note\": \"Matched to QBO entry #4810\",\n  \"type\": \"invoice\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/transactions/{txn}/reconcile","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","transactions",":txn","reconcile"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"},{"key":"txn","value":"803","description":"Internal magento2_invoices.id or magento2_credit_memos.id (disambiguated by `type` query param)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 803,\n    \"integration_instance_id\": 42,\n    \"magento_entity_id\": 5034,\n    \"magento_increment_id\": \"1000005034\",\n    \"type\": \"invoice\",\n    \"state\": \"paid\",\n    \"grand_total\": 198.45,\n    \"currency\": \"USD\",\n    \"payment_method\": \"stripe_payments\",\n    \"order_id\": 921,\n    \"order\": {\n      \"id\": 921,\n      \"magento_entity_id\": 700912,\n      \"magento_increment_id\": \"100000921\",\n      \"customer_email\": \"buyer@example.com\"\n    },\n    \"is_pushed_to_accounting\": false,\n    \"pushed_to_accounting_at\": null,\n    \"is_reconciled\": true,\n    \"reconciled_at\": \"2026-06-16T07:31:00+00:00\",\n    \"accounting_sync_enabled\": true,\n    \"magento_admin_url\": \"https://shop.example.com/admin/sales/invoice/view/invoice_id/5034\",\n    \"magento_created_at\": \"2026-06-10T18:01:11+00:00\",\n    \"magento_updated_at\": null,\n    \"created_at\": \"2026-06-10T18:02:01+00:00\",\n    \"updated_at\": \"2026-06-10T18:02:01+00:00\",\n    \"fees\": [],\n    \"total_fees\": 0,\n    \"total_fee_tax\": 0,\n    \"raw_magento_payload\": {\n      \"entity_id\": 5034,\n      \"increment_id\": \"1000005034\",\n      \"grand_total\": 198.45\n    }\n  },\n  \"message\": \"Transaction reconciled.\"\n}"}]}]},{"name":"Orders","item":[{"name":"Get Order By ID","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/{magento2Order}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders",":magento2Order"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"magento2Order","value":"1042","description":"Internal Magento2Order ID (NOT the Magento `entity_id`)."}]},"description":"Fetch a single Magento 2 order by its internal ID, scoped to the supplied integration instance. The response includes the Magento money block, timestamps, the resolved Magento admin URL, all line items, shipments, invoices, credit memos, and — when linked — the SKU.io sales order with its fulfillments. `sku_sales_order_updated_at` carries that linked order's last create/update timestamp (the \"Last SKU Sync\" column on the orders list), or null when the Magento order isn't mapped yet.\n\n**Embedded `sku_sales_order.fulfillments[]`** drives the Fulfillments accordion panel on the order detail page. Each fulfillment carries: `id`, `status`, `fulfillment_type`, `tracking_number`, `cost`, `fulfilled_at`, `submitted_to_sales_channel_at`, the `warehouse` (id + name), the `shipping_method` (id + name), and the per-line `line_items[]` array. When the linked SKU sales order has no fulfillments the array is empty.\n\n**Activity log + raw payload** are NOT included here — they are lazy-loaded by the detail page from `/orders/:id/activity-log` and `/orders/:id/raw` respectively. Pass `include_raw=1` if you need `raw_payload` inline.\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/{magento2Order}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders",":magento2Order"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"magento2Order","value":"1042","description":"Internal Magento2Order ID (NOT the Magento `entity_id`)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"integration_instance_id\": 42,\n    \"magento_entity_id\": 5821,\n    \"magento_increment_id\": 5821,\n    \"magento_state\": \"processing\",\n    \"magento_status\": \"processing\",\n    \"store_id\": 1,\n    \"customer_id\": 312,\n    \"customer_email\": \"buyer@example.com\",\n    \"currency_code\": \"USD\",\n    \"base_grand_total\": \"129.99\",\n    \"grand_total\": \"129.99\",\n    \"tax_amount\": \"10.40\",\n    \"shipping_amount\": \"9.99\",\n    \"discount_amount\": \"-5.00\",\n    \"total_paid\": \"129.99\",\n    \"total_refunded\": \"0.00\",\n    \"magento_created_at\": \"2026-06-15T10:22:18+00:00\",\n    \"magento_updated_at\": \"2026-06-15T10:25:00+00:00\",\n    \"created_at\": \"2026-06-15T10:22:30+00:00\",\n    \"updated_at\": \"2026-06-15T10:30:00+00:00\",\n    \"archived_at\": null,\n    \"error_log\": null,\n    \"magento_admin_url\": \"https://shop.example.com/admin/sales/order/view/order_id/5821\",\n    \"sku_sales_order_id\": 99012,\n    \"sku_sales_order\": {\n      \"id\": 99012,\n      \"number\": \"SO-99012\",\n      \"sales_order_number\": \"SO-99012\",\n      \"status\": \"open\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"partial\",\n      \"payment_status\": \"paid\",\n      \"fulfillments\": [\n        {\n          \"id\": 7710,\n          \"status\": \"fulfilled\",\n          \"fulfillment_type\": \"warehouse\",\n          \"tracking_number\": \"1Z999AA10123456784\",\n          \"cost\": 9.99,\n          \"fulfilled_at\": \"2026-06-16T14:05:11+00:00\",\n          \"submitted_to_sales_channel_at\": \"2026-06-16T14:10:00+00:00\",\n          \"warehouse\": {\n            \"id\": 3,\n            \"name\": \"Main Warehouse\"\n          },\n          \"shipping_method\": {\n            \"id\": 12,\n            \"name\": \"UPS Ground\"\n          },\n          \"line_items\": [\n            {\n              \"id\": 88410,\n              \"quantity\": 1,\n              \"product_name\": \"Acme Widget Pro\",\n              \"sku\": \"AWP-001\"\n            }\n          ]\n        }\n      ]\n    },\n    \"sku_sales_order_updated_at\": \"2026-06-16T14:10:00+00:00\",\n    \"integration_instance\": {\n      \"id\": 42,\n      \"name\": \"Acme Magento 2 Store\"\n    },\n    \"customer\": {\n      \"id\": 312,\n      \"magento_customer_id\": 9001,\n      \"email\": \"buyer@example.com\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\"\n    },\n    \"line_items_count\": 1,\n    \"line_items\": [\n      {\n        \"id\": 88410,\n        \"magento_item_id\": 18221,\n        \"magento_product_id\": 4501,\n        \"sku\": \"AWP-001\",\n        \"name\": \"Acme Widget Pro\",\n        \"image_url\": \"https://shop.example.com/media/catalog/product/a/w/awp-001.jpg\",\n        \"qty_ordered\": 1,\n        \"qty_invoiced\": 1,\n        \"qty_shipped\": 1,\n        \"qty_refunded\": 0,\n        \"price\": \"114.60\",\n        \"tax_amount\": \"10.40\",\n        \"discount_amount\": \"-5.00\",\n        \"row_total\": \"129.99\"\n      }\n    ],\n    \"shipments\": [\n      {\n        \"id\": 4710,\n        \"magento_entity_id\": 6611,\n        \"magento_increment_id\": \"000006611\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"tracking_carrier\": \"ups\",\n        \"source_code\": \"default\",\n        \"magento_created_at\": \"2026-06-16T14:00:00+00:00\",\n        \"pushed_to_magento_at\": \"2026-06-16T14:10:00+00:00\",\n        \"sku_sales_order_fulfillment_id\": 7710\n      }\n    ],\n    \"invoices\": [\n      {\n        \"id\": 5510,\n        \"magento_entity_id\": 7022,\n        \"magento_increment_id\": \"000007022\",\n        \"state\": \"paid\",\n        \"grand_total\": 129.99,\n        \"subtotal\": 114.6,\n        \"tax_amount\": 10.4,\n        \"shipping_amount\": 9.99,\n        \"discount_amount\": -5,\n        \"magento_created_at\": \"2026-06-15T10:25:00+00:00\",\n        \"pushed_to_accounting_at\": \"2026-06-16T09:00:00+00:00\",\n        \"reconciled_at\": null,\n        \"payment_method\": \"stripe\"\n      }\n    ],\n    \"credit_memos\": [],\n    \"raw_payload\": null\n  }\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Dispatch the tracked job that refreshes Magento 2 orders. Returns the `tracked_job_log_id` so the frontend can pivot the global JobProgressTray to it. Job name prefix is `Refresh Magento 2 Orders: ` — the page's `lastCompletedJob` watcher matches on this prefix.\n\n**Body params:**\n- `mode` *(required)* — one of `since_latest`, `from_start_date`, `date_range`, `all`.\n  - `since_latest` resumes from the cursor stored on the local orders table (falls back to `since_at` then to the integration's configured start_date).\n  - `from_start_date` walks from the integration's configured start date (Settings → Orders → Start date).\n  - `date_range` walks a bounded `[date_from, date_to]` window.\n  - `all` — **Full Re-sync.** Walks every order Magento returns, ignoring start_date entirely. Mirrors the option BigCommerce / eBay / WooCommerce already expose.\n- `since_at` *(optional, ISO datetime)* — fallback cursor used by `since_latest` when our local orders table is empty.\n- `date_from` / `date_to` *(required when `mode=date_range`, ISO date)* — inclusive bounds of the date window.","body":{"mode":"raw","raw":"{\n  \"mode\": \"all\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 92148\n  },\n  \"message\": \"Order sync queued.\"\n}"}]},{"name":"Pre-Start-Date Orders — Search Specific Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/pre-start-date-search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","pre-start-date-search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Live single-order lookup against the Magento store for the pre-start-date import dialog's **Search specific order** tab. Hits Magento directly via the REST API (GET /V1/orders/{id} for `entity_id`, GET /V1/orders?searchCriteria for `email`) — local DB lookups would miss orders that have never been imported, which is the whole point of a pre-start-date back-fill.\n\n**Body params:**\n- `search_by` *(required)* — `entity_id` (Magento order entity id) or `email` (customer email, exact match).\n- `search_term` *(required, max 255 chars)* — the value to look up. For `entity_id` must parse as a positive integer.\n\n**Response shape** mirrors the Browse-by-date result so the shared dialog can render either path uniformly:\n- `data[]` — orders found, each with `eligible`, `eligibility_reason`, `already_imported`, `line_items[]`, etc.\n- `inventory_start_date` — the integration's configured `sync_start_date` (orders on or after this date are not eligible — covered by regular sync).\n- `meta.total_queried` / `meta.eligible_count` / `meta.already_imported_count`.\n\nAn `entity_id` that doesn't exist in Magento returns `data: []` (NOT a 404) so the dialog can show a clean 'no results' state.","body":{"mode":"raw","raw":"{\n  \"search_by\": \"entity_id\",\n  \"search_term\": \"5421\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/pre-start-date-search","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","pre-start-date-search"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"magento_entity_id\": 5421,\n      \"increment_id\": \"100000123\",\n      \"name\": \"100000123\",\n      \"email\": \"customer@example.com\",\n      \"created_at\": \"2023-11-04 14:22:11\",\n      \"magento_status\": \"complete\",\n      \"magento_state\": \"complete\",\n      \"total_price\": \"129.95\",\n      \"currency\": \"USD\",\n      \"item_count\": 2,\n      \"total_quantity\": 3,\n      \"line_items\": [\n        {\n          \"title\": \"Acme Hoodie - Medium - Blue\",\n          \"sku\": \"ACME-HOODIE-M-BLU\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"49.99\",\n          \"variant_title\": null\n        },\n        {\n          \"title\": \"Stickers Pack\",\n          \"sku\": \"STICKER-PK\",\n          \"quantity\": 1,\n          \"current_quantity\": 1,\n          \"price\": \"29.97\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2024-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Pre-Start-Date Orders — Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/import-pre-start-date","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","import-pre-start-date"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Dispatches the tracked job that back-fills Magento 2 orders pre-dating the integration's normal sync start date. Returns `tracked_job_log_id` so the frontend can pivot the global JobProgressTray to it. Job name prefix is `Import Pre-Start-Date Magento 2 Orders: `.\n\n**Two modes — supply exactly one:**\n- **Date-range mode** *(Browse-by-date tab)* — walks every Magento order in [`created_at` >= `date_from`, `created_at` <= `date_to`].\n  - `date_from` *(required, date)* — inclusive lower bound.\n  - `date_to` *(required, date, >= date_from)* — inclusive upper bound.\n- **Entity-ids mode** *(Search-specific-order tab)* — imports only the explicit entity ids the user picked from the live Magento search.\n  - `magento_entity_ids[]` *(required, array of positive integers)* — Magento order entity ids to import. Each is fetched live via `syncManager->syncOrder()` and upserted into `magento2_orders`.\n\nWhen `magento_entity_ids` is present, `date_from` / `date_to` are not required and are ignored if supplied.\n\nAlso accessible via the alias route `POST /api/magento2/integration-instances/{instance}/pre-start-date-orders/import`.","body":{"mode":"raw","raw":"{\n  \"magento_entity_ids\": [\n    5421,\n    5422\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/orders/import-pre-start-date","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","orders","import-pre-start-date"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Pre-start-date import job queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 92201\n  }\n}"}]}]},{"name":"Shipments","item":[{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipments","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipments"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]},"description":"Paginated Magento 2 shipments for the instance, newest first (by magento_created_at, then id).\n\n**Response contract (matches the frontend Magento2Shipment type):** `shipment_number` (shipment's own Magento increment), `magento_order_id` (internal magento2_orders.id — drives the order link + tooltip), `magento_increment_id` (ORDER increment — the user-facing reference), `status` (`pushed` | `synced`), `carrier` (alias of `tracking_carrier`), `source_code` (MSI source).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipments","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipments"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"magento2_order_id\": 23,\n      \"magento_entity_id\": 3,\n      \"shipment_number\": \"000000003\",\n      \"magento_order_id\": 23,\n      \"magento_increment_id\": \"000000023\",\n      \"status\": \"pushed\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_carrier\": \"ups\",\n      \"carrier\": \"ups\",\n      \"source_code\": \"default\",\n      \"magento_created_at\": \"2026-07-04T15:11:20+00:00\",\n      \"created_at\": \"2026-07-04T15:11:21+00:00\",\n      \"updated_at\": \"2026-07-04T15:11:21+00:00\",\n      \"pushed_to_magento_at\": \"2026-07-04T15:11:21+00:00\",\n      \"sku_sales_order_fulfillment_id\": 5,\n      \"order\": {\n        \"id\": 23,\n        \"magento_increment_id\": \"000000023\",\n        \"customer_email\": \"buyer@example.com\",\n        \"grand_total\": \"9.9900\",\n        \"currency_code\": \"USD\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipments",":shipment"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"shipment","value":"2","description":"Internal Magento2Shipment ID."}]},"description":"Fetch a single shipment (same contract as the list row) plus the full `raw_payload` from Magento. 404 when the shipment does not belong to the supplied instance.\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipments",":shipment"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID."},{"key":"shipment","value":"2","description":"Internal Magento2Shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"magento2_order_id\": 23,\n    \"magento_entity_id\": 3,\n    \"shipment_number\": \"000000003\",\n    \"magento_order_id\": 23,\n    \"magento_increment_id\": \"000000023\",\n    \"status\": \"pushed\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_carrier\": \"ups\",\n    \"carrier\": \"ups\",\n    \"source_code\": \"default\",\n    \"magento_created_at\": \"2026-07-04T15:11:20+00:00\",\n    \"created_at\": \"2026-07-04T15:11:21+00:00\",\n    \"updated_at\": \"2026-07-04T15:11:21+00:00\",\n    \"pushed_to_magento_at\": \"2026-07-04T15:11:21+00:00\",\n    \"sku_sales_order_fulfillment_id\": 5,\n    \"order\": {\n      \"id\": 23,\n      \"magento_increment_id\": \"000000023\",\n      \"customer_email\": \"buyer@example.com\",\n      \"grand_total\": \"9.9900\",\n      \"currency_code\": \"USD\"\n    },\n    \"raw_payload\": {\n      \"entity_id\": 3,\n      \"increment_id\": \"000000003\"\n    }\n  }\n}"}]}]},{"name":"Inventory Sources (MSI)","item":[{"name":"List Cached MSI Sources","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources-cache","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources-cache"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Returns the paginated list of cached Magento MSI sources for the instance.\n\nAuthenticated. Requires a Bearer token.\n\nResponse fields per row:\n- `id` — cache row id\n- `integration_instance_id` — owning integration instance\n- `source_code` — Magento MSI source_code (unique per instance)\n- `name` — human-friendly source name\n- `enabled` — whether the source is enabled in Magento\n- `country_id`, `region`, `city`, `postcode`, `contact_email` — location/contact metadata\n- `master_of_stock` — per-source sync direction; one of `sku.io`, `magento2`, `disabled` (defaults to `sku.io`). See PATCH `…/inventory-sources/{sourceCode}/master-of-stock`.\n- `last_fetched_at` — ISO8601 timestamp of the most recent refresh\n\nAllowed sorts: `source_code`, `name`, `enabled`, `updated_at`. Default sort: `source_code` ASC."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources-cache","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources-cache"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_instance_id\": 1,\n      \"source_code\": \"default\",\n      \"name\": \"Default Source\",\n      \"enabled\": true,\n      \"country_id\": \"US\",\n      \"region\": \"California\",\n      \"city\": \"San Francisco\",\n      \"postcode\": \"94103\",\n      \"contact_email\": \"ops@example.test\",\n      \"last_fetched_at\": \"2026-06-20T14:32:11+00:00\",\n      \"created_at\": \"2026-06-12T09:00:00+00:00\",\n      \"master_of_stock\": \"sku.io\"\n    },\n    {\n      \"id\": 2,\n      \"integration_instance_id\": 1,\n      \"source_code\": \"east_dc\",\n      \"name\": \"East Coast Warehouse\",\n      \"enabled\": true,\n      \"country_id\": \"US\",\n      \"region\": \"New Jersey\",\n      \"city\": \"Newark\",\n      \"postcode\": \"07102\",\n      \"contact_email\": null,\n      \"last_fetched_at\": \"2026-06-20T14:32:11+00:00\",\n      \"created_at\": \"2026-06-12T09:00:00+00:00\",\n      \"master_of_stock\": \"sku.io\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Refresh MSI Sources from Magento","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Synchronously fetches MSI sources from Magento via `GET /rest/V1/inventory/sources` and upserts them into the local cache.\n\nAuthenticated. Requires a Bearer token. Empty JSON body (`{}`).\n\nSide effects:\n- Issues one Saloon request to Magento (no tracked job, no queue).\n- Upserts each returned source by `(integration_instance_id, source_code)`.\n- Updates the row's `updated_at` so the UI can render \"last refreshed at\".\n\nWhen Magento has MSI disabled, it returns HTTP 400. The connector translates this into an empty result — the endpoint still returns 200 with `fetched: 0`, `written: 0` so the UI can surface a friendly message instead of an error.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources/refresh","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources","refresh"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Magento 2 MSI sources refreshed.\",\n  \"data\": {\n    \"fetched\": 2,\n    \"written\": 2,\n    \"last_fetched_at\": \"2026-06-20T14:32:11+00:00\"\n  }\n}"}]},{"name":"Update Master of Stock for a Source","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources/{sourceCode}/master-of-stock","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources",":sourceCode","master-of-stock"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"Magento 2 integration instance ID"},{"key":"sourceCode","value":"default","description":"Magento MSI source_code (e.g. 'default', 'warehouse_east')"}]},"description":"Update the Master of Stock direction for a single Magento MSI source.\n\nPer the sales-channel standard §7.10, Master of Stock lives per-location (per MSI source for Magento 2), not as a single global value on the integration instance.\n\n**Authentication:** Requires Bearer token.\n\n**Request body:**\n- `master_of_stock` (string, required) — one of `sku.io`, `magento2`, `disabled`.\n  - `sku.io` — SKU.io pushes on-hand to this Magento source on a schedule.\n  - `magento2` — RESERVED. Magento→SKU.io direction is not implemented yet; the UI exposes it as a disabled \"(contact support)\" option.\n  - `disabled` — no automatic sync for this source.\n\n**Responses:**\n- `200 OK` — returns `{ data: { source_code, master_of_stock } }`.\n- `404 Not Found` — the MSI source is not cached for this instance. Refresh sources on Settings → Locations first.\n- `422 Unprocessable Entity` — `master_of_stock` missing or not one of the allowed values.","body":{"mode":"raw","raw":"{\n  \"master_of_stock\": \"sku.io\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/inventory-sources/{sourceCode}/master-of-stock","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","inventory-sources",":sourceCode","master-of-stock"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"Magento 2 integration instance ID"},{"key":"sourceCode","value":"default","description":"Magento MSI source_code (e.g. 'default', 'warehouse_east')"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Master of Stock updated.\",\n  \"data\": {\n    \"source_code\": \"default\",\n    \"master_of_stock\": \"sku.io\"\n  }\n}"}]}]},{"name":"Warehouse Mappings","item":[{"name":"List Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","warehouse-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Returns the cached MSI inventory sources for the instance joined to any persisted SKU.io warehouse mappings, plus the full list of SKU.io warehouses available to map to.\n\nAuthenticated. Requires a Bearer token.\n\nResponse fields:\n- `data.sources[]` — one row per cached MSI source. `warehouse_id`/`warehouse_name` are null when the source is not yet mapped.\n- `data.warehouses[]` — every SKU.io warehouse the user can pick.\n- `data.mapped_count` / `data.unmapped_count` — counts derived from `sources`.\n\nThe page renders the entire table from this single response — no separate calls for the warehouse picker are required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","warehouse-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sources\": [\n      {\n        \"source_code\": \"default\",\n        \"source_name\": \"Default Warehouse\",\n        \"enabled\": true,\n        \"country_id\": \"US\",\n        \"region\": \"CA\",\n        \"city\": \"Los Angeles\",\n        \"warehouse_id\": 12,\n        \"warehouse_name\": \"LA Main\"\n      },\n      {\n        \"source_code\": \"east_dc\",\n        \"source_name\": \"East Coast DC\",\n        \"enabled\": true,\n        \"country_id\": \"US\",\n        \"region\": \"NJ\",\n        \"city\": \"Newark\",\n        \"warehouse_id\": null,\n        \"warehouse_name\": null\n      }\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 12,\n        \"name\": \"LA Main\"\n      },\n      {\n        \"id\": 13,\n        \"name\": \"NJ Hub\"\n      }\n    ],\n    \"mapped_count\": 1,\n    \"unmapped_count\": 1\n  }\n}"}]},{"name":"Bulk Replace Warehouse Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","warehouse-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Bulk-replaces warehouse mappings for the instance in a single transaction.\n\nAuthenticated. Requires a Bearer token.\n\nRequest body (`mappings[]`):\n- `source_code` (string, required) — must exist in `magento2_inventory_sources_cache` for this instance. Refresh from the Locations tab first if the source is missing.\n- `warehouse_id` (integer or null, required) — must exist in `warehouses`. `null` removes the mapping for that source.\n\nDuplicate `source_code` entries in the same payload are rejected (422).\n\nReturns the freshly-rebuilt index payload so the UI can re-render without an extra GET.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"source_code\": \"default\",\n      \"warehouse_id\": 12\n    },\n    {\n      \"source_code\": \"east_dc\",\n      \"warehouse_id\": 13\n    },\n    {\n      \"source_code\": \"legacy_pop_up\",\n      \"warehouse_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","warehouse-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sources\": [\n      {\n        \"source_code\": \"default\",\n        \"source_name\": \"Default Warehouse\",\n        \"enabled\": true,\n        \"country_id\": \"US\",\n        \"region\": \"CA\",\n        \"city\": \"Los Angeles\",\n        \"warehouse_id\": 12,\n        \"warehouse_name\": \"LA Main\"\n      },\n      {\n        \"source_code\": \"east_dc\",\n        \"source_name\": \"East Coast DC\",\n        \"enabled\": true,\n        \"country_id\": \"US\",\n        \"region\": \"NJ\",\n        \"city\": \"Newark\",\n        \"warehouse_id\": 13,\n        \"warehouse_name\": \"NJ Hub\"\n      }\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 12,\n        \"name\": \"LA Main\"\n      },\n      {\n        \"id\": 13,\n        \"name\": \"NJ Hub\"\n      }\n    ],\n    \"mapped_count\": 2,\n    \"unmapped_count\": 0\n  },\n  \"message\": \"Warehouse mappings saved successfully\"\n}"}]}]},{"name":"Shipping Method Mappings","item":[{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipping-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Returns the existing Magento -> SKU.io shipping method mappings, the distinct Magento shipping methods observed on past imported orders for this instance, and the catalogue of SKU.io ShippingMethod records that can be picked from the row-level select.\n\nAuthenticated. Requires a Bearer token.\n\nResponse fields:\n- `data.mappings[]` — union of observed methods and any persisted mappings. `sku_shipping_method_id`/`sku_shipping_method_name` are null when the method is not yet mapped. `magento_method_label` is the human-friendly description from `shipping_description` on the original order (when available).\n- `data.observed_methods[]` — raw list of distinct `{carrier}_{method}` codes seen on past orders, paired with the latest `shipping_description` observed.\n- `data.sku_shipping_methods[]` — every SKU.io ShippingMethod available to pick from. Rendered as friendly labels in the row-level select via `full_name` (\"Carrier - Method\").\n\nThe page renders the entire table from this single response — no separate call for the shipping-method catalogue is required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipping-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 42,\n        \"magento_method_code\": \"flatrate_flatrate\",\n        \"magento_method_label\": \"Flat Rate - Fixed\",\n        \"sku_shipping_method_id\": 12,\n        \"sku_shipping_method_name\": \"USPS - Priority Mail\"\n      },\n      {\n        \"id\": null,\n        \"magento_method_code\": \"ups_GND\",\n        \"magento_method_label\": \"United Parcel Service - Ground\",\n        \"sku_shipping_method_id\": null,\n        \"sku_shipping_method_name\": null\n      },\n      {\n        \"id\": null,\n        \"magento_method_code\": \"fedex_FEDEX_2_DAY\",\n        \"magento_method_label\": \"Federal Express - 2 Day\",\n        \"sku_shipping_method_id\": null,\n        \"sku_shipping_method_name\": null\n      }\n    ],\n    \"observed_methods\": [\n      {\n        \"magento_method_code\": \"flatrate_flatrate\",\n        \"magento_method_label\": \"Flat Rate - Fixed\"\n      },\n      {\n        \"magento_method_code\": \"ups_GND\",\n        \"magento_method_label\": \"United Parcel Service - Ground\"\n      },\n      {\n        \"magento_method_code\": \"fedex_FEDEX_2_DAY\",\n        \"magento_method_label\": \"Federal Express - 2 Day\"\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 12,\n        \"full_name\": \"USPS - Priority Mail\"\n      },\n      {\n        \"id\": 13,\n        \"full_name\": \"UPS - Ground\"\n      },\n      {\n        \"id\": 14,\n        \"full_name\": \"FedEx - 2 Day Air\"\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Replace Shipping Method Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipping-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Bulk-replaces the shipping method mappings for the instance in a single transaction. Uses **replace** semantics:\n- Rows present in the payload with a non-null `sku_shipping_method_id` are upserted.\n- Rows present with a null `sku_shipping_method_id` are removed (the user cleared the row-level select).\n- Rows whose `magento_method_code` is absent from the payload are removed (delete-by-omission).\n\nAuthenticated. Requires a Bearer token.\n\nRequest body (`mappings[]`):\n- `magento_carrier_code` (string, optional, max 64) — informational; the canonical key is `magento_method_code`.\n- `magento_method_code` (string, required, max 128) — the Magento `{carrier}_{method}` identifier (e.g. `flatrate_flatrate`, `ups_GND`, `fedex_FEDEX_2_DAY`).\n- `sku_shipping_method_id` (integer or null, optional) — must exist in `shipping_methods`. `null` removes the mapping.\n- `sku_shipping_method_name` (string, optional, max 255) — informational label used by the UI / activity log; not authoritative.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"magento_carrier_code\": \"flatrate\",\n      \"magento_method_code\": \"flatrate_flatrate\",\n      \"sku_shipping_method_id\": 12,\n      \"sku_shipping_method_name\": \"USPS - Priority Mail\"\n    },\n    {\n      \"magento_carrier_code\": \"ups\",\n      \"magento_method_code\": \"ups_GND\",\n      \"sku_shipping_method_id\": 13,\n      \"sku_shipping_method_name\": \"UPS - Ground\"\n    },\n    {\n      \"magento_carrier_code\": \"fedex\",\n      \"magento_method_code\": \"fedex_FEDEX_2_DAY\",\n      \"sku_shipping_method_id\": null,\n      \"sku_shipping_method_name\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","shipping-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"magento_method_code\": \"flatrate_flatrate\",\n      \"sku_shipping_method_id\": 12\n    },\n    {\n      \"id\": 43,\n      \"magento_method_code\": \"ups_GND\",\n      \"sku_shipping_method_id\": 13\n    }\n  ]\n}"}]}]},{"name":"Payment Method Mappings","item":[{"name":"List Payment Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","payment-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Returns the Magento 2 -> SKU.io payment-method mapping table for this instance, plus the catalogue of SKU.io payment types that can be mapped to.\n\nThe mapping rows are the union of every payment method observed on past imported orders and every persisted mapping — methods seen on orders that are not yet mapped appear with `sku_payment_type_id: null`, and persisted-but-no-longer-observed methods still appear so stale mappings can be revisited or cleared.\n\nEach mapping row contains:\n- `id` — the persisted mapping row ID, or null when the method has been observed on orders but not yet mapped.\n- `magento_method` — the Magento 2 payment method code (e.g. `checkmo`, `paypal_express`, `banktransfer`).\n- `magento_method_title` — the human-friendly method title observed on orders (falls back to the code).\n- `sku_payment_type_id` / `sku_payment_type_name` — the SKU.io payment type the method maps to; null when unmapped.\n- `unpaid_disposition` — how orders that arrive UNPAID with this payment method are imported: null (inherit the store-level payment-pending policy), `open` (import normally, no hold), `draft` (import without allocating stock), or `reserve` (allocate stock and hold fulfillment until payment arrives, optionally expiring per the store-level reservation expiry).\n- `accounting_sync` — when this method's orders sync to the connected accounting provider: null (inherit the store-level trigger), `always` (sync once confirmed regardless of payment), `when_paid` (sync only after payment arrives), or `never` (this method's orders are excluded from accounting sync).\n\nResponse also includes:\n- `data.available_payment_types[]` — every active SKU.io payment type (`id`, `name`).\n- `meta` — `total_mappings`, `mapped_count`, `unmapped_count` counters.\n\nAuthenticated. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","payment-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 31,\n        \"magento_method\": \"checkmo\",\n        \"magento_method_title\": \"Check / Money order\",\n        \"sku_payment_type_id\": 4,\n        \"sku_payment_type_name\": \"Check\",\n        \"unpaid_disposition\": \"reserve\",\n        \"accounting_sync\": \"when_paid\"\n      },\n      {\n        \"id\": 32,\n        \"magento_method\": \"paypal_express\",\n        \"magento_method_title\": \"PayPal Express Checkout\",\n        \"sku_payment_type_id\": 2,\n        \"sku_payment_type_name\": \"PayPal\",\n        \"unpaid_disposition\": null,\n        \"accounting_sync\": null\n      },\n      {\n        \"id\": null,\n        \"magento_method\": \"banktransfer\",\n        \"magento_method_title\": \"Bank Transfer Payment\",\n        \"sku_payment_type_id\": null,\n        \"sku_payment_type_name\": null,\n        \"unpaid_disposition\": null,\n        \"accounting_sync\": null\n      }\n    ],\n    \"available_payment_types\": [\n      {\n        \"id\": 1,\n        \"name\": \"Cash\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"PayPal\"\n      },\n      {\n        \"id\": 3,\n        \"name\": \"Credit Card\"\n      },\n      {\n        \"id\": 4,\n        \"name\": \"Check\"\n      }\n    ]\n  },\n  \"meta\": {\n    \"total_mappings\": 3,\n    \"mapped_count\": 2,\n    \"unmapped_count\": 1\n  }\n}"}]},{"name":"Bulk Replace Payment Method Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","payment-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]},"description":"Bulk-replaces the payment-method mapping set for this instance. Any persisted row whose `magento_method` is NOT in the supplied payload is deleted; the rest are upserted — so send the complete set of mappings you want kept, not a delta.\n\nBody parameters:\n- `mappings` (array, required — may be empty to clear all mappings). Each row:\n  - `mappings.*.magento_method` (string, required, max 128) — the Magento 2 payment method code.\n  - `mappings.*.sku_payment_type_id` (integer or null) — the SKU.io payment type to map to; null records the method as known but unmapped.\n  - `mappings.*.unpaid_disposition` (string or null, optional) — per-method override for how orders arriving unpaid with this method are imported: null inherits the store-level payment-pending policy, `open` imports normally, `draft` imports without allocating stock, `reserve` allocates stock and holds fulfillment with an expiry per the store-level reservation settings.\n  - `mappings.*.accounting_sync` (string or null, optional) — per-method override for when this method's orders sync to the accounting provider: null inherits the store-level trigger, `always`, `when_paid`, or `never`.\n\nReturns the same payload as the list endpoint, rebuilt after the update.\n\nAuthenticated. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"magento_method\": \"checkmo\",\n      \"sku_payment_type_id\": 4,\n      \"unpaid_disposition\": \"reserve\",\n      \"accounting_sync\": \"when_paid\"\n    },\n    {\n      \"magento_method\": \"paypal_express\",\n      \"sku_payment_type_id\": 2,\n      \"unpaid_disposition\": null,\n      \"accounting_sync\": null\n    },\n    {\n      \"magento_method\": \"banktransfer\",\n      \"sku_payment_type_id\": null,\n      \"unpaid_disposition\": \"draft\",\n      \"accounting_sync\": \"never\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","payment-method-mappings"],"variable":[{"key":"magento2IntegrationInstance","value":"1","description":"ID of the Magento 2 integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 31,\n        \"magento_method\": \"checkmo\",\n        \"magento_method_title\": \"Check / Money order\",\n        \"sku_payment_type_id\": 4,\n        \"sku_payment_type_name\": \"Check\",\n        \"unpaid_disposition\": \"reserve\",\n        \"accounting_sync\": \"when_paid\"\n      },\n      {\n        \"id\": 32,\n        \"magento_method\": \"paypal_express\",\n        \"magento_method_title\": \"PayPal Express Checkout\",\n        \"sku_payment_type_id\": 2,\n        \"sku_payment_type_name\": \"PayPal\",\n        \"unpaid_disposition\": null,\n        \"accounting_sync\": null\n      },\n      {\n        \"id\": null,\n        \"magento_method\": \"banktransfer\",\n        \"magento_method_title\": \"Bank Transfer Payment\",\n        \"sku_payment_type_id\": null,\n        \"sku_payment_type_name\": null,\n        \"unpaid_disposition\": \"draft\",\n        \"accounting_sync\": \"never\"\n      }\n    ],\n    \"available_payment_types\": [\n      {\n        \"id\": 1,\n        \"name\": \"Cash\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"PayPal\"\n      },\n      {\n        \"id\": 3,\n        \"name\": \"Credit Card\"\n      },\n      {\n        \"id\": 4,\n        \"name\": \"Check\"\n      }\n    ]\n  },\n  \"meta\": {\n    \"total_mappings\": 3,\n    \"mapped_count\": 2,\n    \"unmapped_count\": 1\n  }\n}"}]}]},{"name":"BOMs","item":[{"name":"List BOMs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms?per_page=25","host":["{{baseUrl}}"],"path":["api","manufacturing","boms"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of BOMs. Supports Spatie filters (status, product_id, search) and sort.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms","host":["{{baseUrl}}"],"path":["api","manufacturing","boms"]},"description":"Create a new BOM with output lines, component lines, and (optional) operations.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Consumption method fields:**\n- `default_consumption_method` (optional, enum: `forward_flush` | `backflush`) — BOM-level default inherited by component lines that omit their own `consumption_method`. Null means no default (lines fall back to `forward_flush`).\n- `component_lines[].consumption_method` (optional, enum: `forward_flush` | `backflush`) — how the component is issued when production is recorded. `forward_flush` (the default) waits for the operator to issue the component explicitly with an actual consumed quantity; `backflush` auto-consumes it from the produced output quantity multiplied by the BOM per-unit usage, with no operator entry required. An explicit `null` behaves exactly like omitting the field — the line inherits `default_consumption_method`, falling back to `forward_flush` when the BOM has no default. The method is snapshotted onto each manufacturing-order component line at confirmation, so later BOM edits never change how an already-open order consumes.\n\n**Operation cost fields:** each `operations[]` row accepts `time_minutes`, `cost_per_hour`, and `fixed_cost` (optional, numeric, min 0) — a flat per-run cost added on top of time-based labour. Fixed cost is capitalized onto finished goods the same way labour is, but is never marked up by work-center overhead.\nAuth: requires Bearer token.\n\n`cost_classification` (optional, `labor`|`overhead`, default `labor`) sets the expense classification independently of the rate basis: `labor` posts the operation's variable cost to the Labor bucket (marked up by the work center's overhead %); `overhead` posts machine/tooling-style cost to the Overhead bucket with no additional markup.","body":{"mode":"raw","raw":"{\n  \"product_id\": 1,\n  \"name\": \"Default Recipe v1\",\n  \"version_notes\": \"Initial recipe\",\n  \"status\": \"draft\",\n  \"effective_from\": \"2026-01-01\",\n  \"effective_to\": null,\n  \"is_default\": true,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": 98,\n  \"cost_allocation_method\": \"by_value\",\n  \"default_consumption_method\": \"forward_flush\",\n  \"output_lines\": [\n    {\n      \"product_id\": 1,\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"sort_order\": 0\n    }\n  ],\n  \"component_lines\": [\n    {\n      \"product_id\": 2,\n      \"quantity\": 2,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 2,\n      \"consumption_method\": \"forward_flush\",\n      \"is_optional\": false,\n      \"sort_order\": 0\n    },\n    {\n      \"product_id\": 3,\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"consumption_method\": \"backflush\",\n      \"sort_order\": 1\n    }\n  ],\n  \"operations\": [\n    {\n      \"sequence\": 10,\n      \"name\": \"Mix\",\n      \"work_center_id\": 1,\n      \"operation_type\": \"setup\",\n      \"time_minutes\": 30,\n      \"cost_per_hour\": 45,\n      \"fixed_cost\": 0,\n      \"cost_classification\": \"labor\",\n      \"instructions\": \"Mix components thoroughly.\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/boms","host":["{{baseUrl}}"],"path":["api","manufacturing","boms"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"product_id\": 1,\n  \"product_variant_id\": null,\n  \"name\": \"Default Recipe v1\",\n  \"version_number\": 1,\n  \"version_notes\": \"Initial recipe\",\n  \"status\": \"draft\",\n  \"effective_from\": \"2026-01-01\",\n  \"effective_to\": null,\n  \"is_default\": true,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": 98,\n  \"manufacturing_leadtime_days\": null,\n  \"cost_allocation_method\": \"by_value\",\n  \"default_consumption_method\": \"forward_flush\",\n  \"created_by_id\": 1,\n  \"component_lines\": [\n    {\n      \"id\": 31,\n      \"bom_id\": 12,\n      \"product_id\": 2,\n      \"product_variant_id\": null,\n      \"quantity\": 2,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 2,\n      \"consumption_method\": \"forward_flush\",\n      \"is_optional\": false,\n      \"notes\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    },\n    {\n      \"id\": 32,\n      \"bom_id\": 12,\n      \"product_id\": 3,\n      \"product_variant_id\": null,\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": null,\n      \"consumption_method\": \"backflush\",\n      \"is_optional\": false,\n      \"notes\": null,\n      \"sort_order\": 1,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"output_lines\": [\n    {\n      \"id\": 21,\n      \"bom_id\": 12,\n      \"product_id\": 1,\n      \"product_variant_id\": null,\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"manual_cost_percent\": null,\n      \"byproduct_valuation_method\": null,\n      \"byproduct_valuation_amount\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"operations\": [\n    {\n      \"id\": 7,\n      \"bom_id\": 12,\n      \"sequence\": 10,\n      \"name\": \"Mix\",\n      \"work_center_id\": 1,\n      \"operation_type\": \"setup\",\n      \"time_minutes\": 30,\n      \"cost_per_hour\": 45,\n      \"fixed_cost\": 0,\n      \"cost_classification\": \"labor\",\n      \"instructions\": \"Mix components thoroughly.\"\n    }\n  ],\n  \"archived_at\": null,\n  \"created_at\": \"2026-07-01T10:15:00.000000Z\",\n  \"updated_at\": \"2026-07-01T10:15:00.000000Z\"\n}"}]},{"name":"Bulk Delete BOMs","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms","host":["{{baseUrl}}"],"path":["api","manufacturing","boms"]},"description":"Permanently delete multiple BOMs in one call.\nAuth: requires Bearer token.\nBody: ids (required, array of BOM ids, min 1). Rows that fail to delete are counted in failCount instead of aborting the batch.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/boms","host":["{{baseUrl}}"],"path":["api","manufacturing","boms"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 2 BOM(s)\",\n  \"data\": {\n    \"totalCount\": 2,\n    \"failCount\": 0\n  }\n}"}]},{"name":"Get BOM","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a single BOM with its product, component lines, output lines, operations (with work centers), and creator, plus `manufacturing_orders_count`.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe BOM carries `default_consumption_method` (`forward_flush` | `backflush` | null) — the default inherited by component lines that don't set their own — and each `component_lines[]` row carries its effective `consumption_method`. `forward_flush` components are issued explicitly by the operator when production is recorded; `backflush` components are auto-consumed from the produced output quantity multiplied by the BOM per-unit usage.\nAuth: requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"product_id\": 1,\n  \"product_variant_id\": null,\n  \"product\": {\n    \"id\": 1,\n    \"sku\": \"KIT-A\",\n    \"name\": \"Widget Kit A\",\n    \"stock_uom\": {\n      \"id\": 11,\n      \"product_id\": 1,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"is_stock_uom\": true,\n      \"is_purchase_uom\": true,\n      \"is_sales_uom\": true,\n      \"conversion_factor\": 1,\n      \"display_precision\": 0,\n      \"has_transactional_history\": true\n    }\n  },\n  \"name\": \"Default Recipe v1\",\n  \"version_number\": 1,\n  \"version_notes\": \"Initial recipe\",\n  \"status\": \"active\",\n  \"effective_from\": \"2026-01-01\",\n  \"effective_to\": null,\n  \"is_default\": true,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": 98,\n  \"manufacturing_leadtime_days\": 2,\n  \"cost_allocation_method\": \"by_value\",\n  \"default_consumption_method\": \"forward_flush\",\n  \"created_by_id\": 1,\n  \"created_by\": {\n    \"id\": 1,\n    \"name\": \"Dev User\"\n  },\n  \"component_lines\": [\n    {\n      \"id\": 31,\n      \"bom_id\": 12,\n      \"product_id\": 2,\n      \"product_variant_id\": null,\n      \"product\": {\n        \"id\": 2,\n        \"sku\": \"RM-BEAN\",\n        \"name\": \"Raw Coffee Beans\",\n        \"weight\": 0.5,\n        \"weight_unit\": \"kg\",\n        \"stock_uom\": null\n      },\n      \"quantity\": 2,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"expected_scrap_percent\": 2,\n      \"consumption_method\": \"forward_flush\",\n      \"is_optional\": false,\n      \"notes\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    },\n    {\n      \"id\": 32,\n      \"bom_id\": 12,\n      \"product_id\": 3,\n      \"product_variant_id\": null,\n      \"product\": {\n        \"id\": 3,\n        \"sku\": \"PKG-POUCH\",\n        \"name\": \"250g Pouch\",\n        \"weight\": 0.02,\n        \"weight_unit\": \"kg\",\n        \"stock_uom\": null\n      },\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"expected_scrap_percent\": null,\n      \"consumption_method\": \"backflush\",\n      \"is_optional\": false,\n      \"notes\": null,\n      \"sort_order\": 1,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"output_lines\": [\n    {\n      \"id\": 21,\n      \"bom_id\": 12,\n      \"product_id\": 1,\n      \"product_variant_id\": null,\n      \"product\": {\n        \"id\": 1,\n        \"sku\": \"KIT-A\",\n        \"name\": \"Widget Kit A\",\n        \"weight\": 1.2,\n        \"weight_unit\": \"kg\",\n        \"stock_uom\": null\n      },\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"manual_cost_percent\": null,\n      \"byproduct_valuation_method\": null,\n      \"byproduct_valuation_amount\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"operations\": [\n    {\n      \"id\": 7,\n      \"bom_id\": 12,\n      \"sequence\": 10,\n      \"name\": \"Mix\",\n      \"work_center_id\": 1,\n      \"work_center\": {\n        \"id\": 1,\n        \"name\": \"Mixing Station\",\n        \"overhead_rate_percent\": 10\n      },\n      \"operation_type\": \"setup\",\n      \"time_minutes\": 30,\n      \"cost_per_hour\": 45,\n      \"fixed_cost\": 75,\n      \"instructions\": \"Mix components thoroughly.\"\n    }\n  ],\n  \"manufacturing_orders_count\": 3,\n  \"draft_manufacturing_orders_count\": 2,\n  \"archived_at\": null,\n  \"created_at\": \"2026-07-01T10:15:00.000000Z\",\n  \"updated_at\": \"2026-07-02T08:30:00.000000Z\"\n}"}]},{"name":"Update BOM","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update a BOM. All fields are optional — omitted fields keep their current values.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`default_consumption_method` (nullable, enum: `forward_flush` | `backflush`) sets the BOM-level default inherited by component lines that omit their own `consumption_method`; a per-line `consumption_method` always overrides it. A component line submitted with an explicit `consumption_method: null` behaves exactly like omitting the field — a new line inherits the BOM default (falling back to `forward_flush`), and an existing line keeps its current method. Changing consumption methods only affects manufacturing orders confirmed after the change — each order snapshots the method per component line at confirmation, so open orders keep consuming the way they were confirmed.\nAuth: requires Bearer token.\n\n`cost_classification` (optional, `labor`|`overhead`, default `labor`) sets the expense classification independently of the rate basis: `labor` posts the operation's variable cost to the Labor bucket (marked up by the work center's overhead %); `overhead` posts machine/tooling-style cost to the Overhead bucket with no additional markup.","body":{"mode":"raw","raw":"{\n  \"name\": \"Default Recipe v2\",\n  \"version_notes\": \"Adjusted scrap\",\n  \"cost_allocation_method\": \"by_quantity\",\n  \"default_consumption_method\": \"backflush\",\n  \"component_lines\": [\n    {\n      \"id\": 11,\n      \"product_id\": 2,\n      \"quantity\": 2.5,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 3,\n      \"consumption_method\": \"forward_flush\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"product_id\": 1,\n  \"product_variant_id\": null,\n  \"name\": \"Default Recipe v2\",\n  \"version_number\": 1,\n  \"version_notes\": \"Adjusted scrap\",\n  \"status\": \"active\",\n  \"effective_from\": \"2026-01-01\",\n  \"effective_to\": null,\n  \"is_default\": true,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": 98,\n  \"manufacturing_leadtime_days\": 2,\n  \"cost_allocation_method\": \"by_quantity\",\n  \"default_consumption_method\": \"backflush\",\n  \"created_by_id\": 1,\n  \"component_lines\": [\n    {\n      \"id\": 11,\n      \"bom_id\": 12,\n      \"product_id\": 2,\n      \"product_variant_id\": null,\n      \"quantity\": 2.5,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 3,\n      \"consumption_method\": \"forward_flush\",\n      \"is_optional\": false,\n      \"notes\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"output_lines\": [\n    {\n      \"id\": 21,\n      \"bom_id\": 12,\n      \"product_id\": 1,\n      \"product_variant_id\": null,\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1,\n      \"manual_cost_percent\": null,\n      \"byproduct_valuation_method\": null,\n      \"byproduct_valuation_amount\": null,\n      \"sort_order\": 0,\n      \"estimated_cost\": 0.03\n    }\n  ],\n  \"operations\": [],\n  \"archived_at\": null,\n  \"created_at\": \"2026-07-01T10:15:00.000000Z\",\n  \"updated_at\": \"2026-07-02T11:40:00.000000Z\"\n}"}]},{"name":"Delete BOM","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete BOM\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Duplicate BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/duplicate","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","duplicate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deep-clones a BOM into a new draft (output lines, component lines, operations). The new BOM's name is the source's name with \" (Copy)\" appended; if that name is already taken for the same product/variant the suffix becomes \" (Copy 2)\", \" (Copy 3)\", etc.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Save BOM as New Version","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{bom}/save-as-new-version","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":bom","save-as-new-version"],"variable":[{"key":"bom","value":"1","description":"The bom ID."}]},"description":"Create a new version of the BOM from the submitted fields, leaving the source version untouched. Accepts the same fields as Update BOM. The new version is created as Active with version_number set to the next number for the same product/variant.\nAuth: requires Bearer token.\nPath param: bom = source BOM id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`update_draft_mos` (boolean, optional, default false): when true, every still-in-Draft manufacturing order that references the old version is moved onto the new version. Started/completed orders keep their pinned version.","body":{"mode":"raw","raw":"{\n  \"name\": \"Default Recipe\",\n  \"version_notes\": \"Reduced component scrap\",\n  \"effective_from\": \"2026-07-01\",\n  \"cost_allocation_method\": \"by_weight\",\n  \"default_consumption_method\": \"forward_flush\",\n  \"output_lines\": [\n    {\n      \"product_id\": 1,\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1\n    }\n  ],\n  \"component_lines\": [\n    {\n      \"product_id\": 2,\n      \"quantity\": 2.5,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 3,\n      \"consumption_method\": \"forward_flush\"\n    }\n  ],\n  \"update_draft_mos\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{bom}/save-as-new-version","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":bom","save-as-new-version"],"variable":[{"key":"bom","value":"1","description":"The bom ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 15,\n  \"product_id\": 1,\n  \"product_variant_id\": null,\n  \"name\": \"Default Recipe\",\n  \"version_number\": 3,\n  \"version_notes\": \"Reduced component scrap\",\n  \"status\": \"active\",\n  \"effective_from\": \"2026-07-01\",\n  \"effective_to\": null,\n  \"is_default\": false,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": null,\n  \"manufacturing_leadtime_days\": 2,\n  \"cost_allocation_method\": \"by_weight\",\n  \"default_consumption_method\": \"forward_flush\",\n  \"created_by_id\": 1,\n  \"component_lines\": [\n    {\n      \"id\": 61,\n      \"product_id\": 2,\n      \"quantity\": 2.5,\n      \"uom_id\": 1,\n      \"expected_scrap_percent\": 3,\n      \"consumption_method\": \"forward_flush\"\n    }\n  ],\n  \"output_lines\": [\n    {\n      \"id\": 44,\n      \"product_id\": 1,\n      \"role\": \"primary\",\n      \"quantity\": 1,\n      \"uom_id\": 1\n    }\n  ],\n  \"operations\": [],\n  \"manufacturing_orders_count\": 0,\n  \"draft_manufacturing_orders_count\": 0,\n  \"archived_at\": null,\n  \"created_at\": \"2026-07-01T14:22:09.000000Z\",\n  \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n}"}]},{"name":"Activate BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/activate","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","activate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Transitions a draft BOM to active. Optionally overrides effective dates.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"effective_from\": \"2026-04-19\",\n  \"effective_to\": null\n}","options":{"raw":{"language":"json"}}}}},{"name":"Deactivate BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/deactivate","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","deactivate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Transitions an Active BOM back to Draft so it can be edited without archiving it (distinct from Archive, which retires the BOM). If the BOM was the default for its product/variant, the next eligible BOM is auto-promoted. Returns the refreshed BOM object under `data` (200), plus a root-level `promoted_default` object ({id, name, version_number}) naming the newly-promoted default — or `null` if nothing was promoted. The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Needs a recipe correction before re-activating\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Archive BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/archive","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives an Active BOM, marking it as retired (sets `archived_at`). If the archived BOM was the default for its product/variant, the next eligible BOM is auto-promoted to default. Returns the refreshed BOM object under `data` (200), plus a root-level `promoted_default` object ({id, name, version_number}) naming the newly-promoted default — or `null` if nothing was promoted. The frontend uses this to show \"BOM archived — {name} v{version} is now the default\". The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Superseded by v2\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Restore BOM","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/restore","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","restore"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Restores an archived BOM back to Draft status. Clears `archived_at` and removes the `is_default` flag so it does not auto-promote on next activation. The caller can then re-activate from Draft when ready. Returns the refreshed BOM object (200). Returns 500 if the BOM is not currently archived. The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Customer asked us to bring this recipe back.\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Archive BOMs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/bulk-archive","host":["{{baseUrl}}"],"path":["api","manufacturing","boms","bulk-archive"]},"description":"Archives multiple BOMs in one call. Body: `ids` (required array of BOM IDs, min 1; each must exist in `boms`). Only BOMs currently in `active` status are archived; BOMs in any other status are skipped. Each archived BOM that was a default triggers auto-promotion of the next eligible BOM for its product/variant. Returns a `message` summary and a `data` object: `{ totalCount, archivedCount, skippedCount, failCount }`.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/bulk-archive","host":["{{baseUrl}}"],"path":["api","manufacturing","boms","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Archived 2 BOM(s) (1 skipped)\",\n  \"data\": {\n    \"totalCount\": 3,\n    \"archivedCount\": 2,\n    \"skippedCount\": 1,\n    \"failCount\": 0\n  }\n}"}]},{"name":"Bulk Restore BOMs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/bulk-restore","host":["{{baseUrl}}"],"path":["api","manufacturing","boms","bulk-restore"]},"description":"Restores multiple archived BOMs back to Draft in one call. Body: `ids` (required array of BOM IDs, min 1; each must exist in `boms`). Only BOMs currently in `archived` status are restored; BOMs in any other status are skipped. Returns a `message` summary and a `data` object: `{ totalCount, restoredCount, skippedCount, failCount }`.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/bulk-restore","host":["{{baseUrl}}"],"path":["api","manufacturing","boms","bulk-restore"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Restored 3 BOM(s)\",\n  \"data\": {\n    \"totalCount\": 3,\n    \"restoredCount\": 3,\n    \"skippedCount\": 0,\n    \"failCount\": 0\n  }\n}"}]},{"name":"Set BOM as Default","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/set-default","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","set-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Promotes the given BOM to be the default for its product/variant. Any other BOM currently marked default for the same product (and variant, if scoped) is automatically demoted to `is_default = false`. This is the single-record endpoint backing the kebab \"Set as Default\" action; for status transitions use `activate`/`archive` instead. Returns the refreshed BOM object (200). No request body is required.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/set-default","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","set-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 14,\n  \"product_id\": 822,\n  \"product_variant_id\": null,\n  \"name\": \"Vanilla Latte v3\",\n  \"version_number\": 3,\n  \"version_notes\": null,\n  \"status\": \"active\",\n  \"effective_from\": \"2026-05-28\",\n  \"effective_to\": null,\n  \"is_default\": true,\n  \"is_phantom\": false,\n  \"expected_yield_percent\": null,\n  \"cost_allocation_method\": \"by_weight\",\n  \"created_by_id\": 1,\n  \"archived_at\": null,\n  \"created_at\": \"2026-05-28T09:14:11.000000Z\",\n  \"updated_at\": \"2026-05-28T11:02:48.000000Z\"\n}"}]},{"name":"Get Current Default for BOM","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/current-default","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","current-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns the BOM currently marked default for the same product/variant as the given BOM, excluding the given BOM itself. Used by the UI to name the existing default in a \"Set as Default\" confirmation dialog (e.g. \"This will replace 'Vanilla Latte v2' as the default.\"). Returns `{ \"data\": { id, name, version_number } }` when another default exists; returns `{ \"data\": null }` when there is no other default for that product/variant.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/current-default","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","current-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Vanilla Latte v2\",\n    \"version_number\": 2\n  }\n}"}]},{"name":"Explode BOM","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{id}/explode?quantity=10","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":id","explode"],"query":[{"key":"quantity","value":"10","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Recursively explodes a BOM into its full multi-level component list for a target quantity.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List BOM Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{bom}/activity-log","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":bom","activity-log"],"variable":[{"key":"bom","value":"1","description":"The bom ID."}]},"description":"Paginated audit trail of changes made to the BOM and its lines - who changed what and when, newest first.\nAuth: requires Bearer token.\nPath param: bom = BOM id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/boms/{bom}/activity-log","host":["{{baseUrl}}"],"path":["api","manufacturing","boms",":bom","activity-log"],"variable":[{"key":"bom","value":"1","description":"The bom ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 911,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Bom\",\n      \"subject_id\": 15,\n      \"properties\": {\n        \"attributes\": {\n          \"name\": \"Default Recipe v2\"\n        },\n        \"old\": {\n          \"name\": \"Default Recipe\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-07-01T14:22:09.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://your-domain.sku.io/api/manufacturing/boms/15/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-domain.sku.io/api/manufacturing/boms/15/activity-log?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://your-domain.sku.io/api/manufacturing/boms/15/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]}]},{"name":"Manufacturing Orders","item":[{"name":"List Manufacturing Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders?per_page=25","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of Manufacturing Orders. Supports Spatie QueryBuilder filters, sorts, and pagination.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Filters** (all optional, all use `filter[key]=value` syntax):\n- `filter[status]` — exact match against `draft|confirmed|in_progress|completed|closed|cancelled`\n- `filter[warehouse_id]` — exact match\n- `filter[is_simple_mode]` — `1` to show only Simple Mode MOs (created via /simple-assemble)\n- `filter[is_disassemble]` — `1` to show only disassembly MOs (Simple Mode with action=disassemble)\n\n**Sort:** `sort=<field>`, prefix with `-` for DESC (e.g. `-created_at`). Defaults to `-created_at`. Allowed sorts: id, mo_number, status, priority, production_method, scheduled_start, scheduled_end, started_at, completed_at, planned_quantity, completed_quantity, created_at, updated_at, warehouse_name, contractor_supplier_name, assigned_to. `warehouse_name`, `contractor_supplier_name`, and `assigned_to` sort by the related warehouse / supplier / assignee name (LEFT JOIN).\n**Pagination:** `page`, `per_page` (default 10).\n\nResponse items are manufacturing order list object (trimmed payload — no component_lines/output_lines). `primary_output_name` / `primary_output_product_id` resolve the primary output line's product, falling back to the BOM output product for draft MOs (so the list can link the Output cell to the product detail page)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders?per_page=25","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"mo_number\": \"MO-000042\",\n      \"status\": \"confirmed\",\n      \"bom_id\": 88,\n      \"bom_name\": \"Premium Hoodie Assembly v3\",\n      \"warehouse_id\": 2,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"destination_warehouse_id\": 2,\n      \"destination_warehouse_name\": \"Main Warehouse\",\n      \"primary_output_name\": \"Premium Cotton Hoodie - Black - L\",\n      \"primary_output_product_id\": 4551,\n      \"planned_quantity\": 250,\n      \"completed_quantity\": 0,\n      \"production_method\": \"in_house\",\n      \"contractor_supplier_id\": null,\n      \"contractor_supplier_name\": null,\n      \"outsourced_purchase_order_id\": null,\n      \"sales_order_id\": null,\n      \"sales_order_line_id\": null,\n      \"priority\": 10,\n      \"scheduled_start\": \"2026-07-05T08:00:00.000000Z\",\n      \"scheduled_end\": \"2026-07-08T17:00:00.000000Z\",\n      \"started_at\": null,\n      \"completed_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"is_simple_mode\": false,\n      \"is_disassemble\": false,\n      \"internal_reference\": \"Batch Q3-A\",\n      \"assigned_to_id\": 7,\n      \"assigned_to\": {\n        \"id\": 7,\n        \"name\": \"Jamie Rivera\"\n      },\n      \"cost_breakdown\": null,\n      \"has_shortage\": false,\n      \"created_at\": \"2026-07-01T14:32:10.000000Z\",\n      \"updated_at\": \"2026-07-02T09:15:44.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 25,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 25\n}"}]},{"name":"Create Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders"]},"description":"Create a draft MO from a BOM. Hydrates component + output + operation snapshot lines from the BOM.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFor outsourced orders (production_method: outsourced) the request also accepts: contractor_supplier_id (required for outsourced, integer, must be a supplier flagged as a manufacturing contractor); outsourced_cost_basis (optional, string, one of: toll, hybrid) - how the contractor's product charge is costed into the finished output. toll = you own all component materials and the charge is a processing cost only; hybrid = the contractor supplies additional materials of their own and the charge is capitalized into output cost. When omitted the contractor's default_outsourced_cost_basis applies, falling back to hybrid; service_fee_amount (optional, numeric, min 0). These three fields are rejected for in_house orders.","body":{"mode":"raw","raw":"{\n  \"bom_id\": 1,\n  \"warehouse_id\": 1,\n  \"destination_warehouse_id\": 1,\n  \"planned_quantity\": 100,\n  \"production_method\": \"in_house\",\n  \"contractor_supplier_id\": 12,\n  \"outsourced_cost_basis\": \"toll\",\n  \"priority\": 10,\n  \"scheduled_start\": \"2026-04-22\",\n  \"scheduled_end\": \"2026-04-24\",\n  \"notes\": \"Standard production run\",\n  \"internal_reference\": \"BATCH-001\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Manufacturing Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Return the full Manufacturing Order with its BOM, component/output lines, operations, warehouses, and events.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**BOM line counts (P5/P6):** The nested `bom` object includes `component_lines_count`, `output_lines_count`, and `operations_count` (eager-loaded via `withCount`). For **draft** MOs — which have no materialised `component_lines`/`output_lines`/`operations` rows yet (those are created by ConfirmMoAction) — clients should fall back to these BOM counts when rendering tab badges and the footer summary so the user sees what the MO *will* contain once confirmed.\n\nOnce production has been recorded, `cost_breakdown` is populated with cumulative cost categories: `materials`, `labor`, `overhead`, `fixed` (flat per-run operation costs — never marked up by overhead), `service_fee`, `landed_cost` (outsourced orders only), `total`, `allocation_method`, `recorded_at`, and per-output allocation rows in `outputs[]`. It is null until the first production record.\n\nEach `component_lines[]` row carries `consumption_method` (`forward_flush` | `backflush`) — snapshotted from the BOM at confirmation — and each `operations[]` row carries `fixed_cost` plus `cost_source` (`none` | `actual` | `estimated` | `manual`) — the provenance of its `actual_cost`: `estimated` flags a cost that fell back to the planned duration because no time was logged, and `manual` marks an explicitly supplied cost that is never auto-recalculated (only another explicit cost, or an explicitly logged positive time, replaces it).\n\n**Outsourced cost basis:** `outsourced_cost_basis` is the order's explicit override (`toll` | `hybrid`, null = inherit) and `resolved_outsourced_cost_basis` is the basis actually used for costing (override, else the contractor's `default_outsourced_cost_basis`, else `hybrid`). `resolved_outsourced_cost_basis` is null for in-house orders. The nested `contractor_supplier` object also carries the contractor's `default_outsourced_cost_basis`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 18,\n  \"mo_number\": \"MO-000018\",\n  \"status\": \"draft\",\n  \"bom_id\": 2,\n  \"bom\": {\n    \"id\": 2,\n    \"product_id\": 412,\n    \"product\": {\n      \"id\": 412,\n      \"sku\": \"WIDGET-A\",\n      \"name\": \"Widget A — Finished\"\n    },\n    \"name\": \"Widget A BOM\",\n    \"version_number\": 1,\n    \"status\": \"active\",\n    \"effective_from\": \"2026-01-01\",\n    \"effective_to\": null,\n    \"is_default\": true,\n    \"is_phantom\": false,\n    \"cost_allocation_method\": \"by_weight\",\n    \"component_lines_count\": 3,\n    \"output_lines_count\": 1,\n    \"operations_count\": 2,\n    \"archived_at\": null,\n    \"created_at\": \"2026-05-20T10:00:00.000000Z\",\n    \"updated_at\": \"2026-05-20T10:00:00.000000Z\"\n  },\n  \"warehouse_id\": 1,\n  \"warehouse\": {\n    \"id\": 1,\n    \"name\": \"Main Warehouse\"\n  },\n  \"destination_warehouse_id\": 1,\n  \"destination_warehouse\": {\n    \"id\": 1,\n    \"name\": \"Main Warehouse\"\n  },\n  \"planned_quantity\": 10,\n  \"completed_quantity\": 0,\n  \"production_method\": \"in_house\",\n  \"contractor_supplier_id\": null,\n  \"outsourced_cost_basis\": null,\n  \"resolved_outsourced_cost_basis\": null,\n  \"outsourced_purchase_order_id\": null,\n  \"sales_order_id\": null,\n  \"sales_order_line_id\": null,\n  \"priority\": 100,\n  \"scheduled_start\": null,\n  \"scheduled_end\": null,\n  \"started_at\": null,\n  \"completed_at\": null,\n  \"closed_at\": null,\n  \"cancelled_at\": null,\n  \"cancelled_reason_code\": null,\n  \"cancelled_reason_notes\": null,\n  \"is_simple_mode\": false,\n  \"is_disassemble\": false,\n  \"notes\": null,\n  \"internal_reference\": null,\n  \"cost_breakdown\": null,\n  \"created_by_id\": 1,\n  \"created_by\": {\n    \"id\": 1,\n    \"name\": \"Dev User\"\n  },\n  \"assigned_to_id\": null,\n  \"component_lines\": [],\n  \"output_lines\": [],\n  \"operations\": [],\n  \"events\": [],\n  \"created_at\": \"2026-05-28T09:00:00.000000Z\",\n  \"updated_at\": \"2026-05-28T09:00:00.000000Z\",\n  \"archived_at\": null\n}"}]},{"name":"Update Manufacturing Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update Manufacturing Order\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`warehouse_id`, `destination_warehouse_id` and `planned_quantity` are only applied while the order is Draft — from Confirmed onward component requirements and allocations are already sized to them, so the values are pinned.","body":{"mode":"raw","raw":"{\n  \"planned_quantity\": 120,\n  \"priority\": 20,\n  \"notes\": \"Increased to cover backorders\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Manufacturing Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Only draft MOs may be deleted.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Confirm Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/confirm","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","confirm"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Draft -> Confirmed. Reserves components. Optionally lock in FIFO layer picks keyed by mo_component_line_id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"priority\": 10,\n  \"scheduled_start\": \"2026-04-22\",\n  \"scheduled_end\": \"2026-04-24\",\n  \"lot_picks\": {\n    \"1\": [\n      101,\n      102\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}}},{"name":"Preview Manufacturing Order Confirmation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/confirm-preview","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","confirm-preview"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]},"description":"Dry run of Confirm for a Draft manufacturing order. Computes per-component shortages and the largest planned quantity current inventory could support end-to-end, without changing any state. For orders that are no longer Draft, the response contains empty shortages and a reason explaining that the preview only applies before confirmation.\nAuth: requires Bearer token.\nPath param: manufacturingOrder = manufacturing order id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/confirm-preview","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","confirm-preview"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"shortages\": [\n    {\n      \"product_id\": 2,\n      \"product_sku\": \"CMP-001\",\n      \"product_name\": \"Widget Frame\",\n      \"required_quantity\": 250,\n      \"allocated_quantity\": 180,\n      \"short_by_quantity\": 70,\n      \"uom_code\": \"EA\"\n    }\n  ],\n  \"max_producible_quantity\": 72,\n  \"requested_quantity\": 100\n}"}]},{"name":"Unconfirm Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/unconfirm","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","unconfirm"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]},"description":"Reverse a Confirm: moves the order from Confirmed back to Draft, releases its component inventory allocations, and discards the BOM-derived component lines, output lines, and operations. Operations added manually after confirmation are kept.\nAuth: requires Bearer token.\nPath param: manufacturingOrder = manufacturing order id.\nBody: reason (optional, string, max 1000) recorded on the order's event log.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Confirmed against the wrong warehouse\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/unconfirm","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","unconfirm"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"mo_number\": \"MO-00042\",\n  \"status\": \"draft\",\n  \"bom_id\": 15,\n  \"warehouse_id\": 3,\n  \"destination_warehouse_id\": 3,\n  \"planned_quantity\": 100,\n  \"completed_quantity\": 0,\n  \"production_method\": \"in_house\",\n  \"contractor_supplier_id\": null,\n  \"outsourced_purchase_order_id\": null,\n  \"sales_order_id\": null,\n  \"sales_order_line_id\": null,\n  \"priority\": 0,\n  \"scheduled_start\": null,\n  \"scheduled_end\": null,\n  \"started_at\": null,\n  \"completed_at\": null,\n  \"closed_at\": null,\n  \"cancelled_at\": null,\n  \"cancelled_reason_code\": null,\n  \"cancelled_reason_notes\": null,\n  \"is_simple_mode\": false,\n  \"is_disassemble\": false,\n  \"notes\": null,\n  \"internal_reference\": null,\n  \"cost_breakdown\": null,\n  \"created_by_id\": 1,\n  \"assigned_to_id\": null,\n  \"created_at\": \"2026-06-28T10:15:00.000000Z\",\n  \"updated_at\": \"2026-07-01T14:22:09.000000Z\",\n  \"archived_at\": null\n}"}]},{"name":"Start Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/start","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","start"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Confirmed -> In Progress.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"started_at\": \"2026-04-22T08:00:00Z\",\n  \"assigned_to_id\": 1,\n  \"notes\": \"Production run kicked off\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Record Production","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/record-production","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","record-production"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Record actual component consumption, output produced, and operation actuals for an in-progress MO. Posts inventory movements (consumption + receipts) and creates FIFO layers for outputs.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Lot tracking validation (B23/B24):**\n- `outputs[].batch_number` is **required** when the output product is `is_lot_tracked = true`.\n- `outputs[].expiry_date` is **required** when the output product has `lot_tracking_method = fefo`.\n- Validation errors are returned per-output with dot notation, e.g. `outputs.0.batch_number`.\n\nThe MO Show endpoint (`GET /api/manufacturing/manufacturing-orders/{id}`) exposes `output_lines[].product` and `component_lines[].product` with `is_lot_tracked`, `lot_tracking_method`, `shelf_life_days`, `near_expiry_threshold_days`, and `min_remaining_shelf_life_days` so clients can drive UI gating before submitting.\n\n**Component lot consumption override (FEFO suggest-with-override):**\n- Each `components[]` entry may carry an optional `lot_allocation[]` of `{fifo_layer_id, quantity}` to choose exactly which lots of a lot-tracked component are consumed. Omit it to consume by automatic FEFO/FIFO.\n- The allocation must reconcile to that component's total draw this run (`actual_consumed_quantity + actual_scrap_quantity`), reference active FIFO layers of that component product + the MO's source warehouse, and respect the tenant's lot-override policy (under `enforce`, consuming expired stock or a later-expiry lot for a FEFO product is hard-blocked).\n- The legacy `components[].fifo_layer_ids[]` (restrict-eligibility, FEFO-ordered) is still accepted; `lot_allocation[]` takes precedence when both are present.\n- Validation errors are returned per row with dot notation, e.g. `components.0.lot_allocation.1.fifo_layer_id`.\n\n**Over-consumption guard (BQ8):** if `components[].actual_consumed_quantity` exceeds the quantity reserved (Allocated) for that component line at Start, the call returns **422** with `code = over_consumption` and an `offending[]` array (per-component `requested_quantity` vs `allocated_quantity`) instead of a 500. The whole call rolls back — MO status and consumption are unchanged.\n\nDestination bin: each output may optionally set `warehouse_location_id` — the bin the produced quantity is received into. When omitted, the assembly's preferred bin (or the warehouse's default storage location) is used.\n\n**Request `components` (present, may be empty):** the `components` array must always be present, but it no longer needs at least one entry. Only `forward_flush` component lines need entries — omit `backflush` lines entirely (they are consumed automatically, prorated to the recorded output), and submit `\"components\": []` when every component line on the order is backflush. Including an entry for a backflush line acts as a manual override of the automatic quantity for that run.\n\n**Backflush components:** component lines with `consumption_method = backflush` are consumed automatically — for each backflush line without an explicit `components[]` entry, the recorded output is converted to that line's BOM-implied usage (per-unit usage multiplied by cumulative primary output produced — deliberately uncapped, so over-yield beyond the planned quantity consumes proportionally more — minus what earlier production records already consumed) and issued through the same FIFO/lot machinery as operator entries. Consumption beyond the quantity reserved at confirmation automatically tops up the line's allocation from free (unreserved) stock; when free stock cannot cover the excess the request fails with the same structured 422s as a manual over-issue (`code = insufficient_inventory` when the stock physically does not exist, `code = over_consumption` when it exists but is reserved by other documents) and the whole call rolls back. Submitting an explicit `components[]` entry for a backflush line overrides the automatic quantity for that run. `forward_flush` lines are only consumed when an explicit entry is submitted.\n\n**Response `cost_breakdown`:** the returned manufacturing order carries a cumulative `cost_breakdown` object: `materials` (FIFO value consumed so far), `labor` (time-based operation labour), `overhead` (labour multiplied by the work-center overhead percent), `fixed` (flat per-run operation costs — never marked up by overhead), `service_fee` and `landed_cost` (outsourced orders only), `total`, `allocation_method`, `recorded_at`, and per-output allocation rows in `outputs[]`.\n\n**Operation costing without a timer:** each `operations[]` row in the response reports `fixed_cost`, `actual_cost`, and `cost_source` — `none` (no cost recorded), `actual` (from logged time or a flat fixed-cost operation), `estimated` (fell back to the planned duration because no time was logged), or `manual` (an explicitly supplied cost that is never auto-recalculated — only another explicit cost, or an explicitly logged positive time, replaces it).\n\n**Insufficient stock guard:** if a component's FIFO layers in the MO's source warehouse cannot cover the quantity to consume (forward-flush or backflush), the call returns **422** with `code = insufficient_inventory` and an `offending[]` array (`product_id`, `product_sku`, `product_name`, `warehouse_id`, `requested_quantity`, `available_quantity`). The whole call rolls back — no movements, FIFO layers, or production iterations are written.\n\n**Explicit lot allocation shortages:** shortage failures inside an explicit `lot_allocation[]` return the same **422** `code = insufficient_inventory` envelope (previously an internal error). A named lot that is no longer an active layer for the component at consumption time, or a lot that cannot cover its requested quantity, reports the usual `product_id`, `product_sku`, `product_name`, `warehouse_id`, `requested_quantity`, `available_quantity` row. A lot-level overdraw detected mid-consumption (e.g. duplicate entries naming the same lot whose combined quantity exceeds its availability) identifies the lot with `fifo_layer_id` and reports the layer's real state at the failed draw — `layer_original_quantity`, `layer_fulfilled_quantity` (includes quantities drawn earlier in the same rolled-back call), and `layer_remaining_quantity` — rather than a fabricated requested/available pair. The whole call rolls back.\n\n**Downward cost revision guard:** operation cost revisions between production records are recognized as SIGNED deltas on the next iteration's journal — negative buckets post as balanced flipped legs (e.g. a debit to Direct Labor Applied) and a net-zero reclassification still posts its offsetting legs. When a negative conversion delta exceeds the value this run's output FIFO layers can absorb (a layer's cost would drop below zero), the call returns **422** with `code = cost_revision_exceeds_layer_value`, the signed `conversion_delta`, and an `offending[]` array (`output_line_id`, `fifo_layer_id`, `product_id`, `product_sku`, `product_name`, `layer_cost`, `revision_share`, `resulting_cost`). The whole call rolls back — reverse the over-costed earlier iteration and re-record it with the corrected operation costs.","body":{"mode":"raw","raw":"{\n  \"completed_quantity\": 100,\n  \"production_date\": \"2026-04-23\",\n  \"notes\": \"Full run completed\",\n  \"components\": [\n    {\n      \"mo_component_line_id\": 1,\n      \"actual_consumed_quantity\": 200,\n      \"actual_scrap_quantity\": 4,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 101,\n          \"quantity\": 150\n        },\n        {\n          \"fifo_layer_id\": 102,\n          \"quantity\": 54\n        }\n      ],\n      \"scrap_reason_code\": \"spillage\"\n    },\n    {\n      \"mo_component_line_id\": 2,\n      \"actual_consumed_quantity\": 100,\n      \"actual_scrap_quantity\": 0\n    }\n  ],\n  \"outputs\": [\n    {\n      \"mo_output_line_id\": 1,\n      \"actual_produced_quantity\": 100,\n      \"batch_number\": \"LOT-2026-04-001\",\n      \"expiry_date\": \"2027-04-23\",\n      \"catch_weight\": null,\n      \"warehouse_location_id\": 15\n    }\n  ],\n  \"operation_actuals\": [\n    {\n      \"mo_operation_id\": 1,\n      \"actual_time_minutes\": 35,\n      \"operator_id\": 1,\n      \"status\": \"completed\",\n      \"notes\": \"Ran 5 minutes over\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/record-production","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","record-production"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 14,\n  \"mo_number\": \"MO-000014\",\n  \"status\": \"in_progress\",\n  \"bom_id\": 12,\n  \"warehouse_id\": 1,\n  \"destination_warehouse_id\": 1,\n  \"planned_quantity\": 100,\n  \"completed_quantity\": 100,\n  \"production_method\": \"in_house\",\n  \"contractor_supplier_id\": null,\n  \"outsourced_purchase_order_id\": null,\n  \"sales_order_id\": null,\n  \"sales_order_line_id\": null,\n  \"priority\": 0,\n  \"scheduled_start\": \"2026-04-22T08:00:00.000000Z\",\n  \"scheduled_end\": \"2026-04-24T17:00:00.000000Z\",\n  \"started_at\": \"2026-04-22T08:05:00.000000Z\",\n  \"completed_at\": null,\n  \"closed_at\": null,\n  \"cancelled_at\": null,\n  \"cancelled_reason_code\": null,\n  \"cancelled_reason_notes\": null,\n  \"is_simple_mode\": false,\n  \"is_disassemble\": false,\n  \"notes\": \"Full run completed\",\n  \"internal_reference\": null,\n  \"cost_breakdown\": {\n    \"materials\": 1240.5,\n    \"labor\": 26.25,\n    \"overhead\": 2.625,\n    \"fixed\": 75,\n    \"service_fee\": 0,\n    \"landed_cost\": 0,\n    \"total\": 1344.375,\n    \"allocation_method\": \"by_value\",\n    \"outputs\": [\n      {\n        \"mo_output_line_id\": 1,\n        \"product_id\": 1,\n        \"role\": \"primary\",\n        \"produced_quantity\": 100,\n        \"allocated_cost\": 1344.375,\n        \"allocated_this_step\": 1344.375,\n        \"unit_cost\": 13.44375\n      }\n    ],\n    \"recorded_at\": \"2026-04-23T14:12:09+00:00\"\n  },\n  \"created_by_id\": 1,\n  \"assigned_to_id\": null,\n  \"component_lines\": [\n    {\n      \"id\": 1,\n      \"manufacturing_order_id\": 14,\n      \"bom_component_line_id\": 31,\n      \"product_id\": 2,\n      \"product_variant_id\": null,\n      \"expected_quantity\": 200,\n      \"actual_consumed_quantity\": 200,\n      \"expected_scrap_quantity\": 4,\n      \"actual_scrap_quantity\": 4,\n      \"scrap_reason_code\": \"spillage\",\n      \"uom_id\": 1,\n      \"consumption_method\": \"forward_flush\",\n      \"consumption_posted_at\": \"2026-04-23T14:12:09.000000Z\",\n      \"estimated_cost\": 100\n    },\n    {\n      \"id\": 2,\n      \"manufacturing_order_id\": 14,\n      \"bom_component_line_id\": 32,\n      \"product_id\": 3,\n      \"product_variant_id\": null,\n      \"expected_quantity\": 100,\n      \"actual_consumed_quantity\": 100,\n      \"expected_scrap_quantity\": 0,\n      \"actual_scrap_quantity\": 0,\n      \"scrap_reason_code\": null,\n      \"uom_id\": 1,\n      \"consumption_method\": \"backflush\",\n      \"consumption_posted_at\": \"2026-04-23T14:12:09.000000Z\",\n      \"estimated_cost\": 100\n    }\n  ],\n  \"output_lines\": [\n    {\n      \"id\": 1,\n      \"manufacturing_order_id\": 14,\n      \"bom_output_line_id\": 21,\n      \"product_id\": 1,\n      \"product_variant_id\": null,\n      \"role\": \"primary\",\n      \"expected_quantity\": 100,\n      \"actual_produced_quantity\": 100,\n      \"uom_id\": 1,\n      \"allocated_cost\": 1344.375,\n      \"batch_number\": \"LOT-2026-04-001\",\n      \"expiry_date\": \"2027-04-23\"\n    }\n  ],\n  \"operations\": [\n    {\n      \"id\": 1,\n      \"manufacturing_order_id\": 14,\n      \"source\": \"from_bom\",\n      \"bom_operation_id\": 7,\n      \"sequence\": 10,\n      \"name\": \"Mix\",\n      \"type\": \"setup\",\n      \"operation_type\": \"setup\",\n      \"expected_duration_minutes\": 30,\n      \"hourly_rate\": 45,\n      \"status\": \"completed\",\n      \"scheduled_start\": null,\n      \"started_at\": null,\n      \"completed_at\": \"2026-04-23T14:12:09.000000Z\",\n      \"actual_time_minutes\": 35,\n      \"operator_id\": 1,\n      \"default_operator_id\": null,\n      \"work_center_id\": 1,\n      \"fixed_cost\": 75,\n      \"actual_cost\": 101.25,\n      \"cost_source\": \"actual\",\n      \"notes\": \"Ran 5 minutes over\",\n      \"is_modified_from_bom\": false\n    }\n  ],\n  \"events\": [],\n  \"created_at\": \"2026-04-20T09:00:00.000000Z\",\n  \"updated_at\": \"2026-04-23T14:12:09.000000Z\",\n  \"archived_at\": null\n}"}]},{"name":"Complete Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/complete","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","complete"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"In Progress -> Completed. Finalizes variance calculations.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Cancel Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/cancel","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","cancel"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Cancel a manufacturing order. Transitions any non-closed status → Cancelled and releases any inventory reservations.\n\n**Required body fields:**\n- `reason_code` (string, required) — must be one of the 5 allowed values:\n  - `plan_changed` — Plan changed\n  - `materials_unavailable` — Materials unavailable\n  - `customer_cancellation` — Customer cancellation\n  - `equipment_issue` — Equipment issue\n  - `other` — Other\n\n**Optional body fields:**\n- `notes` (string, nullable, max 2000) — Free-text reason explanation\n- `reason_notes` (string, nullable, max 2000) — **Alias for `notes`** — accepted for API consistency. If `notes` is absent and `reason_notes` is provided, it is copied into `notes` during validation. Sending both means `notes` wins.\n\n**Returns 422 if `reason_code` is missing or not in the allowed list.**\n**Authentication:** Bearer token required.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason_code\": \"customer_cancellation\",\n  \"notes\": \"Sales order cancelled upstream\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/cancel","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","cancel"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"manufacturing_order_number\": \"MO-000001\",\n  \"status\": \"cancelled\",\n  \"bom_id\": 12,\n  \"warehouse_id\": 3,\n  \"quantity_planned\": \"10.000000\",\n  \"quantity_produced\": \"0.000000\",\n  \"scheduled_start\": \"2026-06-01T00:00:00.000000Z\",\n  \"scheduled_end\": \"2026-06-03T00:00:00.000000Z\",\n  \"started_at\": null,\n  \"completed_at\": null,\n  \"closed_at\": \"2026-05-28T14:32:11.000000Z\",\n  \"notes\": null,\n  \"created_at\": \"2026-05-25T09:00:00.000000Z\",\n  \"updated_at\": \"2026-05-28T14:32:11.000000Z\"\n}"}]},{"name":"Close Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/close","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","close"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Completed -> Closed. Locks the MO from further changes.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"notes\": \"Costing locked\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Reopen Manufacturing Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/reopen","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","reopen"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Closed -> Partially Completed (or Completed if completed_quantity >= planned_quantity). Required reason (string, max 2000) is captured in the Reopened event payload.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Correcting component consumption\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Generate Accounting Transaction (MO)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","generate-accounting-transaction"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Generate (or rebuild) the WIP-routed GL journals for this MO — ONE journal per production iteration, each dated to that iteration's production date (so multi-day / multi-period production is period-accurate). Conversion costs (labor + overhead + outsourced service) are capitalized into finished goods through Work In Process:\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n- Dr Work In Process (total)\n- Cr Raw Materials Inventory (materials), Cr Direct Labor Applied (labor), Cr Manufacturing Overhead Applied (overhead), Cr Accrued Purchases (outsourced service fee)\n- Dr Finished Goods Inventory (total), Cr Work In Process (total)\n\nWIP nets to zero. Each journal links polymorphically to the MO and is tagged with its mo_production_iteration_id. Requires the Work In Process / Direct Labor Applied / Manufacturing Overhead Applied nominal codes to be mapped (Settings -> Nominal Code Mappings). No request body. Returns an ARRAY of accounting transaction object (one per iteration) with their journal lines. Each iteration's journal is also posted automatically as production is recorded (when accounting is enabled), and removed if the iteration is reversed."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","generate-accounting-transaction"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Production journals generated successfully.\",\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"display_status\": {\n        \"label\": \"Synced\",\n        \"color\": \"success\"\n      },\n      \"total\": 37,\n      \"reference\": \"Production MO-000001 #1: QA-COFFEE-250\",\n      \"transaction_date\": \"2026-06-05T00:00:00+00:00\",\n      \"type\": \"manufacturing_order\"\n    }\n  ]\n}"}]},{"name":"MO Events (Audit Log)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/events","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","events"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns audit log of every status transition and significant action on the MO.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List MO Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated list of inventory movements created by this Manufacturing Order. Includes movements linked to the MO itself, to any of its component lines (consumption + scrap) and to any of its output lines (production output).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `per_page` — items per page (default: 15)\n- `filter[search]` — search by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4012,\n      \"type\": \"production_output\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": 10,\n      \"reference\": \"MO-000014\",\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 88,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"product_id\": 412,\n      \"product_sku\": \"KIT-A\",\n      \"product_name\": \"Widget Kit\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 7.25,\n      \"layer\": {\n        \"fifo_layer_id\": 19,\n        \"name\": null\n      },\n      \"fifo_layer_id\": 19,\n      \"inventory_movement_date\": \"2026-04-15T09:30:00.000000Z\",\n      \"created_at\": \"2026-04-15T09:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List MO FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated list of FIFO layers CREATED by this Manufacturing Order (production output layers). Layers consumed by this MO are surfaced on each layer's own detail view.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `per_page` — items per page (default: 15)\n- `filter[search]` — search by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 19,\n      \"product_id\": 412,\n      \"warehouse_id\": 1,\n      \"batch_number\": \"LOT-2026-04-001\",\n      \"manufacture_date\": \"2026-04-15\",\n      \"expiry_date\": \"2027-04-15\",\n      \"original_quantity\": 50,\n      \"fulfilled_quantity\": 12,\n      \"quantity_on_hand\": 38,\n      \"available_quantity\": 38,\n      \"avg_cost\": 7.25,\n      \"total_cost\": 362.5,\n      \"fifo_layer_date\": \"2026-04-15T00:00:00.000000Z\",\n      \"created_at\": \"2026-04-15T09:30:00.000000Z\",\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 88\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Manufacturing Order Output Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Show a single Manufacturing Output line — the canonical detail view used by the standalone Manufacturing Output page.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the output-line resource plus three derived blocks:\n- `fifo_layer` — the FIFO layer this output created (one per output, max)\n- `inventory_movement` — the single production-output movement created when the line posted\n- `layer_movements` — every movement that touched the FIFO layer this output produced: the production movement itself plus any downstream consumption (sales, transfers, further manufacturing). Drives the Movements tab.\n- `production_date` — top-level canonical date (movement's `inventory_movement_date` when available, else MO `completed_at`)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"manufacturing_order_id\": 14,\n    \"bom_output_line_id\": 42,\n    \"product_id\": 412,\n    \"role\": \"primary\",\n    \"expected_quantity\": 10,\n    \"actual_produced_quantity\": 10,\n    \"allocated_cost\": 72.5,\n    \"batch_number\": \"LOT-2026-04-001\",\n    \"expiry_date\": \"2027-04-15\",\n    \"manufacturing_order\": {\n      \"id\": 14,\n      \"mo_number\": \"MO-000014\",\n      \"status\": \"completed\"\n    },\n    \"product\": {\n      \"id\": 412,\n      \"sku\": \"KIT-A\",\n      \"name\": \"Widget Kit\"\n    },\n    \"unit_of_measure\": {\n      \"id\": 1,\n      \"code\": \"EA\",\n      \"name\": \"Each\"\n    },\n    \"fifo_layer\": {\n      \"id\": 19,\n      \"original_quantity\": 50,\n      \"available_quantity\": 38,\n      \"fulfilled_quantity\": 12,\n      \"avg_cost\": 7.25,\n      \"total_cost\": 362.5,\n      \"fifo_layer_date\": \"2026-04-15T00:00:00.000000Z\",\n      \"created_at\": \"2026-04-15T09:30:00.000000Z\"\n    },\n    \"inventory_movement\": {\n      \"id\": 4012,\n      \"type\": \"production_output\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": 10,\n      \"inventory_movement_date\": \"2026-04-15T09:30:00.000000Z\",\n      \"created_at\": \"2026-04-15T09:30:00.000000Z\"\n    },\n    \"production_date\": \"2026-04-15T09:30:00.000000Z\"\n  }\n}"}]},{"name":"Get Manufacturing Order Component Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-component-lines/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-component-lines",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Show a single Manufacturing Consumption (component) line — the detail view used by the standalone Manufacturing Consumption page.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the component-line resource plus:\n- `inventory_movements` — every movement attached to this consumption line (one consumption row per FIFO layer drawn, plus optionally one scrap row)\n- `layers_drawn` — denormalised summary of the FIFO layers consumed (with quantity taken, unit cost, layer date)\n- `consumption_date` — top-level canonical date (component `consumption_posted_at`, falling back to first movement date or MO `completed_at`)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-component-lines/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-component-lines",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 211,\n    \"manufacturing_order_id\": 14,\n    \"bom_component_line_id\": 305,\n    \"product_id\": 305,\n    \"expected_quantity\": 22,\n    \"expected_scrap_quantity\": 2,\n    \"actual_consumed_quantity\": 22,\n    \"actual_scrap_quantity\": 2,\n    \"scrap_reason_code\": null,\n    \"is_optional\": false,\n    \"consumption_method\": \"backflush\",\n    \"consumption_posted_at\": \"2026-04-15T09:30:00.000000Z\",\n    \"estimated_cost\": 100,\n    \"manufacturing_order\": {\n      \"id\": 14,\n      \"mo_number\": \"MO-000014\",\n      \"status\": \"completed\"\n    },\n    \"product\": {\n      \"id\": 305,\n      \"sku\": \"WIDGET-A\",\n      \"name\": \"Widget Component A\"\n    },\n    \"unit_of_measure\": {\n      \"id\": 1,\n      \"code\": \"EA\",\n      \"name\": \"Each\"\n    },\n    \"consumption_date\": \"2026-04-15T09:30:00.000000Z\",\n    \"inventory_movements\": [\n      {\n        \"id\": 4010,\n        \"type\": \"manufacturing_consumption\",\n        \"inventory_status\": \"on_hand\",\n        \"quantity\": -20,\n        \"fifo_layer_id\": 14,\n        \"unit_cost\": 3,\n        \"inventory_movement_date\": \"2026-04-15T09:30:00.000000Z\"\n      },\n      {\n        \"id\": 4011,\n        \"type\": \"manufacturing_scrap\",\n        \"inventory_status\": \"on_hand\",\n        \"quantity\": -2,\n        \"fifo_layer_id\": 14,\n        \"unit_cost\": 3,\n        \"inventory_movement_date\": \"2026-04-15T09:30:00.000000Z\"\n      }\n    ],\n    \"layers_drawn\": [\n      {\n        \"fifo_layer_id\": 14,\n        \"quantity_taken\": 20,\n        \"unit_cost\": 3,\n        \"fifo_layer_date\": \"2026-03-01T00:00:00.000000Z\",\n        \"movement_id\": 4010,\n        \"movement_type\": \"manufacturing_consumption\"\n      },\n      {\n        \"fifo_layer_id\": 14,\n        \"quantity_taken\": 2,\n        \"unit_cost\": 3,\n        \"fifo_layer_date\": \"2026-03-01T00:00:00.000000Z\",\n        \"movement_id\": 4011,\n        \"movement_type\": \"manufacturing_scrap\"\n      }\n    ]\n  }\n}"}]},{"name":"List Output Line Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated inventory movements scoped to a single MO output line — every movement that touches the FIFO layer this output produced. Includes the production-output movement itself and any downstream consumption of the batch (sales, transfers, further manufacturing). Backs the Movements tab on the Manufacturing Output detail page.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `per_page` — items per page (default: 15)\n- `filter[search]` — search by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8,\n      \"type\": \"manufacturing_output\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": 10,\n      \"reference\": null,\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 1,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"product_id\": 4,\n      \"product_sku\": \"QA-COFFEE-250\",\n      \"product_name\": \"Coffee 250g Pouch\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 3.58,\n      \"layer\": {\n        \"fifo_layer_id\": 5,\n        \"name\": null\n      },\n      \"fifo_layer_id\": 5,\n      \"inventory_movement_date\": \"2026-06-02T20:36:22.000000Z\",\n      \"created_at\": \"2026-06-02T20:36:22.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Output Line FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated FIFO layers scoped to a single MO output line. Always returns at most one row — the layer this output produced — but shapes the response as a paginated collection so the frontend can reuse the same list view contract as the MO-scoped equivalent.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `per_page` — items per page (default: 15)\n- `filter[search]` — search by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-output-lines/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-output-lines",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"product_id\": 4,\n      \"warehouse_id\": 1,\n      \"batch_number\": \"MO-000001-2026-06-02\",\n      \"manufacture_date\": \"2026-06-02\",\n      \"expiry_date\": null,\n      \"original_quantity\": 10,\n      \"fulfilled_quantity\": 0,\n      \"available_quantity\": 10,\n      \"avg_cost\": 3.58,\n      \"total_cost\": 35.81,\n      \"fifo_layer_date\": \"2026-06-02T00:00:00.000000Z\",\n      \"created_at\": \"2026-06-02T20:36:22.000000Z\",\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 1\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List MO Production Iterations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated list of production iterations for this Manufacturing Order. Each iteration is one call to Record Production; includes restore-cost information and a reversibility flag.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `per_page` — items per page (default: 15)\n- `sort` — sort field. Prefix with `-` for DESC. Allowed: id, iteration_number, production_date, output_quantity, total_input_cost, created_at. Default: `-iteration_number`\n- `filter[is_reversed]` — true/false\n- `filter[iteration_number]` — exact match\n- `filter[search]` — LIKE on iteration_number / reverse_reason\n- `filter[date_from]`, `filter[date_to]` — production_date range (Y-m-d)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"0fa1c2bb-8b1b-4c5a-9d63-1f4b5e6d7c80\",\n      \"manufacturing_order_id\": 1,\n      \"iteration_number\": 1,\n      \"created_by\": {\n        \"id\": 1,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"production_date\": \"2026-06-02T20:36:22.000000Z\",\n      \"output_quantity\": 10,\n      \"total_input_cost\": 35.81,\n      \"total_allocated_cost\": 35.81,\n      \"is_reversed\": false,\n      \"reversed_at\": null,\n      \"reversed_by\": null,\n      \"reverse_reason\": null,\n      \"reversible\": true,\n      \"non_reversible_reason\": null,\n      \"movement_count\": 5,\n      \"output_fifo_layer_id\": 5,\n      \"created_at\": \"2026-06-02T20:36:22.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Production Iteration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single production iteration with all relations eagerly loaded (manufacturing order, created_by user, reversed_by user) plus the output FIFO layer expanded. Backs the standalone Production Iteration detail page.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `moProductionIteration` (string, UUID) — the iteration's UUID primary key. Iteration IDs are globally unique so no MO scope is required.\n\n**Notes:**\n- `reversible` / `non_reversible_reason` reflect whether the iteration can still be reversed (e.g. blocked by downstream consumption of its output layer).\n- `output_fifo_layer` is the single FIFO layer this iteration produced (nullable for outsourced or partial iterations)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"0fa1c2bb-8b1b-4c5a-9d63-1f4b5e6d7c80\",\n    \"manufacturing_order_id\": 1,\n    \"manufacturing_order\": {\n      \"id\": 1,\n      \"mo_number\": \"MO-000001\",\n      \"status\": \"in_progress\"\n    },\n    \"iteration_number\": 1,\n    \"created_by\": {\n      \"id\": 1,\n      \"name\": \"Administrator\"\n    },\n    \"production_date\": \"2026-06-03T04:32:22.000000Z\",\n    \"output_quantity\": 10,\n    \"total_input_cost\": 35.81,\n    \"total_allocated_cost\": 35.81,\n    \"is_reversed\": false,\n    \"reversed_at\": null,\n    \"reversed_by\": null,\n    \"reverse_reason\": null,\n    \"reversible\": true,\n    \"non_reversible_reason\": null,\n    \"movement_count\": 4,\n    \"output_fifo_layer_id\": 5,\n    \"output_fifo_layer\": {\n      \"id\": 5,\n      \"original_quantity\": 10,\n      \"available_quantity\": 10,\n      \"fulfilled_quantity\": 0,\n      \"avg_cost\": 3.581,\n      \"total_cost\": 35.81,\n      \"fifo_layer_date\": \"2026-06-03T04:32:22.000000Z\",\n      \"created_at\": \"2026-06-03T04:32:22.000000Z\"\n    },\n    \"created_at\": \"2026-06-03T04:32:22.000000Z\"\n  }\n}"}]},{"name":"List Production Iteration Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated inventory movements scoped to a single production iteration — every movement created by the underlying Record Production call (component consumption, scrap, and output). Scope is `inventory_movements.production_iteration_id = {iteration.id}`. Backs the Movements tab on the Production Iteration detail page.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `moProductionIteration` (string, UUID) — the iteration's UUID primary key.\n\n**Query parameters (Spatie QueryBuilder):**\n- `per_page` — items per page (default: 15)\n- `sort` — sort field. Prefix with `-` for DESC. Allowed: `id`, `inventory_movement_date`, `type`, `inventory_status`, `quantity`, `reference`, `created_at`. Default: `-id`\n- `filter[type]` — exact match (e.g. `manufacturing_consumption`, `manufacturing_output`, `manufacturing_scrap`)\n- `filter[inventory_status]` — exact match (e.g. `on_hand`, `scrapped`)\n- `filter[link_type]` — exact FQN model class (e.g. `App\\Models\\MoOutputLine`, `App\\Models\\MoComponentLine`)\n- `filter[warehouse_id]` — exact match\n- `filter[fifo_layer_id]` — exact match\n- `filter[search]` — LIKE on product SKU or product name\n- `filter[inventory_movement_date_from]`, `filter[inventory_movement_date_to]` — date range (Y-m-d)\n- `filter[created_at_from]`, `filter[created_at_to]` — date range (Y-m-d)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}/inventory-movements","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id","inventory-movements"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8,\n      \"type\": \"manufacturing_output\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": 10,\n      \"reference\": null,\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 1,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"product_id\": 4,\n      \"product_sku\": \"QA-COFFEE-250\",\n      \"product_name\": \"Coffee 250g Pouch\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 3.581,\n      \"layer\": {\n        \"fifo_layer_id\": 5,\n        \"name\": null\n      },\n      \"fifo_layer_id\": 5,\n      \"inventory_movement_date\": \"2026-06-03T04:32:22.000000Z\",\n      \"created_at\": \"2026-06-03T04:32:22.000000Z\"\n    },\n    {\n      \"id\": 7,\n      \"type\": \"manufacturing_consumption\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": -25,\n      \"reference\": null,\n      \"link_type\": \"App\\\\Models\\\\MoComponentLine\",\n      \"link_id\": 3,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"product_id\": 7,\n      \"product_sku\": \"QA-BEAN-1KG\",\n      \"product_name\": \"Raw Coffee Bean 1kg\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 1.2,\n      \"layer\": {\n        \"fifo_layer_id\": 2,\n        \"name\": null\n      },\n      \"fifo_layer_id\": 2,\n      \"inventory_movement_date\": \"2026-06-03T04:32:22.000000Z\",\n      \"created_at\": \"2026-06-03T04:32:22.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 4,\n  \"from\": 1,\n  \"to\": 4\n}"}]},{"name":"List Production Iteration FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated FIFO layers scoped to a single production iteration — every layer (output + any auxiliary) created by the underlying Record Production call. Scope is `fifo_layers.production_iteration_id = {iteration.id}`. Mirrors the MO-output-line FIFO-layers endpoint so the frontend list view can reuse the same contract.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `moProductionIteration` (string, UUID) — the iteration's UUID primary key.\n\n**Query parameters (Spatie QueryBuilder):**\n- `per_page` — items per page (default: 15)\n- `sort` — sort field. Prefix with `-` for DESC. Allowed: `id`, `fifo_layer_date`, `original_quantity`, `fulfilled_quantity`, `avg_cost`, `total_cost`, `created_at`. Default: `-created_at`\n- `filter[warehouse_id]` — exact match\n- `filter[product_id]` — exact match\n- `filter[search]` — LIKE on product SKU or product name\n- `filter[fifo_layer_date_from]`, `filter[fifo_layer_date_to]` — date range (Y-m-d)\n- `filter[avg_cost_min]`, `filter[avg_cost_max]` — avg_cost range"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/production-iterations/{id}/fifo-layers","host":["{{baseUrl}}"],"path":["api","manufacturing","production-iterations",":id","fifo-layers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"product_id\": 4,\n      \"warehouse_id\": 1,\n      \"batch_number\": \"MO-000001-2026-06-03\",\n      \"manufacture_date\": \"2026-06-03\",\n      \"expiry_date\": null,\n      \"original_quantity\": 10,\n      \"available_quantity\": 10,\n      \"fulfilled_quantity\": 0,\n      \"avg_cost\": 3.581,\n      \"total_cost\": 35.81,\n      \"fifo_layer_date\": \"2026-06-03T04:32:22.000000Z\",\n      \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n      \"link_id\": 1,\n      \"created_at\": \"2026-06-03T04:32:22.000000Z\",\n      \"updated_at\": \"2026-06-03T04:32:22.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Reverse Production Iteration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations/{id2}/reverse","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations",":id2","reverse"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Reverses a production iteration: restores input FIFO layers, deletes the output layer (if not yet drawn from), rolls back actuals on the component/output lines, decrements `completed_quantity` on the MO, and writes a `production_reversed` audit event. Refuses with 422 if already reversed, mismatched MO, or downstream-drawn.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n- `reason` (string, optional, max 1000) — free-text reason for the reversal\n\n**Failure modes (422 JSON with discriminator `code`):**\n- `iteration_already_reversed`\n- `downstream_draw_blocks_reverse` — carries `details.layer_id`, `details.fulfilled_quantity`, `details.original_quantity`\n- `iteration_belongs_to_other_mo`\n\n**Success:** 200 with the refreshed manufacturing order object.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Quality control rejected this batch\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations/{id2}/reverse","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations",":id2","reverse"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"mo_number\": \"MO-000001\",\n  \"status\": \"in_progress\",\n  \"bom_id\": 5,\n  \"planned_quantity\": 100,\n  \"completed_quantity\": 0,\n  \"production_method\": \"in_house\",\n  \"started_at\": \"2026-06-02T20:30:00.000000Z\",\n  \"completed_at\": null,\n  \"cost_breakdown\": null,\n  \"created_at\": \"2026-06-02T20:00:00.000000Z\",\n  \"updated_at\": \"2026-06-02T20:38:00.000000Z\"\n}"}]},{"name":"Get MO Cost Allocation Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/cost-allocation-breakdown","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","cost-allocation-breakdown"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]},"description":"Get the cumulative cost-allocation breakdown across all posted production for this manufacturing order: the allocation method in use, each output's basis value, share percent, allocated cost, and unit cost, plus byproduct valuations. Always returns a usable shape - has_production is false when no production has been recorded yet.\nAuth: requires Bearer token.\nPath param: manufacturingOrder = manufacturing order id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/cost-allocation-breakdown","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","cost-allocation-breakdown"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"method\": \"by_weight\",\n    \"method_label\": \"By Weight\",\n    \"method_formula\": \"share = (producedQty × product.weight) ÷ Σ\",\n    \"basis_label\": \"Weight\",\n    \"basis_hint\": \"Product weight\",\n    \"has_production\": true,\n    \"total_input_cost\": 1250,\n    \"byproduct_value\": 50,\n    \"remaining_pool\": 1200,\n    \"allocatable_outputs\": [\n      {\n        \"output_line_id\": 88,\n        \"product_id\": 1,\n        \"product_sku\": \"KIT-A\",\n        \"product_name\": \"Widget Kit A\",\n        \"role\": \"primary\",\n        \"produced_quantity\": 100,\n        \"basis_value\": 0.5,\n        \"weight\": 50,\n        \"allocated_cost\": 1200,\n        \"unit_cost\": 12,\n        \"missing_basis\": false,\n        \"share_percent\": 100\n      }\n    ],\n    \"byproducts\": [\n      {\n        \"output_line_id\": 89,\n        \"product_id\": 9,\n        \"product_sku\": \"SCRAP-01\",\n        \"product_name\": \"Offcut Material\",\n        \"role\": \"byproduct\",\n        \"produced_quantity\": 5,\n        \"valuation_method\": \"fixed_value\",\n        \"valuation_amount\": 10,\n        \"allocated_cost\": 50,\n        \"unit_cost\": 10\n      }\n    ]\n  }\n}"}]},{"name":"Download Work Order PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/print","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","print"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]},"description":"Download a printable work order PDF for the manufacturing order (returned inline with Content-Type application/pdf). For Draft orders that have not been confirmed yet, component and output rows fall back to the BOM definition.\nAuth: requires Bearer token.\nPath param: manufacturingOrder = manufacturing order id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/print","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","print"],"variable":[{"key":"manufacturingOrder","value":"1","description":"The manufacturing order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Preview Reverse Production Iteration Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations/{id2}/reverse-impact","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations",":id2","reverse-impact"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]},"description":"Read-only preview of the allocation-demotion impact of reversing this production iteration. Because reversing it removes the stock it added, this behaves like a manual negative adjustment and returns one row per affected product: how much of the removed quantity is unallocated vs soft-allocated vs hard-allocated, plus every sales-order allocation and fulfillment (printed shipping label) the removal would disturb. Use it to decide which fulfillments to authorize voiding via `void_confirmations` on the reversing call. Nothing is mutated. A removal that only re-adds stock returns an empty `data` array.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/production-iterations/{id2}/reverse-impact","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","production-iterations",":id2","reverse-impact"],"variable":[{"key":"id","value":"","description":"The id identifier"},{"key":"id2","value":"","description":"The id2 identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 5567,\n      \"product_sku\": \"WIDGET-BLUE\",\n      \"product_name\": \"Blue Widget\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 10,\n      \"soft_allocated_quantity\": 6,\n      \"hard_allocated_quantity\": 4,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88201,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 3120,\n          \"order_number\": \"SO-3120\",\n          \"customer_name\": \"Acme Co.\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 6\n        },\n        {\n          \"allocation_id\": 88205,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 3125,\n          \"order_number\": \"SO-3125\",\n          \"customer_name\": \"Beta LLC\",\n          \"fulfillment_id\": 90142,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 4,\n          \"allocation_ids\": [\n            88205\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Preview Record Production Release Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/record-production/preview-release-impact","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","record-production","preview-release-impact"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Read-only preview of which back-ordered sales orders the proposed produced quantities would release finished-good stock to, returned one row per output product. Nothing is mutated — post the outputs you intend to record and get the release picture before committing.\n\n**Request body:**\n- `outputs` (array, optional) — the produced outputs to evaluate.\n- `outputs[].mo_output_line_id` (integer, required) — the output line being produced.\n- `outputs[].actual_produced_quantity` (number, required, min 0) — the quantity that would be produced.\n\n**Response (`data[]`, one row per output product):**\n- `releasable_quantity` — units of the newly produced stock that can be released to back-ordered demand.\n- `orders[]` — the back-ordered sales orders that would be filled (`sales_order_id`, `order_number`, `customer_name`, `quantity`).\n- `held_back[]` — demand that stays back-ordered, each with `reason_kept` explaining why (e.g. \"Insufficient supply\").\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"outputs\": [\n    {\n      \"mo_output_line_id\": 1,\n      \"actual_produced_quantity\": 100\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/record-production/preview-release-impact","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","record-production","preview-release-impact"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"releasable_quantity\": 8,\n      \"orders\": [\n        {\n          \"sales_order_id\": 4602,\n          \"order_number\": \"SO-10501\",\n          \"customer_name\": \"Acme Retail\",\n          \"quantity\": 5\n        },\n        {\n          \"sales_order_id\": 4610,\n          \"order_number\": \"SO-10509\",\n          \"customer_name\": \"Gamma Foods\",\n          \"quantity\": 3\n        }\n      ],\n      \"held_back\": [\n        {\n          \"allocation_id\": 90311,\n          \"product_id\": 123,\n          \"sales_order_id\": 4620,\n          \"sales_order_line_id\": 55123,\n          \"sales_order_number\": \"SO-10518\",\n          \"customer_name\": \"Delta Mart\",\n          \"quantity\": 4,\n          \"from_status\": \"planned\",\n          \"to_status\": \"allocated\",\n          \"reason_kept\": \"Insufficient supply\"\n        }\n      ]\n    }\n  ]\n}"}]}]},{"name":"MO Operations","item":[{"name":"Create Manual MO Operation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/operations","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","operations"],"variable":[{"key":"manufacturingOrder","value":"1","description":"Manufacturing order ID"}]},"description":"Create a manual operation against a specific MO. The new row is stamped source='manual' with bom_operation_id=null.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `sequence` (required, integer, min 0) — ordering on the MO; can interleave with from_bom rows\n- `name` (required, string, max 255)\n- `type` (required, enum) — one of: process, setup, per_unit, fixed_cost. Stored on the row as operation_type.\n- `work_center_id` (optional, integer, exists:work_centers,id)\n- `default_operator_id` (optional, integer, exists:users,id) — planned operator (distinct from operator_id which is set when the timer starts)\n- `expected_duration_minutes` (optional, integer, min 0)\n- `hourly_rate` (optional, numeric, min 0)\n- `fixed_cost` (optional, numeric, min 0) — flat per-run cost added on top of labour for any operation type (or the entire cost of a fixed_cost operation). Capitalized onto finished goods like labour, but never marked up by work-center overhead.\n- `notes` (optional, string, max 1000)\n\n**Refused** with 422 {code:'mo_locked'} when MO status is completed | closed | cancelled.\n\n`cost_classification` (optional, `labor`|`overhead`, default `labor`) sets the expense classification independently of the rate basis: `labor` posts the operation's variable cost to the Labor bucket (marked up by the work center's overhead %); `overhead` posts machine/tooling-style cost to the Overhead bucket with no additional markup.","body":{"mode":"raw","raw":"{\n  \"sequence\": 40,\n  \"name\": \"Final QA Check\",\n  \"type\": \"process\",\n  \"work_center_id\": 3,\n  \"default_operator_id\": 7,\n  \"expected_duration_minutes\": 15,\n  \"hourly_rate\": 35,\n  \"fixed_cost\": 0,\n  \"cost_classification\": \"labor\",\n  \"notes\": \"Added for this MO only — not on the BOM.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/operations","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","operations"],"variable":[{"key":"manufacturingOrder","value":"1","description":"Manufacturing order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 412,\n    \"manufacturing_order_id\": 14,\n    \"source\": \"manual\",\n    \"bom_operation_id\": null,\n    \"sequence\": 40,\n    \"name\": \"Final QA Check\",\n    \"type\": \"process\",\n    \"operation_type\": \"process\",\n    \"expected_duration_minutes\": 15,\n    \"hourly_rate\": 35,\n    \"status\": \"pending\",\n    \"scheduled_start\": null,\n    \"started_at\": null,\n    \"completed_at\": null,\n    \"actual_time_minutes\": null,\n    \"operator_id\": null,\n    \"default_operator_id\": 7,\n    \"default_operator\": {\n      \"id\": 7,\n      \"name\": \"Sam Cooper\"\n    },\n    \"work_center_id\": 3,\n    \"work_center\": {\n      \"id\": 3,\n      \"name\": \"QA Bench\"\n    },\n    \"fixed_cost\": 0,\n    \"cost_classification\": \"labor\",\n    \"actual_cost\": null,\n    \"cost_source\": \"none\",\n    \"notes\": \"Added for this MO only — not on the BOM.\",\n    \"bom_operation\": null,\n    \"is_modified_from_bom\": false\n  }\n}"}]},{"name":"Update MO Operation","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]},"description":"Update an MO operation. Allowed on both source='manual' AND source='from_bom' rows — edits to from_bom rows do NOT propagate back to the BOM master.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAll body fields are 'sometimes' (omit to leave unchanged):\n- `sequence` (integer, min 0)\n- `name` (string, max 255)\n- `type` (enum: process, setup, per_unit, fixed_cost) — maps to operation_type column\n- `work_center_id` (integer, exists:work_centers,id, nullable)\n- `default_operator_id` (integer, exists:users,id, nullable)\n- `expected_duration_minutes` (integer, min 0, nullable)\n- `hourly_rate` (numeric, min 0, nullable)\n- `fixed_cost` (numeric, min 0, nullable) — flat per-run cost added additively to labour. Changing it re-derives actual_cost as (time × rate) + fixed_cost.\n- `notes` (string, max 1000, nullable)\n\nWhen the row is source='from_bom' and any of {sequence, name, operation_type, work_center_id, default_operator_id, expected_duration_minutes, hourly_rate, fixed_cost} now differs from the linked BOM operation, the response field `is_modified_from_bom` flips to true.\n\n**Refused** with 422 {code:'mo_locked'} when MO status is completed | closed | cancelled.\n\nThe response also carries a `cost_source` field: 'none' (no actual_cost yet), 'actual' (cost backed by logged time, or a fixed_cost operation), 'estimated' (cost fell back to planned duration because no timer was logged), or 'manual' (an explicitly supplied `actual_cost`). Sending `actual_cost` in the body stamps cost_source='manual' and locks the cost against automatic re-derivation — rate, fixed-cost, or type edits no longer recompute it; only another explicit `actual_cost` (null clears both cost and source), or an explicitly logged positive time, replaces it.\n\n`cost_classification` (optional, `labor`|`overhead`, default `labor`) sets the expense classification independently of the rate basis: `labor` posts the operation's variable cost to the Labor bucket (marked up by the work center's overhead %); `overhead` posts machine/tooling-style cost to the Overhead bucket with no additional markup.","body":{"mode":"raw","raw":"{\n  \"sequence\": 25,\n  \"name\": \"Mix (revised)\",\n  \"work_center_id\": 2,\n  \"expected_duration_minutes\": 45,\n  \"hourly_rate\": 55,\n  \"fixed_cost\": 5,\n  \"cost_classification\": \"labor\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"manufacturing_order_id\": 14,\n    \"source\": \"from_bom\",\n    \"bom_operation_id\": 12,\n    \"sequence\": 25,\n    \"name\": \"Mix (revised)\",\n    \"type\": \"setup\",\n    \"operation_type\": \"setup\",\n    \"expected_duration_minutes\": 45,\n    \"hourly_rate\": 55,\n    \"status\": \"pending\",\n    \"scheduled_start\": null,\n    \"started_at\": null,\n    \"completed_at\": null,\n    \"actual_time_minutes\": null,\n    \"operator_id\": null,\n    \"default_operator_id\": null,\n    \"work_center_id\": 2,\n    \"work_center\": {\n      \"id\": 2,\n      \"name\": \"Mixing Station\"\n    },\n    \"fixed_cost\": 5,\n    \"cost_classification\": \"labor\",\n    \"actual_cost\": null,\n    \"cost_source\": \"none\",\n    \"notes\": null,\n    \"bom_operation\": {\n      \"id\": 12,\n      \"bom_id\": 2,\n      \"sequence\": 10,\n      \"name\": \"Mix\",\n      \"work_center_id\": 1,\n      \"operation_type\": \"setup\",\n      \"time_minutes\": 30,\n      \"cost_per_hour\": 45,\n      \"fixed_cost\": null,\n      \"cost_classification\": \"labor\",\n      \"instructions\": null\n    },\n    \"is_modified_from_bom\": true\n  }\n}"}]},{"name":"Delete MO Operation","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]},"description":"Delete an MO operation. Allowed on both source='manual' AND source='from_bom' rows — industry pattern lets an operator drop an inherited step on a one-off MO. The linked BOM operation is untouched.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Refused** with 422 {code:'mo_locked'} when MO status is completed | closed | cancelled."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Start Operation Timer","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}/start","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation","start"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]},"description":"Start the per-operation timer (shop-floor use). Stamps started_at=now() and sets operator_id to the authenticated user. Rejects with 422 if the operation is already done.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns **422** with `code = mo_locked` when the parent manufacturing order is Completed, Closed, or Cancelled — operations on a terminal order are immutable."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}/start","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation","start"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"manufacturing_order_id\": 14,\n    \"source\": \"from_bom\",\n    \"bom_operation_id\": 12,\n    \"sequence\": 25,\n    \"name\": \"Mix\",\n    \"type\": \"process\",\n    \"operation_type\": \"process\",\n    \"expected_duration_minutes\": 30,\n    \"hourly_rate\": 55,\n    \"status\": \"in_progress\",\n    \"scheduled_start\": null,\n    \"started_at\": \"2026-07-15T09:12:00.000000Z\",\n    \"completed_at\": null,\n    \"actual_time_minutes\": null,\n    \"operator_id\": 7,\n    \"operator\": {\n      \"id\": 7,\n      \"name\": \"Sam Cooper\"\n    },\n    \"default_operator_id\": null,\n    \"work_center_id\": 2,\n    \"work_center\": {\n      \"id\": 2,\n      \"name\": \"Mixing Station\"\n    },\n    \"fixed_cost\": 5,\n    \"actual_cost\": null,\n    \"cost_source\": \"none\",\n    \"notes\": null,\n    \"bom_operation\": null,\n    \"is_modified_from_bom\": false\n  }\n}"}]},{"name":"Complete Operation Timer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}/complete","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation","complete"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]},"description":"Stop the timer and mark the operation done. When `actual_time_minutes` is omitted it's computed from the started_at timestamp.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `actual_time_minutes` (optional, numeric, min 0)\n- `notes` (optional, string, max 2000)\n\nWhen `actual_time_minutes` is omitted or 0, the labour cost falls back to the operation's planned `expected_duration_minutes` so a bare mark-done still costs out. The response's `cost_source` then reads 'estimated' (vs 'actual' when a timer was logged, or for a fixed_cost operation). If the operation carries a manually-set cost (cost_source='manual'), a bare mark-done without a positive `actual_time_minutes` keeps that cost and source untouched; logging a positive time re-derives the cost and replaces the manual value.\n\nReturns **422** with `code = mo_locked` when the parent manufacturing order is Completed, Closed, or Cancelled — operations on a terminal order are immutable.","body":{"mode":"raw","raw":"{\n  \"actual_time_minutes\": 35,\n  \"notes\": \"Ran a bit over.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mo-operations/{moOperation}/complete","host":["{{baseUrl}}"],"path":["api","manufacturing","mo-operations",":moOperation","complete"],"variable":[{"key":"moOperation","value":"1","description":"MO operation ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"manufacturing_order_id\": 14,\n    \"source\": \"from_bom\",\n    \"bom_operation_id\": 12,\n    \"sequence\": 25,\n    \"name\": \"Mix\",\n    \"type\": \"process\",\n    \"operation_type\": \"process\",\n    \"expected_duration_minutes\": 30,\n    \"hourly_rate\": 55,\n    \"status\": \"done\",\n    \"scheduled_start\": null,\n    \"started_at\": \"2026-07-15T09:12:00.000000Z\",\n    \"completed_at\": \"2026-07-15T09:47:00.000000Z\",\n    \"actual_time_minutes\": 35,\n    \"operator_id\": 7,\n    \"operator\": {\n      \"id\": 7,\n      \"name\": \"Sam Cooper\"\n    },\n    \"default_operator_id\": null,\n    \"work_center_id\": 2,\n    \"work_center\": {\n      \"id\": 2,\n      \"name\": \"Mixing Station\"\n    },\n    \"fixed_cost\": 5,\n    \"actual_cost\": 37.08,\n    \"cost_source\": \"actual\",\n    \"notes\": \"Ran a bit over.\",\n    \"bom_operation\": null,\n    \"is_modified_from_bom\": false\n  }\n}"}]}]},{"name":"Outsourced Production","item":[{"name":"Outsource MO","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/outsource","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","outsource"],"variable":[{"key":"manufacturingOrder","value":"","description":"The manufacturingOrder identifier"}]},"description":"Switches an existing draft or confirmed Manufacturing Order to outsourced production.\n\nPersists `production_method=outsourced`, the contractor supplier, scheduling dates, and notes on the MO row. Writes a `production_method_changed` event with the full payload (including contractor warehouse and service fee).\n\n**Request body fields:**\n- `contractor_supplier_id` (int, required) — Supplier id with `is_manufacturing_contractor=true`. Must exist in `suppliers`.\n- `contractor_warehouse_id` (int, nullable) — Warehouse the contractor will receive components into. Must exist in `warehouses`.\n- `outsourced_purchase_order_id` (int, nullable) — Optional existing PO to link. Must exist in `purchase_orders`. If omitted, an Open outsourced PO is auto-created against the contractor and linked.\n- `scheduled_start` (datetime, nullable) — `Y-m-d H:i:s`. Persisted to `manufacturing_orders.scheduled_start`.\n- `scheduled_end` (datetime, nullable, must be >= scheduled_start) — Persisted to `manufacturing_orders.scheduled_end`.\n- `service_fee_amount` (decimal, nullable, min:0) — Recorded as a cost FinancialLine on the backing PO; flows into the MO cost_breakdown.service_fee when production is received.\n- `notes` (string, nullable, max:5000) — Persisted to `manufacturing_orders.notes`.\n\n**Rejected (500)** if the MO status is not `draft` or `confirmed`.\n**Rejected (422)** if `contractor_supplier_id` is missing or any FK does not exist.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Validation:** the supplier must be flagged as a manufacturing contractor; `contractor_warehouse_id` must be that contractor's own warehouse (when supplied, a Draft order's source warehouse is re-pointed to it; a Confirmed order releases its component reservations and re-reserves at the new warehouse); `outsourced_purchase_order_id` must reference an outsourced-manufacturing purchase order that is unlinked or already linked to this order. Omitting `service_fee_amount` preserves the existing fee on a reused purchase order — supply a value (including 0) to change it.","body":{"mode":"raw","raw":"{\n  \"contractor_supplier_id\": 9,\n  \"contractor_warehouse_id\": 2,\n  \"outsourced_purchase_order_id\": null,\n  \"scheduled_start\": \"2026-06-01 09:00:00\",\n  \"scheduled_end\": \"2026-06-05 17:00:00\",\n  \"service_fee_amount\": 250,\n  \"notes\": \"Co-packer run for TecMATE\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/outsource","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","outsource"],"variable":[{"key":"manufacturingOrder","value":"","description":"The manufacturingOrder identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"mo_number\": \"MO-000001\",\n    \"status\": \"draft\",\n    \"production_method\": \"outsourced\",\n    \"contractor_supplier_id\": 9,\n    \"outsourced_purchase_order_id\": null,\n    \"scheduled_start\": \"2026-06-01 09:00:00\",\n    \"scheduled_end\": \"2026-06-05 17:00:00\",\n    \"notes\": \"Co-packer run for TecMATE\",\n    \"planned_quantity\": \"5.000\",\n    \"completed_quantity\": \"0.000\",\n    \"created_at\": \"2026-05-28T16:50:00.000000Z\",\n    \"updated_at\": \"2026-05-28T16:56:55.000000Z\"\n  }\n}"}]},{"name":"Record Outsourced Receipt","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/outsourced-receipt","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","outsourced-receipt"],"variable":[{"key":"manufacturingOrder","value":"","description":"The manufacturingOrder identifier"}]},"description":"Record receipt of finished goods from a contractor for an outsourced MO. Runs the production-costing flow: consumes the reserved components from FIFO, produces the output inventory, and costs it as materials + the PO's service fee. The MO must be Started (in_progress / partially_completed).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA service_fee_amount override updates the cost FinancialLine on the backing PO before costing, so it flows into cost_breakdown.service_fee.\n\nFields:\n- receipt_date (required, date)\n- service_fee_amount (optional, numeric ≥ 0) — overrides the PO service-fee financial line\n- lines (required, min 1):\n  - mo_output_line_id (NULLABLE integer) — the MO output line this received quantity produces; defaults to the primary output\n  - purchase_order_line_id (NULLABLE integer) — not used for finished-goods mapping; reserved for PO-linked receipts\n  - received_quantity (required, numeric ≥ 0)\n  - batch_number (optional, ≤ 128 chars) — auto-generated if blank\n  - expiry_date (optional, date)\n- component_variance (optional): mo_component_line_id + actually_consumed_at_contractor — overrides per-component consumption","body":{"mode":"raw","raw":"{\n  \"receipt_date\": \"2026-04-28\",\n  \"service_fee_amount\": 250,\n  \"lines\": [\n    {\n      \"mo_output_line_id\": 1,\n      \"purchase_order_line_id\": null,\n      \"received_quantity\": 100,\n      \"batch_number\": \"CP-LOT-042\",\n      \"expiry_date\": \"2027-04-28\"\n    }\n  ],\n  \"component_variance\": [\n    {\n      \"mo_component_line_id\": 1,\n      \"actually_consumed_at_contractor\": 205\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Backflush Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/backflush-preview?quantity=30000","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","backflush-preview"],"query":[{"key":"quantity","value":"30000","description":"Primary-output quantity you intend to receive. Required.","disabled":true}],"variable":[{"key":"manufacturingOrder","value":"","description":"The manufacturing order ID."}]},"description":"Preview the component consumption that receiving the given quantity of finished goods would record at the contractor site. Consumption is proportional to the manufacturing order's planned quantity per component line. Rows flag a shortage when the projected consumption exceeds the physical on-hand at the contractor site.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{manufacturingOrder}/backflush-preview?quantity=30000","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":manufacturingOrder","backflush-preview"],"query":[{"key":"quantity","value":"30000","description":"Primary-output quantity you intend to receive. Required.","disabled":true}],"variable":[{"key":"manufacturingOrder","value":"","description":"The manufacturing order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"mo_component_line_id\": 18,\n      \"product\": {\n        \"id\": 512,\n        \"sku\": \"100157\",\n        \"name\": \"Single Blade\"\n      },\n      \"on_hand_at_source\": 800000,\n      \"will_consume\": 660000,\n      \"remaining_after\": 140000,\n      \"shortage\": false,\n      \"uom_id\": 1\n    }\n  ]\n}"}]}]},{"name":"Simple Assembly","item":[{"name":"Simple Assemble / Disassemble","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/simple-assemble","host":["{{baseUrl}}"],"path":["api","manufacturing","simple-assemble"]},"description":"Light-manufacturing mode: one-shot assemble/disassemble of a kit product. Creates a Completed Manufacturing Order (`is_simple_mode=true`) in a single call. Use `action: disassemble` to break a kit back into components; the resulting MO is additionally flagged with `is_disassemble=true` so it can be filtered out of the standard MO list.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `kit_product_id` (int, required) — product to assemble or disassemble\n- `quantity` (numeric, required, >0) — units to produce (assemble) or consume (disassemble)\n- `warehouse_id` (int, required)\n- `warehouse_location_id` (int, optional)\n- `action_date` (date, required, m/d/Y or Y-m-d)\n- `action` (string, optional) — `assemble` (default) or `disassemble`\n\n**Response (201 Created):** Flat manufacturing order object for the newly-created Completed MO. The frontend uses the returned `id` to deep-link the success toast to the MO detail page.\n\n**Response (422 Unprocessable Entity — `code: component_shortage`):** Returned when there is not enough on-hand stock to fully allocate the components (assemble) or the kit (disassemble). The atomic run is rolled back, so no partial MO is left behind. The body carries a human-readable `message`/`error` listing the shortfalling lines plus a structured `shortages` array. Use `GET /simple-assemble/preview` first to warn before submit.","body":{"mode":"raw","raw":"{\n  \"kit_product_id\": 42,\n  \"quantity\": 5,\n  \"warehouse_id\": 1,\n  \"warehouse_location_id\": null,\n  \"action_date\": \"2026-05-28\",\n  \"action\": \"assemble\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/simple-assemble","host":["{{baseUrl}}"],"path":["api","manufacturing","simple-assemble"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 15,\n  \"mo_number\": \"MO-000014\",\n  \"status\": \"completed\",\n  \"bom_id\": 4,\n  \"warehouse_id\": 1,\n  \"destination_warehouse_id\": 1,\n  \"planned_quantity\": 2,\n  \"completed_quantity\": 2,\n  \"production_method\": \"in_house\",\n  \"contractor_supplier_id\": null,\n  \"outsourced_purchase_order_id\": null,\n  \"sales_order_id\": null,\n  \"sales_order_line_id\": null,\n  \"priority\": 1000,\n  \"scheduled_start\": null,\n  \"scheduled_end\": null,\n  \"started_at\": \"2026-05-28T00:00:00.000000Z\",\n  \"completed_at\": \"2026-05-28T00:00:00.000000Z\",\n  \"closed_at\": null,\n  \"cancelled_at\": null,\n  \"cancelled_reason_code\": null,\n  \"cancelled_reason_notes\": null,\n  \"is_simple_mode\": true,\n  \"is_disassemble\": true,\n  \"notes\": \"Simple Mode disassembly of QA-COFFEE-250\",\n  \"internal_reference\": null,\n  \"cost_breakdown\": null,\n  \"created_by_id\": 1,\n  \"assigned_to_id\": null,\n  \"created_at\": \"2026-05-28T00:00:00.000000Z\",\n  \"updated_at\": \"2026-05-28T00:00:00.000000Z\",\n  \"archived_at\": null\n}"}]},{"name":"Preview Simple Assemble / Disassemble (Dry-Run)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/simple-assemble/preview","host":["{{baseUrl}}"],"path":["api","manufacturing","simple-assemble","preview"]},"description":"U25: Dry-run preview that returns the BOM-derived components (action=assemble) or the kit itself (action=disassemble) along with required and live on-hand quantities at the chosen warehouse. Does NOT create an MO or consume inventory — used to render a shortage warning beneath the Simple Mode form before submit.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields** (same validation as POST /simple-assemble):\n- `kit_product_id` (int, required) — product to assemble or disassemble\n- `quantity` (numeric, required, >0)\n- `warehouse_id` (int, required)\n- `warehouse_location_id` (int, optional)\n- `action_date` (date, required)\n- `action` (string, optional) — `assemble` (default) or `disassemble`\n\nEach line is also valued: `unit_cost` is the weighted-average cost of the product's available FIFO layers at the chosen warehouse (catalog cost when out of stock), and `extended_cost = unit_cost × required_quantity`. `total_input_cost` sums the line values. For `action=assemble`, `output` carries the expected manufactured product valued at the full component spend (`total_cost = total_input_cost`, `unit_cost = total_cost / quantity`); for `action=disassemble`, `output` is `null`.\n\n**Response shape**:\n```json\n{\n  \"data\": {\n    \"action\": \"assemble\",\n    \"has_shortage\": true,\n    \"total_input_cost\": 36,\n    \"output\": {\n      \"product_id\": 42,\n      \"sku\": \"KIT-001\",\n      \"name\": \"Sample Kit\",\n      \"quantity\": 3,\n      \"total_cost\": 36,\n      \"unit_cost\": 12\n    },\n    \"lines\": [\n      {\n        \"product_id\": 91,\n        \"sku\": \"COMP-A\",\n        \"name\": \"Component A\",\n        \"required_quantity\": 6,\n        \"available_quantity\": 5,\n        \"uom\": \"EACH\",\n        \"unit_cost\": 5,\n        \"extended_cost\": 30,\n        \"shortage\": true\n      }\n    ]\n  }\n}\n```","body":{"mode":"raw","raw":"{\n  \"kit_product_id\": 42,\n  \"quantity\": 5,\n  \"warehouse_id\": 1,\n  \"warehouse_location_id\": null,\n  \"action_date\": \"2026-05-28\",\n  \"action\": \"assemble\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/simple-assemble/preview","host":["{{baseUrl}}"],"path":["api","manufacturing","simple-assemble","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"action\": \"assemble\",\n    \"has_shortage\": true,\n    \"total_input_cost\": 36,\n    \"output\": {\n      \"product_id\": 42,\n      \"sku\": \"KIT-001\",\n      \"name\": \"Sample Kit\",\n      \"quantity\": 3,\n      \"total_cost\": 36,\n      \"unit_cost\": 12\n    },\n    \"lines\": [\n      {\n        \"product_id\": 91,\n        \"sku\": \"COMP-A\",\n        \"name\": \"Component A\",\n        \"required_quantity\": 6,\n        \"available_quantity\": 5,\n        \"uom\": \"EACH\",\n        \"unit_cost\": 5,\n        \"extended_cost\": 30,\n        \"shortage\": true\n      },\n      {\n        \"product_id\": 92,\n        \"sku\": \"COMP-B\",\n        \"name\": \"Component B\",\n        \"required_quantity\": 3,\n        \"available_quantity\": 12,\n        \"uom\": \"EACH\",\n        \"unit_cost\": 2,\n        \"extended_cost\": 6,\n        \"shortage\": false\n      }\n    ]\n  }\n}"}]}]},{"name":"Work Centers","item":[{"name":"List Work Centers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers?per_page=25","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}]},"description":"List Work Centers\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create Work Center","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers"]},"description":"Create Work Center\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Mixing Station\",\n  \"code\": \"WC-MIX-01\",\n  \"default_hourly_rate\": 45,\n  \"default_operator_id\": null,\n  \"overhead_rate_percent\": 15,\n  \"capacity_hours_per_day\": 8,\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Delete Work Centers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers"]},"description":"Permanently delete multiple work centers in one call.\nAuth: requires Bearer token.\nBody: ids (required, array of work center ids, min 1). Rows that fail to delete are counted in failCount instead of aborting the batch.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 2 work center(s)\",\n  \"data\": {\n    \"totalCount\": 2,\n    \"failCount\": 0\n  }\n}"}]},{"name":"List Active Work Centers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers/active","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers","active"]},"description":"Non-paginated list of active work centers. Used for dropdowns on BOM operation editors.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Get Work Center","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get Work Center\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Update Work Center","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update Work Center\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Mixing Station (updated)\",\n  \"default_hourly_rate\": 50,\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Work Center","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/work-centers/{id}","host":["{{baseUrl}}"],"path":["api","manufacturing","work-centers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete Work Center\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}}]},{"name":"Contractors","item":[{"name":"List Contractors","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/contractors","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors"]},"description":"List suppliers flagged as manufacturing contractors, with their default contractor warehouse and default outsourced cost basis (toll | hybrid, null when not set).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/contractors","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 12,\n    \"name\": \"Acme Assembly Co\",\n    \"email\": \"ops@acmeassembly.com\",\n    \"phone\": \"+1-555-0142\",\n    \"is_manufacturing_contractor\": true,\n    \"contractor_default_warehouse_id\": 9,\n    \"default_outsourced_cost_basis\": \"toll\",\n    \"virtual_warehouse\": {\n      \"id\": 9,\n      \"name\": \"Acme Assembly Co (Contractor)\"\n    },\n    \"active_mo_count\": 2,\n    \"total_mo_count\": 14\n  }\n]"}]},{"name":"Create Contractor","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/contractors","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors"]},"description":"Designate an existing supplier as a manufacturing contractor for outsourced production. Provisions a virtual warehouse that holds the stock issued to the contractor for its manufacturing orders.\nAuth: requires Bearer token.\nBody: supplier_id (required, integer, existing supplier id); virtual_warehouse_name (optional, string, max 255) - name for the contractor's virtual warehouse, a default is generated when omitted; default_outsourced_cost_basis (optional, string, one of: toll, hybrid) - default cost basis applied to new outsourced manufacturing orders for this contractor. Use toll when you own all component materials and the contractor only charges for processing (the contractor's product charge is treated as a processing cost, not added on top of your component costs). Use hybrid when the contractor supplies materials of their own beyond the components you provide (their charge is capitalized into the output cost). Omit or null to fall back to hybrid.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 12,\n  \"virtual_warehouse_name\": \"Acme Assembly Co (Contractor)\",\n  \"default_outsourced_cost_basis\": \"toll\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/contractors","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"name\": \"Acme Assembly Co\",\n  \"email\": \"ops@acmeassembly.com\",\n  \"phone\": \"+1-555-0142\",\n  \"is_manufacturing_contractor\": true,\n  \"contractor_default_warehouse_id\": 9,\n  \"default_outsourced_cost_basis\": \"toll\",\n  \"virtual_warehouse\": {\n    \"id\": 9,\n    \"name\": \"Acme Assembly Co (Contractor)\"\n  },\n  \"active_mo_count\": 0,\n  \"total_mo_count\": 0\n}"}]},{"name":"Update Contractor","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/contractors/{supplier}","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors",":supplier"],"variable":[{"key":"supplier","value":"12","description":"The supplier ID."}]},"description":"Update a contractor's manufacturing settings.\nAuth: requires Bearer token.\nPath param: supplier = supplier id.\nBody: default_outsourced_cost_basis (optional, string, one of: toll, hybrid) - default cost basis applied to new outsourced manufacturing orders for this contractor. Use toll when you own all component materials and the contractor only charges for processing (the contractor's product charge is treated as a processing cost, not added on top of your component costs). Use hybrid when the contractor supplies materials of their own beyond the components you provide (their charge is capitalized into the output cost). Omit or null to fall back to hybrid.\nSend null to clear the setting (new outsourced orders then fall back to hybrid). Changing the default does not alter existing manufacturing orders; each order may also set its own outsourced_cost_basis override at creation.","body":{"mode":"raw","raw":"{\n  \"default_outsourced_cost_basis\": \"toll\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/manufacturing/contractors/{supplier}","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors",":supplier"],"variable":[{"key":"supplier","value":"12","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"name\": \"Acme Assembly Co\",\n  \"email\": \"ops@acmeassembly.com\",\n  \"phone\": \"+1-555-0142\",\n  \"is_manufacturing_contractor\": true,\n  \"contractor_default_warehouse_id\": 9,\n  \"default_outsourced_cost_basis\": \"toll\",\n  \"virtual_warehouse\": {\n    \"id\": 9,\n    \"name\": \"Acme Assembly Co (Contractor)\"\n  },\n  \"active_mo_count\": 0,\n  \"total_mo_count\": 0\n}"}]},{"name":"Delete Contractor","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/contractors/{supplier}","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors",":supplier"],"variable":[{"key":"supplier","value":"12","description":"The supplier ID."}]},"description":"Remove the manufacturing-contractor designation from a supplier. The supplier record itself is not deleted. Fails with 409 while the contractor still has active manufacturing orders.\nAuth: requires Bearer token.\nPath param: supplier = supplier id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/contractors/{supplier}","host":["{{baseUrl}}"],"path":["api","manufacturing","contractors",":supplier"],"variable":[{"key":"supplier","value":"12","description":"The supplier ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]}]},{"name":"Units of Measure","item":[{"name":"List Units of Measure","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure"]},"description":"List every unit of measure, ordered by type then code. Includes both system-defined units (is_system=true, read-only) and custom units.\nAuth: requires Bearer token.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"code\": \"BOX12\",\n      \"name\": \"Box of 12\",\n      \"uom_type\": \"count\",\n      \"is_system\": false\n    },\n    {\n      \"id\": 1,\n      \"code\": \"EA\",\n      \"name\": \"Each\",\n      \"uom_type\": \"count\",\n      \"is_system\": true\n    },\n    {\n      \"id\": 7,\n      \"code\": \"KG\",\n      \"name\": \"Kilogram\",\n      \"uom_type\": \"weight\",\n      \"is_system\": true\n    }\n  ]\n}"}]},{"name":"Create Unit of Measure","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure"]},"description":"Create a custom unit of measure.\nAuth: requires Bearer token.\nBody: code (required, string, max 16, unique - stored uppercased); name (required, string, max 64); uom_type (required, one of: weight, volume, count).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"code\": \"BOX12\",\n  \"name\": \"Box of 12\",\n  \"uom_type\": \"count\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"code\": \"BOX12\",\n  \"name\": \"Box of 12\",\n  \"uom_type\": \"count\",\n  \"is_system\": false\n}"}]},{"name":"Get Unit of Measure","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]},"description":"Get a single unit of measure by id.\nAuth: requires Bearer token.\nPath param: unitOfMeasure = unit of measure id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"code\": \"BOX12\",\n  \"name\": \"Box of 12\",\n  \"uom_type\": \"count\",\n  \"is_system\": false\n}"}]},{"name":"Update Unit of Measure","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]},"description":"Update a custom unit of measure. All fields are optional - only submitted fields change.\nAuth: requires Bearer token.\nPath param: unitOfMeasure = unit of measure id.\nBody: code (string, max 16, unique - stored uppercased); name (string, max 64); uom_type (one of: weight, volume, count).\nSystem units of measure (is_system=true) cannot be modified and return 422.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Box of Twelve\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"code\": \"BOX12\",\n  \"name\": \"Box of Twelve\",\n  \"uom_type\": \"count\",\n  \"is_system\": false\n}"}]},{"name":"Delete Unit of Measure","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]},"description":"Delete a custom unit of measure. System units cannot be deleted, and units still referenced by product configurations, BOM lines, or manufacturing order lines return 422 with the reference count.\nAuth: requires Bearer token.\nPath param: unitOfMeasure = unit of measure id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/units-of-measure/{unitOfMeasure}","host":["{{baseUrl}}"],"path":["api","manufacturing","units-of-measure",":unitOfMeasure"],"variable":[{"key":"unitOfMeasure","value":"12","description":"The unit of measure ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Product Units of Measure","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure"],"variable":[{"key":"product","value":"1","description":"The product ID."}]},"description":"List the unit-of-measure configuration for a product: which unit is the stock unit, which are used for purchasing and sales, and the conversion factor of each unit into stock units.\nAuth: requires Bearer token.\nPath param: product = product id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure"],"variable":[{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41,\n      \"product_id\": 1,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"is_stock_uom\": true,\n      \"is_purchase_uom\": false,\n      \"is_sales_uom\": false,\n      \"conversion_factor\": 1,\n      \"display_precision\": 0\n    },\n    {\n      \"id\": 42,\n      \"product_id\": 1,\n      \"uom_id\": 12,\n      \"unit_of_measure\": {\n        \"id\": 12,\n        \"code\": \"BOX12\",\n        \"name\": \"Box of 12\",\n        \"uom_type\": \"count\",\n        \"is_system\": false\n      },\n      \"is_stock_uom\": false,\n      \"is_purchase_uom\": true,\n      \"is_sales_uom\": true,\n      \"conversion_factor\": 12,\n      \"display_precision\": 0\n    }\n  ]\n}"}]},{"name":"Update Product Units of Measure","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure"],"variable":[{"key":"product","value":"1","description":"The product ID."}]},"description":"Replace the product's full unit-of-measure configuration in one call. Exactly one row must be the stock unit with conversion_factor 1; at most one purchase unit and at most one sales unit are allowed.\nAuth: requires Bearer token.\nPath param: product = product id.\nBody: units_of_measure (required, array, min 1). Per row: uom_id (required, existing unit id); conversion_factor (required, numeric, greater than 0 - how many stock units one of this unit represents); display_precision (optional, integer 0-8); is_stock_uom / is_purchase_uom / is_sales_uom (optional booleans).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"units_of_measure\": [\n    {\n      \"uom_id\": 1,\n      \"conversion_factor\": 1,\n      \"is_stock_uom\": true\n    },\n    {\n      \"uom_id\": 12,\n      \"conversion_factor\": 12,\n      \"is_purchase_uom\": true,\n      \"is_sales_uom\": true,\n      \"display_precision\": 0\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure"],"variable":[{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41,\n      \"product_id\": 1,\n      \"uom_id\": 1,\n      \"unit_of_measure\": {\n        \"id\": 1,\n        \"code\": \"EA\",\n        \"name\": \"Each\",\n        \"uom_type\": \"count\",\n        \"is_system\": true\n      },\n      \"is_stock_uom\": true,\n      \"is_purchase_uom\": false,\n      \"is_sales_uom\": false,\n      \"conversion_factor\": 1,\n      \"display_precision\": 0\n    },\n    {\n      \"id\": 42,\n      \"product_id\": 1,\n      \"uom_id\": 12,\n      \"unit_of_measure\": {\n        \"id\": 12,\n        \"code\": \"BOX12\",\n        \"name\": \"Box of 12\",\n        \"uom_type\": \"count\",\n        \"is_system\": false\n      },\n      \"is_stock_uom\": false,\n      \"is_purchase_uom\": true,\n      \"is_sales_uom\": true,\n      \"conversion_factor\": 12,\n      \"display_precision\": 0\n    }\n  ]\n}"}]},{"name":"Enable Product Unit of Measure","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure/enable","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure","enable"],"variable":[{"key":"product","value":"1","description":"The product ID."}]},"description":"Idempotently enable a single unit of measure for a product so a bill-of-materials or manufacturing-order line referencing it can be saved without first configuring the full unit-of-measure set. The unit is added as a pending alternate with no conversion factor (0), which lets draft documents validate; a real conversion factor must still be set before the bill of materials can be activated. Calling this repeatedly for the same unit is safe and returns the existing configuration untouched.\nAuth: requires Bearer token.\nPath param: product = product id.\nBody: uom_id = id of the unit of measure to enable (must exist).","body":{"mode":"raw","raw":"{\n  \"uom_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/products/{product}/units-of-measure/enable","host":["{{baseUrl}}"],"path":["api","manufacturing","products",":product","units-of-measure","enable"],"variable":[{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"product_id\": 1,\n    \"uom_id\": 12,\n    \"unit_of_measure\": {\n      \"id\": 12,\n      \"code\": \"BOX12\",\n      \"name\": \"Box of 12\",\n      \"uom_type\": \"count\",\n      \"is_system\": false\n    },\n    \"is_stock_uom\": false,\n    \"is_purchase_uom\": false,\n    \"is_sales_uom\": false,\n    \"conversion_factor\": 0,\n    \"display_precision\": 2,\n    \"has_transactional_history\": false\n  }\n}"}]}]},{"name":"Scheduler","item":[{"name":"List Scheduled Manufacturing Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/scheduler/scheduled?from=2026-04-01&to=2026-04-30&include_unscheduled=1","host":["{{baseUrl}}"],"path":["api","manufacturing","scheduler","scheduled"],"query":[{"key":"from","value":"2026-04-01","description":"Start date (inclusive) for scheduled_start. Defaults to today's start-of-day when omitted.","disabled":true},{"key":"to","value":"2026-04-30","description":"End date (inclusive) for scheduled_start. Defaults to today + 30 days end-of-day when omitted.","disabled":true},{"key":"include_unscheduled","value":"1","description":"Include MOs with priority but no scheduled_start (U19 / U41). Default: 1 (true). Accepts truthy values 1, true, yes, on. Set to 0 / false to restrict the response to MOs whose scheduled_start falls inside the from/to range.","disabled":true}]},"description":"Returns MOs with a scheduled_start within the date range. Non-paginated response shaped as `{ data, from, to, include_unscheduled, status, warehouse_ids }`.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Show Unscheduled (U19 / U41):** Pass `include_unscheduled=1` (default) to include MOs that have a priority value but no `scheduled_start` — these appear in the application UI Production Scheduler's Priority Queue sidebar so users can clear the production backlog. Pass `include_unscheduled=0` to restrict the response to MOs whose `scheduled_start` falls inside the `from`/`to` date range.\n\n**Status filter (U40):** Pass `status[]=draft&status[]=in_progress` (or comma-separated `status=draft,in_progress`) to restrict the timeline to specific MO statuses. Allowed values: `draft`, `confirmed`, `in_progress`, `partially_completed`. Unknown values are dropped; if nothing valid remains the filter falls back to all four active statuses. Omit to include all four.\n\n**Warehouse filter (U40):** Pass `warehouse_ids[]=5&warehouse_ids[]=7` (or comma-separated `warehouse_ids=5,7`) to restrict the timeline to MOs whose production warehouse OR destination warehouse matches one of the listed IDs. Non-numeric / zero / negative values are dropped. Omit to include all warehouses.\n\nThe top-level `include_unscheduled`, `status`, and `warehouse_ids` fields in the response echo the resolved filters that were applied.\n\n**Primary output name:** `primary_output_name` resolves from the MO output lines. Draft MOs have no materialized output lines yet (they are created from the BOM at confirm time), so for drafts the value falls back to the BOM's primary output product — the Priority Queue never shows a blank output for a valid MO."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/scheduler/scheduled?from=2026-04-01&to=2026-04-30&include_unscheduled=1","host":["{{baseUrl}}"],"path":["api","manufacturing","scheduler","scheduled"],"query":[{"key":"from","value":"2026-04-01","description":"Start date (inclusive) for scheduled_start. Defaults to today's start-of-day when omitted.","disabled":true},{"key":"to","value":"2026-04-30","description":"End date (inclusive) for scheduled_start. Defaults to today + 30 days end-of-day when omitted.","disabled":true},{"key":"include_unscheduled","value":"1","description":"Include MOs with priority but no scheduled_start (U19 / U41). Default: 1 (true). Accepts truthy values 1, true, yes, on. Set to 0 / false to restrict the response to MOs whose scheduled_start falls inside the from/to range.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1042,\n      \"mo_number\": \"MO-001042\",\n      \"status\": \"in_progress\",\n      \"bom_id\": 318,\n      \"bom_name\": \"Widget Assembly v3\",\n      \"warehouse_id\": 5,\n      \"warehouse_name\": \"Main Production\",\n      \"destination_warehouse_id\": 5,\n      \"destination_warehouse_name\": \"Main Production\",\n      \"primary_output_name\": \"Widget Output\",\n      \"planned_quantity\": \"100.000000\",\n      \"completed_quantity\": \"42.000000\",\n      \"production_method\": \"in_house\",\n      \"contractor_supplier_id\": null,\n      \"contractor_supplier_name\": null,\n      \"outsourced_purchase_order_id\": null,\n      \"sales_order_id\": null,\n      \"sales_order_line_id\": null,\n      \"priority\": 1,\n      \"scheduled_start\": \"2026-04-05T08:00:00+00:00\",\n      \"scheduled_end\": \"2026-04-07T17:00:00+00:00\",\n      \"started_at\": \"2026-04-05T08:15:00+00:00\",\n      \"completed_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"is_simple_mode\": false,\n      \"internal_reference\": \"REF-Q2-001\",\n      \"assigned_to_id\": 12,\n      \"assigned_to\": {\n        \"id\": 12,\n        \"name\": \"Jane Doe\"\n      },\n      \"cost_breakdown\": {\n        \"materials\": \"1240.50\",\n        \"labor\": \"320.00\",\n        \"overhead\": \"85.00\",\n        \"fixed\": \"25.00\"\n      },\n      \"has_shortage\": false,\n      \"created_at\": \"2026-03-28T14:22:11+00:00\",\n      \"updated_at\": \"2026-04-05T08:15:00+00:00\",\n      \"archived_at\": null\n    },\n    {\n      \"id\": 1058,\n      \"mo_number\": \"MO-001058\",\n      \"status\": \"draft\",\n      \"bom_id\": 412,\n      \"bom_name\": \"Gadget Pro Kit\",\n      \"warehouse_id\": 5,\n      \"warehouse_name\": \"Main Production\",\n      \"destination_warehouse_id\": 7,\n      \"destination_warehouse_name\": \"Downtown DC\",\n      \"primary_output_name\": \"Gadget Pro\",\n      \"planned_quantity\": \"50.000000\",\n      \"completed_quantity\": \"0.000000\",\n      \"production_method\": \"outsourced\",\n      \"contractor_supplier_id\": 22,\n      \"contractor_supplier_name\": \"Acme Contracting Co.\",\n      \"outsourced_purchase_order_id\": 9871,\n      \"sales_order_id\": null,\n      \"sales_order_line_id\": null,\n      \"priority\": 5,\n      \"scheduled_start\": null,\n      \"scheduled_end\": null,\n      \"started_at\": null,\n      \"completed_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"is_simple_mode\": false,\n      \"internal_reference\": null,\n      \"assigned_to_id\": null,\n      \"assigned_to\": null,\n      \"cost_breakdown\": null,\n      \"has_shortage\": true,\n      \"created_at\": \"2026-04-01T09:10:33+00:00\",\n      \"updated_at\": \"2026-04-01T09:10:33+00:00\",\n      \"archived_at\": null\n    }\n  ],\n  \"from\": \"2026-04-01T00:00:00+00:00\",\n  \"to\": \"2026-04-30T23:59:59+00:00\",\n  \"include_unscheduled\": true,\n  \"status\": [\n    \"draft\",\n    \"in_progress\"\n  ],\n  \"warehouse_ids\": [\n    5\n  ]\n}"}]},{"name":"Reprioritize Manufacturing Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/scheduler/reprioritize","host":["{{baseUrl}}"],"path":["api","manufacturing","scheduler","reprioritize"]},"description":"Bulk update MO priorities after a drag-and-drop reorder on the scheduler board. Each MO whose priority actually changes records a `priority_changed` event on its Manufacturing Order event timeline (with `from_priority` / `to_priority` in the payload); entries whose priority is unchanged are skipped and not counted in `updated`.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"id\": 1,\n      \"priority\": 10\n    },\n    {\n      \"id\": 2,\n      \"priority\": 20\n    },\n    {\n      \"id\": 3,\n      \"priority\": 30\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/scheduler/reprioritize","host":["{{baseUrl}}"],"path":["api","manufacturing","scheduler","reprioritize"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3\n  },\n  \"message\": \"Priorities updated.\"\n}"}]},{"name":"Reschedule MO","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/manufacturing-orders/{id}/reschedule","host":["{{baseUrl}}"],"path":["api","manufacturing","manufacturing-orders",":id","reschedule"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Reschedule MO\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"scheduled_start\": \"2026-04-25\",\n  \"scheduled_end\": \"2026-04-27\"\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Demand Suggestions","item":[{"name":"List Demand Suggestions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions?per_page=25","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions"],"query":[{"key":"per_page","value":"25","description":"Results per page (default 10).","disabled":true}]},"description":"List Demand Suggestions\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Generate Demand Suggestions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/generate","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions","generate"]},"description":"Regenerate the pending demand suggestions from current inventory + sales state and return them. PERSISTS: existing pending rows are replaced; confirmed and dismissed suggestions are preserved. Body params: `look_back_days` (int, default 30) — sales-history window used to compute velocity; `safety_days` (int, default 7) — safety-stock buffer added to the need. Response: `{ data: [DemandSuggestion], message: \"N suggestions generated\", look_back_days, safety_days }`.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"look_back_days\": 30,\n  \"safety_days\": 7\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Demand Suggestion","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]},"description":"Update the suggested quantity on a pending demand suggestion.\nAuth: requires Bearer token.\nPath param: demandSuggestion = demand suggestion id.\nBody: suggested_qty (required, numeric, greater than 0).\nOnly pending suggestions can be edited - confirmed or dismissed suggestions return 422.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"suggested_qty\": 150\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 31,\n    \"product_id\": 1,\n    \"product\": {\n      \"id\": 1,\n      \"sku\": \"KIT-A\",\n      \"name\": \"Widget Kit A\"\n    },\n    \"bom_id\": 15,\n    \"bom\": {\n      \"id\": 15,\n      \"name\": \"Default Recipe\"\n    },\n    \"suggested_qty\": 150,\n    \"on_hand\": 12,\n    \"days_of_supply\": 2.5,\n    \"reason\": \"Projected to run out in 2.5 days based on recent sales velocity\",\n    \"status\": \"pending\",\n    \"confirmed_at\": null,\n    \"dismissed_at\": null,\n    \"confirmed_manufacturing_order_id\": null,\n    \"created_at\": \"2026-06-30T02:00:00.000000Z\",\n    \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n  }\n}"}]},{"name":"Confirm Demand Suggestion","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}/confirm","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion","confirm"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]},"description":"Confirm a pending demand suggestion. Creates a Draft manufacturing order from the suggestion's BOM and suggested quantity, and links it via confirmed_manufacturing_order_id.\nAuth: requires Bearer token.\nPath param: demandSuggestion = demand suggestion id.\nReturns 422 when the suggestion is not pending or has no default BOM.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}/confirm","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion","confirm"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 31,\n    \"product_id\": 1,\n    \"product\": {\n      \"id\": 1,\n      \"sku\": \"KIT-A\",\n      \"name\": \"Widget Kit A\"\n    },\n    \"bom_id\": 15,\n    \"bom\": {\n      \"id\": 15,\n      \"name\": \"Default Recipe\"\n    },\n    \"suggested_qty\": 150,\n    \"on_hand\": 12,\n    \"days_of_supply\": 2.5,\n    \"reason\": \"Projected to run out in 2.5 days based on recent sales velocity\",\n    \"status\": \"confirmed\",\n    \"confirmed_at\": \"2026-07-01T14:22:09.000000Z\",\n    \"dismissed_at\": null,\n    \"confirmed_manufacturing_order_id\": 57,\n    \"created_at\": \"2026-06-30T02:00:00.000000Z\",\n    \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n  }\n}"}]},{"name":"Dismiss Demand Suggestion","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion","dismiss"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]},"description":"Dismiss a pending demand suggestion so it no longer appears as actionable. Dismissed suggestions are preserved and are not recreated by the next generation run.\nAuth: requires Bearer token.\nPath param: demandSuggestion = demand suggestion id.\nReturns 422 when the suggestion is not pending.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/{demandSuggestion}/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions",":demandSuggestion","dismiss"],"variable":[{"key":"demandSuggestion","value":"31","description":"The demand suggestion ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 31,\n    \"product_id\": 1,\n    \"product\": {\n      \"id\": 1,\n      \"sku\": \"KIT-A\",\n      \"name\": \"Widget Kit A\"\n    },\n    \"bom_id\": 15,\n    \"bom\": {\n      \"id\": 15,\n      \"name\": \"Default Recipe\"\n    },\n    \"suggested_qty\": 150,\n    \"on_hand\": 12,\n    \"days_of_supply\": 2.5,\n    \"reason\": \"Projected to run out in 2.5 days based on recent sales velocity\",\n    \"status\": \"dismissed\",\n    \"confirmed_at\": null,\n    \"dismissed_at\": \"2026-07-01T14:22:09.000000Z\",\n    \"confirmed_manufacturing_order_id\": null,\n    \"created_at\": \"2026-06-30T02:00:00.000000Z\",\n    \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n  }\n}"}]},{"name":"Bulk Confirm Demand Suggestions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/bulk/confirm","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions","bulk","confirm"]},"description":"Confirm multiple pending demand suggestions in one call - each confirmed suggestion gets its own Draft manufacturing order. Suggestions that are not pending or have no default BOM are skipped silently; only the confirmed rows are returned.\nAuth: requires Bearer token.\nBody: ids (required, array of demand suggestion ids, min 1).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    31,\n    32,\n    33\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/bulk/confirm","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions","bulk","confirm"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 31,\n      \"product_id\": 1,\n      \"product\": {\n        \"id\": 1,\n        \"sku\": \"KIT-A\",\n        \"name\": \"Widget Kit A\"\n      },\n      \"bom_id\": 15,\n      \"bom\": {\n        \"id\": 15,\n        \"name\": \"Default Recipe\"\n      },\n      \"suggested_qty\": 150,\n      \"on_hand\": 12,\n      \"days_of_supply\": 2.5,\n      \"reason\": \"Projected to run out in 2.5 days based on recent sales velocity\",\n      \"status\": \"confirmed\",\n      \"confirmed_at\": \"2026-07-01T14:22:09.000000Z\",\n      \"dismissed_at\": null,\n      \"confirmed_manufacturing_order_id\": 57,\n      \"created_at\": \"2026-06-30T02:00:00.000000Z\",\n      \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n    }\n  ],\n  \"message\": \"1 suggestions confirmed\"\n}"}]},{"name":"Bulk Dismiss Demand Suggestions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/bulk/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions","bulk","dismiss"]},"description":"Dismiss multiple pending demand suggestions in one call. Suggestions that are not pending are skipped silently; only the dismissed rows are returned.\nAuth: requires Bearer token.\nBody: ids (required, array of demand suggestion ids, min 1).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    31,\n    32,\n    33\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/demand-suggestions/bulk/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","demand-suggestions","bulk","dismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 31,\n      \"product_id\": 1,\n      \"product\": {\n        \"id\": 1,\n        \"sku\": \"KIT-A\",\n        \"name\": \"Widget Kit A\"\n      },\n      \"bom_id\": 15,\n      \"bom\": {\n        \"id\": 15,\n        \"name\": \"Default Recipe\"\n      },\n      \"suggested_qty\": 150,\n      \"on_hand\": 12,\n      \"days_of_supply\": 2.5,\n      \"reason\": \"Projected to run out in 2.5 days based on recent sales velocity\",\n      \"status\": \"dismissed\",\n      \"confirmed_at\": null,\n      \"dismissed_at\": \"2026-07-01T14:22:09.000000Z\",\n      \"confirmed_manufacturing_order_id\": null,\n      \"created_at\": \"2026-06-30T02:00:00.000000Z\",\n      \"updated_at\": \"2026-07-01T14:22:09.000000Z\"\n    }\n  ],\n  \"message\": \"1 suggestions dismissed\"\n}"}]}]},{"name":"Lots","item":[{"name":"List Lots","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lots?page=1&per_page=15&sort=-manufacture_date","host":["{{baseUrl}}"],"path":["api","manufacturing","lots"],"query":[{"key":"page","value":"1","description":"Page number (1-indexed). Defaults to 1.","disabled":true},{"key":"per_page","value":"15","description":"Items per page. Defaults to 15.","disabled":true},{"key":"sort","value":"-manufacture_date","description":"Prefix with `-` for descending. Allowed: `id`, `batch_number`, `manufacture_date`, `expiry_date`, `fifo_layer_date`, `original_quantity`, `fulfilled_quantity`, `created_at`, `updated_at`, `warehouse_name`, `sku`, `product_name`. Defaults to `-manufacture_date,-id`.","disabled":true}]},"description":"Paginated list of FIFO layers that have a `batch_number` (\"lots\"). Drives the Manufacturing → Lots screen and is the data source the Source chip uses to deep-link back to the originating Manufacturing Order, Purchase Order, etc.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSimple-Mode disassembly produces component lots whose `link_type` is `InventoryMovement` (which itself links to the ManufacturingOrder). The `source` block resolves `parent_link_id` to the navigable parent document (e.g. ManufacturingOrder.id) so the UI can build a working link in one hop."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lots?page=1&per_page=15&sort=-manufacture_date","host":["{{baseUrl}}"],"path":["api","manufacturing","lots"],"query":[{"key":"page","value":"1","description":"Page number (1-indexed). Defaults to 1.","disabled":true},{"key":"per_page","value":"15","description":"Items per page. Defaults to 15.","disabled":true},{"key":"sort","value":"-manufacture_date","description":"Prefix with `-` for descending. Allowed: `id`, `batch_number`, `manufacture_date`, `expiry_date`, `fifo_layer_date`, `original_quantity`, `fulfilled_quantity`, `created_at`, `updated_at`, `warehouse_name`, `sku`, `product_name`. Defaults to `-manufacture_date,-id`.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 20,\n      \"batch_number\": \"DA-MO-000015-2026-05-28\",\n      \"manufacture_date\": \"2026-05-28\",\n      \"expiry_date\": null,\n      \"product_id\": 305,\n      \"product\": {\n        \"id\": 305,\n        \"sku\": \"WIDGET-A\",\n        \"name\": \"Widget Component A\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"original_quantity\": 4,\n      \"fulfilled_quantity\": 0,\n      \"quantity_on_hand\": 4,\n      \"source_type\": \"manufacturing_order\",\n      \"source_reference\": \"MO-000015\",\n      \"source\": {\n        \"link_type\": \"App\\\\Models\\\\InventoryMovement\",\n        \"link_id\": 40,\n        \"parent_link_id\": 17,\n        \"reference\": \"MO-000015\"\n      },\n      \"fifo_layer_date\": \"2026-05-28T00:00:00.000000Z\",\n      \"created_at\": \"2026-05-28T14:12:33.000000Z\",\n      \"updated_at\": \"2026-05-28T14:12:33.000000Z\"\n    },\n    {\n      \"id\": 19,\n      \"batch_number\": \"LOT-2026-04-001\",\n      \"manufacture_date\": \"2026-04-15\",\n      \"expiry_date\": \"2027-04-15\",\n      \"product_id\": 412,\n      \"product\": {\n        \"id\": 412,\n        \"sku\": \"KIT-A\",\n        \"name\": \"Widget Kit\"\n      },\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"original_quantity\": 50,\n      \"fulfilled_quantity\": 12,\n      \"quantity_on_hand\": 38,\n      \"source_type\": \"manufacturing_order\",\n      \"source_reference\": \"MO-000014\",\n      \"source\": {\n        \"link_type\": \"App\\\\Models\\\\MoOutputLine\",\n        \"link_id\": 88,\n        \"parent_link_id\": 14,\n        \"reference\": \"MO-000014\"\n      },\n      \"fifo_layer_date\": \"2026-04-15T00:00:00.000000Z\",\n      \"created_at\": \"2026-04-15T09:30:00.000000Z\",\n      \"updated_at\": \"2026-04-20T11:45:12.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 42,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://your-domain.sku.io/api/manufacturing/lots?page=1\",\n  \"last_page_url\": \"https://your-domain.sku.io/api/manufacturing/lots?page=3\",\n  \"next_page_url\": \"https://your-domain.sku.io/api/manufacturing/lots?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://your-domain.sku.io/api/manufacturing/lots\",\n  \"links\": []\n}"}]}]},{"name":"Lot Genealogy","item":[{"name":"Trace Lot Genealogy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy?batch_number=LOT-2026-04-001&product_id=1&direction=backward&max_depth=5","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to trace.","disabled":true},{"key":"product_id","value":"1","description":"Optional. Omit and the API auto-resolves it from the batch number. If the same batch number is shared by multiple products the response is 409 with a `candidates` array.","disabled":true},{"key":"direction","value":"backward","description":"backward = trace inputs; forward = trace outputs","disabled":true},{"key":"max_depth","value":"5","description":"Optional. 1–10, defaults to 5.","disabled":true}]},"description":"Returns a genealogy tree for a batch/lot. `batch_number` is required; `product_id` is optional and auto-resolved from the batch number when it uniquely identifies a FIFO layer. When the same batch number is used across multiple products, the API responds 409 with a `candidates` array so a UI can prompt for product disambiguation. Direction `backward` traces from finished good back to raw material inputs (recall use case); `forward` traces from raw material to all downstream produced lots (recall impact analysis).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy?batch_number=LOT-2026-04-001&product_id=1&direction=backward&max_depth=5","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to trace.","disabled":true},{"key":"product_id","value":"1","description":"Optional. Omit and the API auto-resolves it from the batch number. If the same batch number is shared by multiple products the response is 409 with a `candidates` array.","disabled":true},{"key":"direction","value":"backward","description":"backward = trace inputs; forward = trace outputs","disabled":true},{"key":"max_depth","value":"5","description":"Optional. 1–10, defaults to 5.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"fifo-512\",\n    \"entity_type\": \"manufacturing_order\",\n    \"reference\": \"MO-000123\",\n    \"product_id\": 88,\n    \"product_name\": \"Widget Kit\",\n    \"batch_number\": \"LOT-2026-04-001\",\n    \"quantity\": 50,\n    \"date\": \"2026-04-01\",\n    \"fifo_layer_id\": 512,\n    \"children\": []\n  },\n  \"direction\": \"backward\",\n  \"resolved_product_id\": 88\n}"}]},{"name":"Search Batch Numbers (Typeahead)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/batches?search=VIT","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","batches"],"query":[{"key":"search","value":"VIT","description":"Search term matched against FIFO-layer batch numbers (partial match). Returns an empty array for searches shorter than 2 characters.","disabled":true}]},"description":"Typeahead for the \"Trace a Lot\" batch-number field. Returns up to 25 distinct FIFO-layer batch numbers matching the `search` term, each with single-product context. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns an empty array (`{\"data\": []}`) for searches under 2 characters.\n\nWhen a batch number maps to exactly one product, `product_count` is 1 and `product_id`/`product_sku`/`product_name` are populated. When `product_count` is greater than 1 the batch spans multiple products, so those context fields are null and the caller should also supply a `product_id` on the genealogy trace request (or follow the 409 `candidates` disambiguation flow from `GET /api/manufacturing/lot-genealogy`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/batches?search=VIT","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","batches"],"query":[{"key":"search","value":"VIT","description":"Search term matched against FIFO-layer batch numbers (partial match). Returns an empty array for searches shorter than 2 characters.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"batch_number\": \"VIT-2026-04-001\",\n      \"product_id\": 88,\n      \"product_sku\": \"VIT-C-1000\",\n      \"product_name\": \"Vitamin C 1000mg\",\n      \"product_count\": 1\n    },\n    {\n      \"batch_number\": \"VIT-SHARED-002\",\n      \"product_id\": null,\n      \"product_sku\": null,\n      \"product_name\": null,\n      \"product_count\": 2\n    }\n  ]\n}"}]},{"name":"Trace by Sales Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/by-sales-orders?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","by-sales-orders"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids to trace, as a comma-separated string (`4821,4822`) or an array (`sales_order_ids[]=4821&sales_order_ids[]=4822`). Max 500 per request.","disabled":true}]},"description":"Recall (reverse) — backward \"made-from\" forest for one or more sales orders. For every finished-good batch shipped on each order, traces upstream to the raw-ingredient lots (and their vendors) that went into it. Drives the genealogy page's \"trace by sales order(s)\" mode and the Sales Orders list view's \"Trace Genealogy (Backward)\" bulk action. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAccepts `sales_order_ids` as a comma-separated string or an array. Orders with no shipped finished goods are silently skipped.\n\nReturns:\n- `data.roots` — one synthetic sales-order root node per traced order (entity_type `sales_order`, carrying `reference`, `customer_name`, and `link_parent_id`). Each root's `children` are the backward traces of the finished-good batches that order shipped; each finished-good node's `consumed_quantity` is the qty of that batch shipped on the order, and its descendants are the component lots with `supplier_name` on purchased raw-ingredient layers.\n- `summary` — `order_count` (ids supplied), `traced_order_count` (roots returned), `finished_good_count` (finished-good batches traced).\n\nErrors:\n- `422` when no ids are supplied, or more than 500 are.\n- `404` when none of the supplied orders have shipped finished goods to trace.\n\nThe response also embeds `affected_lots` (rows + summary) — the deduplicated implicated-lots/suppliers list — computed from the same forest build so the UI needn't fetch/rebuild it separately.\n\n`requested_orders` lists every selected order (traced or not) with its number, so the UI can label each selected-order chip — the SO list endpoint can't resolve multiple ids."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/by-sales-orders?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","by-sales-orders"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids to trace, as a comma-separated string (`4821,4822`) or an array (`sales_order_ids[]=4821&sales_order_ids[]=4822`). Max 500 per request.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"roots\": [\n      {\n        \"id\": \"so-4821\",\n        \"entity_type\": \"sales_order\",\n        \"reference\": \"SO-7881\",\n        \"link_parent_id\": 4821,\n        \"customer_name\": \"Acme Health Foods\",\n        \"date\": \"2026-04-12\",\n        \"children\": [\n          {\n            \"id\": \"fifo-135\",\n            \"entity_type\": \"manufacturing_order\",\n            \"reference\": \"MO-504211\",\n            \"product_name\": \"Calm Gummies\",\n            \"product_sku\": \"CALM-GUMMIES\",\n            \"batch_number\": \"CALM-MO-2026-0001\",\n            \"consumed_quantity\": 6,\n            \"manufacturing_order_id\": 504211,\n            \"children\": [\n              {\n                \"id\": \"fifo-134\",\n                \"entity_type\": \"purchase_order\",\n                \"reference\": \"PO-0003\",\n                \"product_name\": \"Ashwagandha Extract\",\n                \"product_sku\": \"ASHWA-EXT\",\n                \"batch_number\": \"ASH-2026-RAW-0001\",\n                \"consumed_quantity\": 20,\n                \"purchase_order_id\": 3,\n                \"supplier_id\": 4,\n                \"supplier_name\": \"Acme Botanicals\",\n                \"children\": []\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  },\n  \"requested_orders\": [\n    {\n      \"id\": 4821,\n      \"reference\": \"SO-7881\",\n      \"customer_name\": \"Acme Health Foods\"\n    },\n    {\n      \"id\": 4822,\n      \"reference\": \"SO-7882\",\n      \"customer_name\": \"Bright Wellness Co\"\n    }\n  ],\n  \"summary\": {\n    \"order_count\": 2,\n    \"traced_order_count\": 1,\n    \"finished_good_count\": 1\n  },\n  \"affected_lots\": {\n    \"rows\": [\n      {\n        \"fifo_layer_id\": 134,\n        \"batch_number\": \"ASH-2026-RAW-0001\",\n        \"product_sku\": \"ASHWA-EXT\",\n        \"product_name\": \"Ashwagandha Extract\",\n        \"lot_type\": \"Purchased\",\n        \"supplier_id\": 4,\n        \"supplier_name\": \"Acme Botanicals\",\n        \"source_reference\": \"PO-0003\",\n        \"quantity\": 20,\n        \"order_count\": 2\n      },\n      {\n        \"fifo_layer_id\": 135,\n        \"batch_number\": \"CALM-MO-2026-0001\",\n        \"product_sku\": \"CALM-GUMMIES\",\n        \"product_name\": \"Calm Gummies\",\n        \"lot_type\": \"Manufactured\",\n        \"supplier_id\": null,\n        \"supplier_name\": null,\n        \"source_reference\": \"MO-504211\",\n        \"quantity\": 7,\n        \"order_count\": 2\n      }\n    ],\n    \"summary\": {\n      \"lot_count\": 2,\n      \"supplier_count\": 1,\n      \"order_count\": 2,\n      \"total_quantity\": 27\n    }\n  }\n}"}]},{"name":"Resolve Sales Order Numbers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/sales-order-refs?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","sales-order-refs"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. Comma-separated or array of sales-order ids.","disabled":true}]},"description":"Resolve selected order ids -> their numbers + customers via a direct whereIn (the SO list filter[id] coerces \"3,4\" to a single id and can't resolve multiple). Lets the \"trace by sales order(s)\" chips show real \"SO-…\" labels before the slower trace returns. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/sales-order-refs?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","sales-order-refs"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. Comma-separated or array of sales-order ids.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"reference\": \"SO-7881\",\n      \"customer_name\": \"Acme Health Foods\"\n    },\n    {\n      \"id\": 4822,\n      \"reference\": \"SO-7882\",\n      \"customer_name\": \"Bright Wellness Co\"\n    }\n  ]\n}"}]},{"name":"Bulk Resolve Sales Order Numbers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/resolve-sales-order-numbers","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","resolve-sales-order-numbers"]},"description":"Bulk-resolve pasted / imported sales-order NUMBERS into ids, so a recall can be seeded from a spreadsheet column or CSV instead of typing each order. Body: `numbers` (array, max 2000, each <= 64 chars). Returns `matched` (id + number + customer) and `unmatched` (numbers that matched no order). Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"numbers\": [\n    \"SO-7881\",\n    \"SO-7882\",\n    \"SO-DOES-NOT-EXIST\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/resolve-sales-order-numbers","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","resolve-sales-order-numbers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"matched\": [\n    {\n      \"id\": 4821,\n      \"reference\": \"SO-7881\",\n      \"customer_name\": \"Acme Health Foods\"\n    }\n  ],\n  \"unmatched\": [\n    \"SO-DOES-NOT-EXIST\"\n  ]\n}"}]},{"name":"List Affected Lots and Suppliers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-lots-by-sales-orders?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-lots-by-sales-orders"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids, comma-separated (`4821,4822`) or as an array. Max 500.","disabled":true}]},"description":"Recall (reverse) — the implicated lots + suppliers behind a set of sales orders: every raw-ingredient / finished-good lot that fed the orders' shipped goods, deduplicated, with supplier and a count of how many of the orders each lot touches. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nQuantities are summed across DISTINCT consumption edges, so a shared upstream ingredient consumed once by a finished good isn't double-counted across the multiple orders that finished good shipped to (finished-good shipment quantities to different orders ARE summed). Supplier-backed lots (the recall-actionable raw materials) sort first.\n\nReturns `data` (one row per implicated lot — batch, product, lot_type, supplier, source_reference, quantity, order_count) and `summary` (lot_count, supplier_count, order_count, total_quantity). 422 when no ids / over 500."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-lots-by-sales-orders?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-lots-by-sales-orders"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids, comma-separated (`4821,4822`) or as an array. Max 500.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fifo_layer_id\": 134,\n      \"batch_number\": \"ASH-2026-RAW-0001\",\n      \"product_id\": 22,\n      \"product_sku\": \"ASHWA-EXT\",\n      \"product_name\": \"Ashwagandha Extract\",\n      \"lot_type\": \"Purchased\",\n      \"supplier_id\": 4,\n      \"supplier_name\": \"Acme Botanicals\",\n      \"source_reference\": \"PO-0003\",\n      \"quantity\": 20,\n      \"order_count\": 2\n    },\n    {\n      \"fifo_layer_id\": 135,\n      \"batch_number\": \"CALM-MO-2026-0001\",\n      \"product_id\": 23,\n      \"product_sku\": \"CALM-GUMMIES\",\n      \"product_name\": \"Calm Gummies\",\n      \"lot_type\": \"Manufactured\",\n      \"supplier_id\": null,\n      \"supplier_name\": null,\n      \"source_reference\": \"MO-504211\",\n      \"quantity\": 7,\n      \"order_count\": 2\n    }\n  ],\n  \"summary\": {\n    \"lot_count\": 2,\n    \"supplier_count\": 1,\n    \"order_count\": 2,\n    \"total_quantity\": 27\n  }\n}"}]},{"name":"Export Affected Lots and Suppliers (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-lots-by-sales-orders/export?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-lots-by-sales-orders","export"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids, comma-separated (`4821,4822`) or as an array. Max 500.","disabled":true}]},"description":"Recall (reverse) — streams the implicated lots + suppliers for a set of sales orders as a CSV download for the recall paper trail. Same resolution + 422 semantics as `GET /api/manufacturing/lot-genealogy/affected-lots-by-sales-orders`. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse is a `text/csv` file download. Columns: Batch, Product SKU, Product, Type, Supplier, Source, Quantity Consumed, Affected Orders."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-lots-by-sales-orders/export?sales_order_ids=4821,4822","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-lots-by-sales-orders","export"],"query":[{"key":"sales_order_ids","value":"4821,4822","description":"Required. One or more sales-order ids, comma-separated (`4821,4822`) or as an array. Max 500.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Batch,\"Product SKU\",Product,Type,Supplier,Source,\"Quantity Consumed\",\"Affected Orders\"\nASH-2026-RAW-0001,ASHWA-EXT,\"Ashwagandha Extract\",Purchased,\"Acme Botanicals\",PO-0003,20,2"}]},{"name":"List Affected Sales Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-sales-orders?batch_number=LOT-2026-04-001","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-sales-orders"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to trace forward to its sales-order consumers.","disabled":true}]},"description":"Recall workflow — the sales orders / customers that consumed the traced batch (or a finished good produced from it). Forward trace only; backward traces (sources) have no customers. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResolves the batch the same way as `GET /api/manufacturing/lot-genealogy` (404 when nothing matches; 409 with a `candidates` array when the batch number is shared across multiple products).\n\nReturns:\n- `data` — one row per (sales order, shipped product, shipped batch), with customer name/email/company, order date, shipped-at date, the shipped product, and the aggregated quantity of the traced batch that reached that order.\n- `order_ids` — the distinct sales-order id list (use this directly as the `{ids: [...]}` selection payload for `POST /api/sales-orders/bulk-email`).\n- `summary` — `customer_count`, `order_count`, `total_quantity`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-sales-orders?batch_number=LOT-2026-04-001","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-sales-orders"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to trace forward to its sales-order consumers.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_order_id\": 4821,\n      \"sales_order_number\": \"SO-7881\",\n      \"customer_name\": \"Acme Health Foods\",\n      \"customer_email\": \"recall@acmehealth.test\",\n      \"customer_company\": \"Acme Health Foods Ltd\",\n      \"order_date\": \"2026-04-12\",\n      \"shipped_at\": \"2026-04-15\",\n      \"shipped_product_id\": 88,\n      \"shipped_product_sku\": \"VIT-C-1000\",\n      \"shipped_product_name\": \"Vitamin C 1000mg\",\n      \"shipped_batch_number\": \"LOT-2026-04-001\",\n      \"quantity\": 6\n    }\n  ],\n  \"order_ids\": [\n    4821\n  ],\n  \"summary\": {\n    \"customer_count\": 1,\n    \"order_count\": 1,\n    \"total_quantity\": 6\n  }\n}"}]},{"name":"Export Affected Sales Orders (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-sales-orders/export?batch_number=LOT-2026-04-001","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-sales-orders","export"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to export the affected sales-order / customer rows for.","disabled":true}]},"description":"Recall workflow — streams the affected sales-order / customer rows as a CSV download for the recall paper trail. Same batch resolution + 404/409 semantics as `GET /api/manufacturing/lot-genealogy/affected-sales-orders`. Authentication: requires a Bearer token (PAT).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse is a `text/csv` file download (filename `recall-affected-orders-{batch}.csv`), not JSON. Columns: Sales Order, Customer, Email, Company, Order Date, Shipped At, Product SKU, Product, Batch, Quantity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/lot-genealogy/affected-sales-orders/export?batch_number=LOT-2026-04-001","host":["{{baseUrl}}"],"path":["api","manufacturing","lot-genealogy","affected-sales-orders","export"],"query":[{"key":"batch_number","value":"LOT-2026-04-001","description":"Required. Exact batch number to export the affected sales-order / customer rows for.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"\"Sales Order\",Customer,Email,Company,\"Order Date\",\"Shipped At\",\"Product SKU\",Product,Batch,Quantity\nSO-7881,\"Acme Health Foods\",recall@acmehealth.test,\"Acme Health Foods Ltd\",2026-04-12,2026-04-15,VIT-C-1000,\"Vitamin C 1000mg\",LOT-2026-04-001,6\n"}]}]},{"name":"MRP Planning","item":[{"name":"List MRP Runs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs"]},"description":"Paginated list of MRP runs, most recent first.\nAuth: requires Bearer token.\nReturns a standard Laravel paginator (MRP run object items in data).\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"scenario_id\": null,\n      \"mode\": \"regenerative\",\n      \"status\": \"completed\",\n      \"horizon_days\": 90,\n      \"bucket_size\": \"week\",\n      \"include_capacity\": true,\n      \"include_forecast\": true,\n      \"counts\": {\n        \"planned_orders\": 128,\n        \"action_messages\": 17,\n        \"pegging\": 240,\n        \"time_phased_records\": 512\n      },\n      \"started_at\": \"2026-06-17T14:03:11.000000Z\",\n      \"completed_at\": \"2026-06-17T14:03:19.000000Z\",\n      \"runtime_ms\": 8421,\n      \"created_at\": \"2026-06-17T14:03:11.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:19.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 24\n}"}]},{"name":"Start MRP Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs"]},"description":"Create and synchronously execute a regenerative or net-change MRP run, then return the completed run.\nAuth: requires Bearer token.\nFormRequest: StartMrpRunRequest (all fields optional; controller applies defaults).\nFields: mode (in: regenerative, net_change; default regenerative), scenario_id (nullable, exists:mrp_scenarios), horizon_days (1-1095; default 90), bucket_size (in: day, week, month; default week), warehouse_ids[] (exists:warehouses), product_ids[] (exists:products), include_capacity (bool; default false), include_forecast (bool; default true).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mode\": \"regenerative\",\n  \"scenario_id\": null,\n  \"horizon_days\": 120,\n  \"bucket_size\": \"week\",\n  \"warehouse_ids\": [\n    1,\n    2\n  ],\n  \"product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"include_capacity\": true,\n  \"include_forecast\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"scenario_id\": null,\n    \"mode\": \"regenerative\",\n    \"status\": \"completed\",\n    \"horizon_days\": 120,\n    \"bucket_size\": \"week\",\n    \"include_capacity\": true,\n    \"include_forecast\": true,\n    \"counts\": {\n      \"planned_orders\": 128,\n      \"action_messages\": 17,\n      \"pegging\": 240,\n      \"time_phased_records\": 512\n    },\n    \"started_at\": \"2026-06-17T14:03:11.000000Z\",\n    \"completed_at\": \"2026-06-17T14:03:19.000000Z\",\n    \"runtime_ms\": 8421,\n    \"created_at\": \"2026-06-17T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-17T14:03:19.000000Z\"\n  },\n  \"message\": \"MRP run completed\"\n}"}]},{"name":"Get MRP Run","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Return a single MRP run by id.\nAuth: requires Bearer token.\nPath param: mrpRun = MRP run id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"scenario_id\": null,\n    \"mode\": \"regenerative\",\n    \"status\": \"completed\",\n    \"horizon_days\": 90,\n    \"bucket_size\": \"week\",\n    \"include_capacity\": true,\n    \"include_forecast\": true,\n    \"counts\": {\n      \"planned_orders\": 128,\n      \"action_messages\": 17,\n      \"pegging\": 240,\n      \"time_phased_records\": 512\n    },\n    \"started_at\": \"2026-06-17T14:03:11.000000Z\",\n    \"completed_at\": \"2026-06-17T14:03:19.000000Z\",\n    \"runtime_ms\": 8421,\n    \"created_at\": \"2026-06-17T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-17T14:03:19.000000Z\"\n  }\n}"}]},{"name":"List Run Planned Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/planned-orders","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","planned-orders"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Paginated planned orders for a run, ordered by low_level_code then release_date. Eager-loads product, warehouse, supplier, bom.\nAuth: requires Bearer token.\nFilters: filter[supply_type] (make|buy|transfer), filter[state] (planned|firm|released), filter[warehouse_id] (int).\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/planned-orders","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","planned-orders"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 901,\n      \"mrp_run_id\": 42,\n      \"product_id\": 101,\n      \"product\": {\n        \"id\": 101,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main DC\"\n      },\n      \"supply_type\": \"make\",\n      \"state\": \"planned\",\n      \"quantity\": 500,\n      \"net_requirement\": 480,\n      \"due_date\": \"2026-07-15\",\n      \"release_date\": \"2026-07-01\",\n      \"bucket_start\": \"2026-06-29\",\n      \"lead_time_days\": 14,\n      \"lot_sizing_rule\": \"lot_for_lot\",\n      \"supplier_id\": null,\n      \"supplier\": null,\n      \"bom_id\": 55,\n      \"bom\": {\n        \"id\": 55,\n        \"name\": \"Red Widget BOM v3\"\n      },\n      \"source_warehouse_id\": null,\n      \"low_level_code\": 1,\n      \"accepted\": false,\n      \"firm_quantity\": null,\n      \"firm_due_date\": null,\n      \"released_order_type\": null,\n      \"released_order_id\": null,\n      \"created_at\": \"2026-06-17T14:03:18.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:18.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 128\n}"}]},{"name":"Get Item Time-Phased Grid","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/items/{product}/time-phased","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","items",":product","time-phased"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."},{"key":"product","value":"1","description":"The product ID."}]},"description":"Time-phased MRP grid (gross-to-net buckets) for one product within a run, optionally scoped to a warehouse. Plain array, not a Resource.\nAuth: requires Bearer token.\nPath params: mrpRun = run id, product = product id.\nOptional query: warehouse_id to restrict buckets to one warehouse.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/items/{product}/time-phased","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","items",":product","time-phased"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."},{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 101,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget\"\n    },\n    \"buckets\": [\n      {\n        \"warehouse_id\": 2,\n        \"bucket_start\": \"2026-06-22\",\n        \"bucket_end\": \"2026-06-28\",\n        \"gross_requirements\": 120,\n        \"scheduled_receipts\": 0,\n        \"projected_available\": 80,\n        \"net_requirements\": 40,\n        \"planned_order_receipts\": 40,\n        \"planned_order_releases\": 0\n      },\n      {\n        \"warehouse_id\": 2,\n        \"bucket_start\": \"2026-06-29\",\n        \"bucket_end\": \"2026-07-05\",\n        \"gross_requirements\": 200,\n        \"scheduled_receipts\": 0,\n        \"projected_available\": 0,\n        \"net_requirements\": 160,\n        \"planned_order_receipts\": 160,\n        \"planned_order_releases\": 500\n      }\n    ]\n  }\n}"}]},{"name":"List Run Action Messages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/action-messages","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","action-messages"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Paginated action/exception messages for a run, ordered by severity priority then id. Eager-loads product, warehouse.\nAuth: requires Bearer token.\nFilters: filter[type] (enum), filter[severity] (emergency|exception|attention), filter[message_class] (action|exception), filter[status] (open|accepted|dismissed).\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/action-messages","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","action-messages"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"mrp_run_id\": 42,\n      \"product_id\": 101,\n      \"product\": {\n        \"id\": 101,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main DC\"\n      },\n      \"message_class\": \"action\",\n      \"type\": \"reschedule_in\",\n      \"severity\": \"exception\",\n      \"order_type\": \"purchase_order\",\n      \"order_id\": 7788,\n      \"current_due_date\": \"2026-07-20\",\n      \"current_qty\": 500,\n      \"recommended_due_date\": \"2026-07-12\",\n      \"recommended_qty\": 500,\n      \"days_late\": 8,\n      \"peg_id\": 3120,\n      \"status\": \"open\",\n      \"created_at\": \"2026-06-17T14:03:19.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:19.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 17\n}"}]},{"name":"Get Action Message Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/action-messages/counts","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","action-messages","counts"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Grouped counts of action messages for the run, bucketed by type and by severity. Plain array.\nAuth: requires Bearer token.\nPath param: mrpRun = run id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/action-messages/counts","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","action-messages","counts"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"by_type\": {\n      \"release\": 6,\n      \"reschedule_in\": 4,\n      \"reschedule_out\": 2,\n      \"past_due\": 3,\n      \"shortage\": 2\n    },\n    \"by_severity\": {\n      \"emergency\": 2,\n      \"exception\": 7,\n      \"attention\": 8\n    }\n  }\n}"}]},{"name":"Get Planned Order Pegging","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/planned-orders/{plannedOrder}/pegging","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","planned-orders",":plannedOrder","pegging"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."},{"key":"plannedOrder","value":"1","description":"The planned order ID."}]},"description":"Bottom-up peg trace for a planned order: walks the parent chain from the supply order up to the originating independent demand. Plain array.\nAuth: requires Bearer token.\nPath params: mrpRun = run id, plannedOrder = planned order id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/planned-orders/{plannedOrder}/pegging","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","planned-orders",":plannedOrder","pegging"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."},{"key":"plannedOrder","value":"1","description":"The planned order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"planned_order_id\": 901,\n    \"trace\": [\n      {\n        \"id\": 3120,\n        \"level\": 2,\n        \"quantity\": 500,\n        \"demand_type\": \"dependent\",\n        \"demand_ref\": \"PO-901\",\n        \"demand_product_id\": 205,\n        \"demand_product\": {\n          \"id\": 205,\n          \"sku\": \"SUBASSY-A\",\n          \"name\": \"Sub-assembly A\"\n        },\n        \"supply_planned_order_id\": 901,\n        \"supply_order_type\": \"planned\",\n        \"parent_planned_order_id\": 880\n      },\n      {\n        \"id\": 3090,\n        \"level\": 1,\n        \"quantity\": 500,\n        \"demand_type\": \"sales_order_line\",\n        \"demand_ref\": \"SO-10042-1\",\n        \"demand_product_id\": 101,\n        \"demand_product\": {\n          \"id\": 101,\n          \"sku\": \"WIDGET-RED\",\n          \"name\": \"Red Widget\"\n        },\n        \"supply_planned_order_id\": 880,\n        \"supply_order_type\": \"planned\",\n        \"parent_planned_order_id\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Capacity Load Profile","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/load-profile","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","load-profile"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Detailed CRP load profile from BOM routings: required vs rated capacity per work center per time bucket. Plain array.\nAuth: requires Bearer token.\nPath param: mrpRun = run id.\nStatus per bucket: under (<50% util), ok, over (required > rated or util > 100%).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/load-profile","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","load-profile"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"work_center_id\": 11,\n      \"work_center_name\": \"Assembly Line 1\",\n      \"buckets\": [\n        {\n          \"bucket_index\": 0,\n          \"bucket_start\": \"2026-06-18\",\n          \"required_hours\": 42.5,\n          \"rated_capacity\": 40,\n          \"utilization_pct\": 106.25,\n          \"status\": \"over\"\n        },\n        {\n          \"bucket_index\": 1,\n          \"bucket_start\": \"2026-06-25\",\n          \"required_hours\": 18,\n          \"rated_capacity\": 40,\n          \"utilization_pct\": 45,\n          \"status\": \"under\"\n        },\n        {\n          \"bucket_index\": 2,\n          \"bucket_start\": \"2026-07-02\",\n          \"required_hours\": 30,\n          \"rated_capacity\": 40,\n          \"utilization_pct\": 75,\n          \"status\": \"ok\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Capacity Heatmap","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/heatmap","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","heatmap"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"CRP data reshaped into a heatmap grid (work centers x buckets) with a color band per cell. Plain object.\nAuth: requires Bearer token.\nPath param: mrpRun = run id.\nColors: under -> blue, over -> orange, ok -> green.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/heatmap","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","heatmap"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"buckets\": [\n      {\n        \"bucket_index\": 0,\n        \"bucket_start\": \"2026-06-18\"\n      },\n      {\n        \"bucket_index\": 1,\n        \"bucket_start\": \"2026-06-25\"\n      },\n      {\n        \"bucket_index\": 2,\n        \"bucket_start\": \"2026-07-02\"\n      }\n    ],\n    \"rows\": [\n      {\n        \"work_center_id\": 11,\n        \"work_center_name\": \"Assembly Line 1\",\n        \"cells\": [\n          {\n            \"bucket_index\": 0,\n            \"required_hours\": 42.5,\n            \"rated_capacity\": 40,\n            \"utilization_pct\": 106.25,\n            \"status\": \"over\",\n            \"color\": \"orange\"\n          },\n          {\n            \"bucket_index\": 1,\n            \"required_hours\": 18,\n            \"rated_capacity\": 40,\n            \"utilization_pct\": 45,\n            \"status\": \"under\",\n            \"color\": \"blue\"\n          },\n          {\n            \"bucket_index\": 2,\n            \"required_hours\": 30,\n            \"rated_capacity\": 40,\n            \"utilization_pct\": 75,\n            \"status\": \"ok\",\n            \"color\": \"green\"\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Get Rough-Cut Capacity Plan","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/rough-cut","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","rough-cut"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]},"description":"Rough-Cut Capacity Planning (RCCP) using the bill of resources (is_key_resource rows): required hours time-phased per key work center vs rated capacity. Plain array (same shape as load-profile).\nAuth: requires Bearer token.\nPath param: mrpRun = run id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/runs/{mrpRun}/capacity/rough-cut","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","runs",":mrpRun","capacity","rough-cut"],"variable":[{"key":"mrpRun","value":"1","description":"The mrp run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"work_center_id\": 11,\n      \"work_center_name\": \"Assembly Line 1\",\n      \"buckets\": [\n        {\n          \"bucket_index\": 0,\n          \"bucket_start\": \"2026-06-18\",\n          \"required_hours\": 50,\n          \"rated_capacity\": 40,\n          \"utilization_pct\": 125,\n          \"status\": \"over\"\n        },\n        {\n          \"bucket_index\": 1,\n          \"bucket_start\": \"2026-06-25\",\n          \"required_hours\": 20,\n          \"rated_capacity\": 40,\n          \"utilization_pct\": 50,\n          \"status\": \"ok\"\n        }\n      ]\n    },\n    {\n      \"work_center_id\": 12,\n      \"work_center_name\": \"Paint Booth\",\n      \"buckets\": [\n        {\n          \"bucket_index\": 0,\n          \"bucket_start\": \"2026-06-18\",\n          \"required_hours\": 12,\n          \"rated_capacity\": 32,\n          \"utilization_pct\": 37.5,\n          \"status\": \"under\"\n        },\n        {\n          \"bucket_index\": 1,\n          \"bucket_start\": \"2026-06-25\",\n          \"required_hours\": 0,\n          \"rated_capacity\": 32,\n          \"utilization_pct\": 0,\n          \"status\": \"under\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Firm Planned Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/firm","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","firm"]},"description":"Firm one or more planned orders (planned -> firm), optionally overriding quantity and/or due date.\nAuth: requires Bearer token.\nFormRequest: FirmPlannedOrderRequest.\nFields: ids[] (required, exists:mrp_planned_orders), firm_quantity (nullable, numeric, gt:0), firm_due_date (nullable, date).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ],\n  \"firm_quantity\": 500,\n  \"firm_due_date\": \"2026-07-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/firm","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","firm"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"mrp_run_id\": 42,\n      \"product_id\": 9001,\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"WIDGET-A\",\n        \"name\": \"Blue Widget Assembly\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Distribution Center\"\n      },\n      \"supply_type\": \"make\",\n      \"state\": \"firm\",\n      \"quantity\": 500,\n      \"net_requirement\": 480,\n      \"due_date\": \"2026-07-15\",\n      \"release_date\": \"2026-07-01\",\n      \"bucket_start\": \"2026-06-29\",\n      \"lead_time_days\": 14,\n      \"lot_sizing_rule\": \"lot_for_lot\",\n      \"supplier_id\": null,\n      \"supplier\": null,\n      \"bom_id\": 55,\n      \"bom\": {\n        \"id\": 55,\n        \"name\": \"Blue Widget Assembly BOM v3\"\n      },\n      \"source_warehouse_id\": null,\n      \"low_level_code\": 1,\n      \"accepted\": false,\n      \"firm_quantity\": 500,\n      \"firm_due_date\": \"2026-07-15\",\n      \"released_order_type\": null,\n      \"released_order_id\": null,\n      \"created_at\": \"2026-06-17T14:03:18.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:18.000000Z\"\n    }\n  ],\n  \"message\": \"1 planned orders firmed\"\n}"}]},{"name":"Unfirm Planned Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/unfirm","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","unfirm"]},"description":"Revert firmed planned orders back to planned (clears firm overrides).\nAuth: requires Bearer token.\nFormRequest: BulkPlannedOrderRequest.\nFields: ids[] (required, exists:mrp_planned_orders).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/unfirm","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","unfirm"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"mrp_run_id\": 42,\n      \"product_id\": 9001,\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"WIDGET-A\",\n        \"name\": \"Blue Widget Assembly\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Distribution Center\"\n      },\n      \"supply_type\": \"make\",\n      \"state\": \"planned\",\n      \"quantity\": 500,\n      \"net_requirement\": 480,\n      \"due_date\": \"2026-07-15\",\n      \"release_date\": \"2026-07-01\",\n      \"bucket_start\": \"2026-06-29\",\n      \"lead_time_days\": 14,\n      \"lot_sizing_rule\": \"lot_for_lot\",\n      \"supplier_id\": null,\n      \"supplier\": null,\n      \"bom_id\": 55,\n      \"bom\": {\n        \"id\": 55,\n        \"name\": \"Blue Widget Assembly BOM v3\"\n      },\n      \"source_warehouse_id\": null,\n      \"low_level_code\": 1,\n      \"accepted\": false,\n      \"firm_quantity\": null,\n      \"firm_due_date\": null,\n      \"released_order_type\": null,\n      \"released_order_id\": null,\n      \"created_at\": \"2026-06-17T14:03:18.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:18.000000Z\"\n    }\n  ],\n  \"message\": \"1 planned orders unfirmed\"\n}"}]},{"name":"Accept Planned Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/accept","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","accept"]},"description":"Mark planned orders as accepted (accepted = true).\nAuth: requires Bearer token.\nFormRequest: BulkPlannedOrderRequest.\nFields: ids[] (required, exists:mrp_planned_orders).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/accept","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","accept"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"mrp_run_id\": 42,\n      \"product_id\": 9001,\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"WIDGET-A\",\n        \"name\": \"Blue Widget Assembly\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Distribution Center\"\n      },\n      \"supply_type\": \"buy\",\n      \"state\": \"planned\",\n      \"quantity\": 1000,\n      \"net_requirement\": 1000,\n      \"due_date\": \"2026-07-15\",\n      \"release_date\": \"2026-07-01\",\n      \"bucket_start\": \"2026-06-29\",\n      \"lead_time_days\": 14,\n      \"lot_sizing_rule\": \"fixed_order_qty\",\n      \"supplier_id\": 7,\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Components Ltd\"\n      },\n      \"bom_id\": null,\n      \"bom\": null,\n      \"source_warehouse_id\": null,\n      \"low_level_code\": 0,\n      \"accepted\": true,\n      \"firm_quantity\": null,\n      \"firm_due_date\": null,\n      \"released_order_type\": null,\n      \"released_order_id\": null,\n      \"created_at\": \"2026-06-17T14:03:18.000000Z\",\n      \"updated_at\": \"2026-06-17T14:03:18.000000Z\"\n    }\n  ],\n  \"message\": \"1 planned orders accepted\"\n}"}]},{"name":"Dismiss Planned Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","dismiss"]},"description":"Dismiss (delete) the given planned orders from the run. Returns a count, not a resource collection.\nAuth: requires Bearer token.\nFormRequest: BulkPlannedOrderRequest.\nFields: ids[] (required, exists:mrp_planned_orders).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    104,\n    105\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","dismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dismissed\": 2\n  },\n  \"message\": \"2 planned orders dismissed\"\n}"}]},{"name":"Release Planned Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/release","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","release"]},"description":"Release planned orders into real supply documents: make -> draft Manufacturing Orders, buy -> one Purchase Order per supplier, transfer -> Warehouse Transfers. Already-released and buy-without-supplier orders are skipped. Returns created document IDs grouped by type plus a released count.\nAuth: requires Bearer token.\nFormRequest: ReleasePlannedOrderRequest.\nFields: ids[] (required, exists:mrp_planned_orders).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103,\n    106\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/release","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders","release"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"manufacturing_orders\": [\n      3201\n    ],\n    \"purchase_orders\": [\n      880\n    ],\n    \"warehouse_transfers\": [\n      145\n    ],\n    \"released\": 4\n  },\n  \"message\": \"4 planned orders released\"\n}"}]},{"name":"Update Planned Order","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/{plannedOrder}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders",":plannedOrder"],"variable":[{"key":"plannedOrder","value":"1","description":"The planned order ID."}]},"description":"Update a single planned order's quantity, due date, supplier, and/or supply type. All fields optional - send only what changes.\nAuth: requires Bearer token.\nPath param: plannedOrder = planned order id.\nFormRequest: UpdateMrpPlannedOrderRequest.\nFields: quantity (nullable, numeric, gt:0), due_date (nullable, date), supplier_id (nullable, exists:suppliers), supply_type (nullable, in: make, buy, transfer).\nReturns 422 with {message} when the manager rejects the change (e.g. changing supply type of a released order).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"quantity\": 750,\n  \"due_date\": \"2026-08-01\",\n  \"supplier_id\": 7,\n  \"supply_type\": \"buy\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planned-orders/{plannedOrder}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planned-orders",":plannedOrder"],"variable":[{"key":"plannedOrder","value":"1","description":"The planned order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"mrp_run_id\": 42,\n    \"product_id\": 9001,\n    \"product\": {\n      \"id\": 9001,\n      \"sku\": \"WIDGET-A\",\n      \"name\": \"Blue Widget Assembly\"\n    },\n    \"warehouse_id\": 3,\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Distribution Center\"\n    },\n    \"supply_type\": \"buy\",\n    \"state\": \"planned\",\n    \"quantity\": 750,\n    \"net_requirement\": 480,\n    \"due_date\": \"2026-08-01\",\n    \"release_date\": \"2026-07-01\",\n    \"bucket_start\": \"2026-06-29\",\n    \"lead_time_days\": 25,\n    \"lot_sizing_rule\": \"fixed_order_qty\",\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\"\n    },\n    \"bom_id\": null,\n    \"bom\": null,\n    \"source_warehouse_id\": null,\n    \"low_level_code\": 1,\n    \"accepted\": false,\n    \"firm_quantity\": null,\n    \"firm_due_date\": null,\n    \"released_order_type\": null,\n    \"released_order_id\": null,\n    \"created_at\": \"2026-06-17T14:03:18.000000Z\",\n    \"updated_at\": \"2026-06-17T14:03:18.000000Z\"\n  }\n}"}]},{"name":"List Planning Policies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies"]},"description":"Paginated list of item planning policies (item-level defaults and warehouse overrides), product and warehouse eager-loaded, ordered by id desc.\nAuth: requires Bearer token.\nFilters: filter[planning_method], filter[procurement_type], filter[warehouse_id], search (LIKE on product sku/name).\nNote: page size is fixed at 10 - per_page is accepted but ignored for this endpoint.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"product_id\": 1001,\n      \"product\": {\n        \"id\": 1001,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_warehouse_override\": true,\n      \"planning_method\": \"mrp\",\n      \"procurement_type\": \"make\",\n      \"lot_sizing_rule\": \"fixed_order_qty\",\n      \"order_minimum\": 10,\n      \"order_multiple\": 5,\n      \"order_maximum\": 1000,\n      \"fixed_order_quantity\": 100,\n      \"period_order_days\": 7,\n      \"days_of_supply\": null,\n      \"eoq_ordering_cost\": null,\n      \"eoq_holding_cost_pct\": null,\n      \"safety_stock\": 25,\n      \"safety_lead_time_days\": 2,\n      \"reorder_point\": 50,\n      \"reorder_up_to_level\": 200,\n      \"lead_time_source\": \"manual\",\n      \"lead_time_days\": 14,\n      \"demand_time_fence_days\": 7,\n      \"planning_time_fence_days\": 30,\n      \"release_time_fence_days\": 3,\n      \"is_phantom_planning\": false,\n      \"make_to_order\": false,\n      \"planning_calendar_id\": null,\n      \"low_level_code\": 0,\n      \"dampener_days\": 1,\n      \"dampener_qty\": 5,\n      \"dampener_pct\": 10,\n      \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n      \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 37\n}"}]},{"name":"Get Planning Policy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/{product}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies",":product"],"variable":[{"key":"product","value":"1","description":"The product ID."}]},"description":"Resolve the effective item-level policy for a product. Returns data: null when no policy exists.\nAuth: requires Bearer token.\nPath param: product = product id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/{product}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies",":product"],"variable":[{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"product_id\": 1001,\n    \"product\": {\n      \"id\": 1001,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget\"\n    },\n    \"warehouse_id\": null,\n    \"warehouse\": null,\n    \"is_warehouse_override\": false,\n    \"planning_method\": \"reorder_point\",\n    \"procurement_type\": \"buy\",\n    \"lot_sizing_rule\": \"min_max\",\n    \"order_minimum\": 10,\n    \"order_multiple\": null,\n    \"order_maximum\": null,\n    \"fixed_order_quantity\": null,\n    \"period_order_days\": null,\n    \"days_of_supply\": null,\n    \"eoq_ordering_cost\": null,\n    \"eoq_holding_cost_pct\": null,\n    \"safety_stock\": 25,\n    \"safety_lead_time_days\": 0,\n    \"reorder_point\": 50,\n    \"reorder_up_to_level\": 200,\n    \"lead_time_source\": \"supplier\",\n    \"lead_time_days\": 14,\n    \"demand_time_fence_days\": 0,\n    \"planning_time_fence_days\": 0,\n    \"release_time_fence_days\": 0,\n    \"is_phantom_planning\": false,\n    \"make_to_order\": false,\n    \"planning_calendar_id\": null,\n    \"low_level_code\": 0,\n    \"dampener_days\": null,\n    \"dampener_qty\": null,\n    \"dampener_pct\": null,\n    \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n    \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n  }\n}"}]},{"name":"Upsert Planning Policy","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/{product}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies",":product"],"variable":[{"key":"product","value":"1","description":"The product ID."}]},"description":"Create or update the planning policy for a product (and optional warehouse scope).\nAuth: requires Bearer token.\nPath param: product = product id.\nBody fields (UpsertItemPlanningPolicyRequest / shared policyAttributeRules): warehouse_id (nullable, exists:warehouses; null = item-level default), planning_method (required, in: mrp, reorder_point, mps, min_max, none), procurement_type (nullable, in: make, buy, transfer, make_or_buy), lot_sizing_rule (required, in: lot_for_lot, fixed_order_qty, min_max, eoq, period_order_qty, days_of_supply, fixed_period), lead_time_source (nullable, in: manual, bom, supplier, computed), order_minimum, order_multiple, order_maximum, fixed_order_quantity, days_of_supply, eoq_ordering_cost, eoq_holding_cost_pct, safety_stock, reorder_point, reorder_up_to_level, dampener_qty, dampener_pct (numeric, nullable), period_order_days, safety_lead_time_days, lead_time_days, demand_time_fence_days, planning_time_fence_days, release_time_fence_days, low_level_code, dampener_days (integer, nullable), planning_calendar_id (nullable, exists:planning_calendars), is_phantom_planning, make_to_order (boolean, nullable).\nReturns 422 {message} on manager coherence violations (e.g. fixed_order_quantity required when lot_sizing_rule=fixed_order_qty; eoq costs required when lot_sizing_rule=eoq; reorder_point required when planning_method is min_max or reorder_point).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"planning_method\": \"mrp\",\n  \"procurement_type\": \"make\",\n  \"lot_sizing_rule\": \"fixed_order_qty\",\n  \"lead_time_source\": \"manual\",\n  \"order_minimum\": 10,\n  \"order_multiple\": 5,\n  \"order_maximum\": 1000,\n  \"fixed_order_quantity\": 100,\n  \"days_of_supply\": null,\n  \"eoq_ordering_cost\": null,\n  \"eoq_holding_cost_pct\": null,\n  \"safety_stock\": 25,\n  \"reorder_point\": 50,\n  \"reorder_up_to_level\": 200,\n  \"dampener_qty\": 5,\n  \"dampener_pct\": 10,\n  \"period_order_days\": 7,\n  \"safety_lead_time_days\": 2,\n  \"lead_time_days\": 14,\n  \"demand_time_fence_days\": 7,\n  \"planning_time_fence_days\": 30,\n  \"release_time_fence_days\": 3,\n  \"low_level_code\": 0,\n  \"dampener_days\": 1,\n  \"planning_calendar_id\": null,\n  \"is_phantom_planning\": false,\n  \"make_to_order\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/{product}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies",":product"],"variable":[{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"product_id\": 1001,\n    \"product\": {\n      \"id\": 1001,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget\"\n    },\n    \"warehouse_id\": 3,\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"is_warehouse_override\": true,\n    \"planning_method\": \"mrp\",\n    \"procurement_type\": \"make\",\n    \"lot_sizing_rule\": \"fixed_order_qty\",\n    \"order_minimum\": 10,\n    \"order_multiple\": 5,\n    \"order_maximum\": 1000,\n    \"fixed_order_quantity\": 100,\n    \"period_order_days\": 7,\n    \"days_of_supply\": null,\n    \"eoq_ordering_cost\": null,\n    \"eoq_holding_cost_pct\": null,\n    \"safety_stock\": 25,\n    \"safety_lead_time_days\": 2,\n    \"reorder_point\": 50,\n    \"reorder_up_to_level\": 200,\n    \"lead_time_source\": \"manual\",\n    \"lead_time_days\": 14,\n    \"demand_time_fence_days\": 7,\n    \"planning_time_fence_days\": 30,\n    \"release_time_fence_days\": 3,\n    \"is_phantom_planning\": false,\n    \"make_to_order\": false,\n    \"planning_calendar_id\": null,\n    \"low_level_code\": 0,\n    \"dampener_days\": 1,\n    \"dampener_qty\": 5,\n    \"dampener_pct\": 10,\n    \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n    \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n  }\n}"}]},{"name":"Bulk Apply Planning Policy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/bulk-apply","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies","bulk-apply"]},"description":"Apply one identical set of policy attributes to many products at once.\nAuth: requires Bearer token.\nFormRequest: BulkApplyPlanningPolicyRequest.\nFields: product_ids[] (required, min:1, exists:products), warehouse_id (nullable, exists:warehouses), plus the shared policyAttributeRules() (planning_method and lot_sizing_rule required; rest as in Upsert Planning Policy).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    1001,\n    1002,\n    1003\n  ],\n  \"warehouse_id\": 3,\n  \"planning_method\": \"reorder_point\",\n  \"procurement_type\": \"buy\",\n  \"lot_sizing_rule\": \"min_max\",\n  \"lead_time_source\": \"supplier\",\n  \"order_minimum\": 10,\n  \"order_multiple\": null,\n  \"order_maximum\": null,\n  \"fixed_order_quantity\": null,\n  \"days_of_supply\": null,\n  \"eoq_ordering_cost\": null,\n  \"eoq_holding_cost_pct\": null,\n  \"safety_stock\": 25,\n  \"reorder_point\": 50,\n  \"reorder_up_to_level\": 200,\n  \"dampener_qty\": null,\n  \"dampener_pct\": null,\n  \"period_order_days\": null,\n  \"safety_lead_time_days\": 2,\n  \"lead_time_days\": 14,\n  \"demand_time_fence_days\": 0,\n  \"planning_time_fence_days\": 0,\n  \"release_time_fence_days\": 0,\n  \"low_level_code\": 0,\n  \"dampener_days\": null,\n  \"planning_calendar_id\": null,\n  \"is_phantom_planning\": false,\n  \"make_to_order\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-policies/bulk-apply","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-policies","bulk-apply"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"product_id\": 1001,\n      \"product\": {\n        \"id\": 1001,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_warehouse_override\": true,\n      \"planning_method\": \"reorder_point\",\n      \"procurement_type\": \"buy\",\n      \"lot_sizing_rule\": \"min_max\",\n      \"order_minimum\": 10,\n      \"order_multiple\": null,\n      \"order_maximum\": null,\n      \"fixed_order_quantity\": null,\n      \"period_order_days\": null,\n      \"days_of_supply\": null,\n      \"eoq_ordering_cost\": null,\n      \"eoq_holding_cost_pct\": null,\n      \"safety_stock\": 25,\n      \"safety_lead_time_days\": 2,\n      \"reorder_point\": 50,\n      \"reorder_up_to_level\": 200,\n      \"lead_time_source\": \"supplier\",\n      \"lead_time_days\": 14,\n      \"demand_time_fence_days\": 0,\n      \"planning_time_fence_days\": 0,\n      \"release_time_fence_days\": 0,\n      \"is_phantom_planning\": false,\n      \"make_to_order\": false,\n      \"planning_calendar_id\": null,\n      \"low_level_code\": 0,\n      \"dampener_days\": null,\n      \"dampener_qty\": null,\n      \"dampener_pct\": null,\n      \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n      \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n    },\n    {\n      \"id\": 43,\n      \"product_id\": 1002,\n      \"product\": {\n        \"id\": 1002,\n        \"sku\": \"WIDGET-BLUE\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"is_warehouse_override\": true,\n      \"planning_method\": \"reorder_point\",\n      \"procurement_type\": \"buy\",\n      \"lot_sizing_rule\": \"min_max\",\n      \"order_minimum\": 10,\n      \"order_multiple\": null,\n      \"order_maximum\": null,\n      \"fixed_order_quantity\": null,\n      \"period_order_days\": null,\n      \"days_of_supply\": null,\n      \"eoq_ordering_cost\": null,\n      \"eoq_holding_cost_pct\": null,\n      \"safety_stock\": 25,\n      \"safety_lead_time_days\": 2,\n      \"reorder_point\": 50,\n      \"reorder_up_to_level\": 200,\n      \"lead_time_source\": \"supplier\",\n      \"lead_time_days\": 14,\n      \"demand_time_fence_days\": 0,\n      \"planning_time_fence_days\": 0,\n      \"release_time_fence_days\": 0,\n      \"is_phantom_planning\": false,\n      \"make_to_order\": false,\n      \"planning_calendar_id\": null,\n      \"low_level_code\": 0,\n      \"dampener_days\": null,\n      \"dampener_qty\": null,\n      \"dampener_pct\": null,\n      \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n      \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n    }\n  ],\n  \"message\": \"3 policies updated\"\n}"}]},{"name":"Accept Action Messages","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/action-messages/accept","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","action-messages","accept"]},"description":"Accept one or more MRP action messages (planner agrees with the recommendation). Returns a count.\nAuth: requires Bearer token.\nFormRequest: BulkActionMessageRequest.\nFields: ids[] (required, min:1, exists:mrp_action_messages).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/action-messages/accept","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","action-messages","accept"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"accepted\": 3\n  },\n  \"message\": \"3 action messages accepted\"\n}"}]},{"name":"Dismiss Action Messages","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/action-messages/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","action-messages","dismiss"]},"description":"Dismiss one or more MRP action messages (planner rejects/ignores the recommendation). Returns a count.\nAuth: requires Bearer token.\nFormRequest: BulkActionMessageRequest.\nFields: ids[] (required, min:1, exists:mrp_action_messages).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    504,\n    505\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/action-messages/dismiss","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","action-messages","dismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"dismissed\": 2\n  },\n  \"message\": \"2 action messages dismissed\"\n}"}]},{"name":"List MPS Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps"]},"description":"Paginated list of Master Production Schedule entries (time-phased independent demand), product and warehouse eager-loaded.\nAuth: requires Bearer token.\nPagination defaults: per_page=10 (honored).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"product_id\": 1001,\n      \"product\": {\n        \"id\": 1001,\n        \"sku\": \"WIDGET-RED\",\n        \"name\": \"Red Widget\"\n      },\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"bucket_start\": \"2026-06-22\",\n      \"quantity\": 250,\n      \"source\": \"manual\",\n      \"created_at\": \"2026-06-17T14:22:05.000000Z\",\n      \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 14\n}"}]},{"name":"Upsert MPS Entry","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps"]},"description":"Create or update one MPS entry keyed on (product_id, warehouse_id, bucket_start).\nAuth: requires Bearer token.\nFormRequest: UpsertMpsEntryRequest.\nFields: product_id (required, exists:products), warehouse_id (required, exists:warehouses), bucket_start (required, date), quantity (required, numeric, min:0), source (sometimes, in: manual, forecast, drp; defaults manual).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 1001,\n  \"warehouse_id\": 3,\n  \"bucket_start\": \"2026-06-22\",\n  \"quantity\": 250,\n  \"source\": \"manual\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"product_id\": 1001,\n    \"warehouse_id\": 3,\n    \"bucket_start\": \"2026-06-22\",\n    \"quantity\": 250,\n    \"source\": \"manual\",\n    \"created_at\": \"2026-06-18T09:10:41.000000Z\",\n    \"updated_at\": \"2026-06-18T09:10:41.000000Z\"\n  },\n  \"message\": \"MPS entry saved\"\n}"}]},{"name":"Get MPS Grid","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps/grid","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps","grid"]},"description":"Per-product, per-bucket MPS grid. Plain array. Each cell exposes mps_qty plus forecast and customer_orders placeholders.\nAuth: requires Bearer token.\nQuery: product_ids[] (grid rows; default none), warehouse_id (scope grid to one warehouse).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps/grid","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps","grid"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouse_id\": 3,\n    \"products\": [\n      {\n        \"product_id\": 1001,\n        \"buckets\": [\n          {\n            \"bucket_start\": \"2026-06-22\",\n            \"forecast\": 0,\n            \"customer_orders\": 0,\n            \"mps_qty\": 250\n          },\n          {\n            \"bucket_start\": \"2026-06-29\",\n            \"forecast\": 0,\n            \"customer_orders\": 0,\n            \"mps_qty\": 300\n          }\n        ]\n      },\n      {\n        \"product_id\": 1002,\n        \"buckets\": []\n      }\n    ]\n  }\n}"}]},{"name":"Delete MPS Entry","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps/{mpsEntry}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps",":mpsEntry"],"variable":[{"key":"mpsEntry","value":"1","description":"The mps entry ID."}]},"description":"Delete one MPS entry by id. Returns 204 No Content.\nAuth: requires Bearer token.\nPath param: mpsEntry = MPS entry id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/mps/{mpsEntry}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","mps",":mpsEntry"],"variable":[{"key":"mpsEntry","value":"1","description":"The mps entry ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Check Available-to-Promise (ATP)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/atp","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","atp"]},"description":"Compute Available-To-Promise quantity for a product at a warehouse (on-hand + inbound + in-transit; excludes forecast). Plain array.\nAuth: requires Bearer token.\nFormRequest: AtpCheckRequest.\nFields: product_id (required, exists:products), warehouse_id (required, exists:warehouses), method (in: discrete, cumulative_no_lookahead, cumulative_lookahead; default cumulative_lookahead).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 1001,\n  \"warehouse_id\": 3,\n  \"method\": \"cumulative_lookahead\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/atp","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","atp"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_id\": 1001,\n    \"warehouse_id\": 3,\n    \"method\": \"cumulative_lookahead\",\n    \"atp_quantity\": 480,\n    \"detail\": {\n      \"available\": 300,\n      \"inbound\": 150,\n      \"in_transit\": 30\n    }\n  }\n}"}]},{"name":"Check Capable-to-Promise (CTP)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/ctp","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","ctp"]},"description":"Capable-To-Promise: determine how much of a requested quantity can be promised - directly from ATP, or by exploding the active BOM and checking component availability for the shortfall. Plain array.\nAuth: requires Bearer token.\nFormRequest: CtpCheckRequest.\nFields: product_id (required, exists:products), warehouse_id (required, exists:warehouses), quantity (required, numeric, gt:0).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 1001,\n  \"warehouse_id\": 3,\n  \"quantity\": 600\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/ctp","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","ctp"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_id\": 1001,\n    \"requested_quantity\": 600,\n    \"promisable_quantity\": 600,\n    \"can_promise\": true,\n    \"atp_quantity\": 720,\n    \"buildable_quantity\": 0,\n    \"limiting_components\": []\n  }\n}"}]},{"name":"List Distribution Edges","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network"]},"description":"Paginated distribution-network edges (warehouse-to-warehouse replenishment links), ordered by priority then id. Source/destination warehouses eager-loaded.\nAuth: requires Bearer token.\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"source_warehouse_id\": 10,\n      \"source_warehouse\": {\n        \"id\": 10,\n        \"name\": \"Main DC\"\n      },\n      \"destination_warehouse_id\": 22,\n      \"destination_warehouse\": {\n        \"id\": 22,\n        \"name\": \"West Coast Store\"\n      },\n      \"transfer_lead_time_days\": 3,\n      \"priority\": 1,\n      \"created_at\": \"2026-06-01T14:20:05.000000Z\",\n      \"updated_at\": \"2026-06-10T09:11:42.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Distribution Edge","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network"]},"description":"Create a distribution edge. Self-edges and cycles are rejected with 422 {message}.\nAuth: requires Bearer token.\nFormRequest: UpsertDistributionNetworkRequest.\nFields: source_warehouse_id (required, exists:warehouses), destination_warehouse_id (required, exists:warehouses, different:source), transfer_lead_time_days (nullable, integer, min:0), priority (nullable, integer).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"source_warehouse_id\": 10,\n  \"destination_warehouse_id\": 22,\n  \"transfer_lead_time_days\": 3,\n  \"priority\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"source_warehouse_id\": 10,\n    \"source_warehouse\": {\n      \"id\": 10,\n      \"name\": \"Main DC\"\n    },\n    \"destination_warehouse_id\": 22,\n    \"destination_warehouse\": {\n      \"id\": 22,\n      \"name\": \"West Coast Store\"\n    },\n    \"transfer_lead_time_days\": 3,\n    \"priority\": 1,\n    \"created_at\": \"2026-06-18T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Distribution Edge","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network/{distributionNetwork}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network",":distributionNetwork"],"variable":[{"key":"distributionNetwork","value":"1","description":"The distribution network ID."}]},"description":"Update an existing edge (acyclic-graph check re-runs on endpoint changes). Same FormRequest as create - source/destination remain required.\nAuth: requires Bearer token.\nPath param: distributionNetwork = edge id.\nFields: source_warehouse_id (required, exists:warehouses), destination_warehouse_id (required, exists:warehouses, different:source), transfer_lead_time_days (nullable, integer, min:0), priority (nullable, integer).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"source_warehouse_id\": 10,\n  \"destination_warehouse_id\": 30,\n  \"transfer_lead_time_days\": 5,\n  \"priority\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network/{distributionNetwork}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network",":distributionNetwork"],"variable":[{"key":"distributionNetwork","value":"1","description":"The distribution network ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"source_warehouse_id\": 10,\n    \"source_warehouse\": {\n      \"id\": 10,\n      \"name\": \"Main DC\"\n    },\n    \"destination_warehouse_id\": 30,\n    \"destination_warehouse\": {\n      \"id\": 30,\n      \"name\": \"East Coast Store\"\n    },\n    \"transfer_lead_time_days\": 5,\n    \"priority\": 2,\n    \"created_at\": \"2026-06-01T14:20:05.000000Z\",\n    \"updated_at\": \"2026-06-18T12:05:00.000000Z\"\n  }\n}"}]},{"name":"Delete Distribution Edge","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network/{distributionNetwork}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network",":distributionNetwork"],"variable":[{"key":"distributionNetwork","value":"1","description":"The distribution network ID."}]},"description":"Delete a distribution edge. Returns 204 No Content.\nAuth: requires Bearer token.\nPath param: distributionNetwork = edge id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/distribution-network/{distributionNetwork}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","distribution-network",":distributionNetwork"],"variable":[{"key":"distributionNetwork","value":"1","description":"The distribution network ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Scenarios","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios"]},"description":"Paginated MRP what-if scenarios, newest first. No relations loaded.\nAuth: requires Bearer token.\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Holiday demand spike\",\n      \"description\": \"Model a 30% Q4 surge\",\n      \"base_run_id\": 12,\n      \"status\": \"draft\",\n      \"overrides\": {\n        \"demand_multiplier\": 1.3,\n        \"lead_time_buffer_days\": 5\n      },\n      \"created_by_user_id\": 7,\n      \"created_at\": \"2026-06-15T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Scenario","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios"]},"description":"Create a scenario. created_by_user_id is set from the authenticated user; status defaults to draft (not settable here).\nAuth: requires Bearer token.\nFormRequest: UpsertMrpScenarioRequest.\nFields: name (required, max:255), description (nullable), base_run_id (nullable, exists:mrp_runs), overrides (nullable, array/object).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Holiday demand spike\",\n  \"description\": \"Model a 30% Q4 surge\",\n  \"base_run_id\": 12,\n  \"overrides\": {\n    \"demand_multiplier\": 1.3,\n    \"lead_time_buffer_days\": 5\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Holiday demand spike\",\n    \"description\": \"Model a 30% Q4 surge\",\n    \"base_run_id\": 12,\n    \"status\": \"draft\",\n    \"overrides\": {\n      \"demand_multiplier\": 1.3,\n      \"lead_time_buffer_days\": 5\n    },\n    \"created_by_user_id\": 7,\n    \"created_at\": \"2026-06-18T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T12:00:00.000000Z\"\n  },\n  \"message\": \"Scenario created\"\n}"}]},{"name":"Compare Scenario Runs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/compare?run_id_a=12&run_id_b=15","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios","compare"],"query":[{"key":"run_id_a","value":"12","description":"First MRP run to compare (required, exists:mrp_runs)","disabled":true},{"key":"run_id_b","value":"15","description":"Second MRP run to compare (required, exists:mrp_runs)","disabled":true}]},"description":"Compare the planned-order output of two MRP RUNS (not scenarios) and return aggregate deltas. Plain object. Validation is inline.\nAuth: requires Bearer token.\nQuery (both required): run_id_a (exists:mrp_runs), run_id_b (exists:mrp_runs).\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/compare?run_id_a=12&run_id_b=15","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios","compare"],"query":[{"key":"run_id_a","value":"12","description":"First MRP run to compare (required, exists:mrp_runs)","disabled":true},{"key":"run_id_b","value":"15","description":"Second MRP run to compare (required, exists:mrp_runs)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"run_id_a\": 12,\n    \"run_id_b\": 15,\n    \"planned_orders_a\": 48,\n    \"planned_orders_b\": 52,\n    \"total_qty_a\": 12750,\n    \"total_qty_b\": 13980.5,\n    \"by_supply_type\": {\n      \"manufacture\": {\n        \"count_a\": 20,\n        \"count_b\": 22,\n        \"qty_a\": 8000,\n        \"qty_b\": 8600\n      },\n      \"purchase\": {\n        \"count_a\": 25,\n        \"count_b\": 26,\n        \"qty_a\": 4500,\n        \"qty_b\": 5180.5\n      },\n      \"transfer\": {\n        \"count_a\": 3,\n        \"count_b\": 4,\n        \"qty_a\": 250,\n        \"qty_b\": 200\n      }\n    }\n  }\n}"}]},{"name":"Get Scenario","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]},"description":"Return a single scenario by id. No relations loaded.\nAuth: requires Bearer token.\nPath param: mrpScenario = scenario id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Holiday demand spike\",\n    \"description\": \"Model a 30% Q4 surge\",\n    \"base_run_id\": 12,\n    \"status\": \"draft\",\n    \"overrides\": {\n      \"demand_multiplier\": 1.3,\n      \"lead_time_buffer_days\": 5\n    },\n    \"created_by_user_id\": 7,\n    \"created_at\": \"2026-06-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Scenario","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]},"description":"Update a scenario. Same FormRequest as create - name remains required. status and created_by_user_id are not settable here.\nAuth: requires Bearer token.\nPath param: mrpScenario = scenario id.\nFields: name (required, max:255), description (nullable), base_run_id (nullable, exists:mrp_runs), overrides (nullable, array/object).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Holiday demand spike (revised)\",\n  \"description\": \"Updated to 40% surge\",\n  \"base_run_id\": 12,\n  \"overrides\": {\n    \"demand_multiplier\": 1.4\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Holiday demand spike (revised)\",\n    \"description\": \"Updated to 40% surge\",\n    \"base_run_id\": 12,\n    \"status\": \"draft\",\n    \"overrides\": {\n      \"demand_multiplier\": 1.4\n    },\n    \"created_by_user_id\": 7,\n    \"created_at\": \"2026-06-15T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T12:10:00.000000Z\"\n  },\n  \"message\": \"Scenario updated\"\n}"}]},{"name":"Delete Scenario","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]},"description":"Delete a scenario. Returns 204 No Content.\nAuth: requires Bearer token.\nPath param: mrpScenario = scenario id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/scenarios/{mrpScenario}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","scenarios",":mrpScenario"],"variable":[{"key":"mrpScenario","value":"1","description":"The mrp scenario ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Planning Calendars","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars"]},"description":"Paginated list of planning calendars, ordered by name asc. No filtering.\nAuth: requires Bearer token.\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard Factory Calendar\",\n      \"is_default\": true,\n      \"working_days\": [\n        1,\n        2,\n        3,\n        4,\n        5\n      ],\n      \"holidays\": [\n        \"2026-07-04\",\n        \"2026-12-25\"\n      ],\n      \"created_at\": \"2026-06-01T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-10T11:15:30.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Weekend Shift Calendar\",\n      \"is_default\": false,\n      \"working_days\": [\n        6,\n        7\n      ],\n      \"holidays\": [],\n      \"created_at\": \"2026-06-01T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-10T11:15:30.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Create Planning Calendar","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars"]},"description":"Create a planning calendar. Setting is_default truthy unsets default on all other calendars.\nAuth: requires Bearer token.\nFormRequest: StorePlanningCalendarRequest.\nFields: name (required, max:255), is_default (sometimes, boolean), working_days (nullable, array), working_days.* (integer, min:1, max:7; 1=Mon..7=Sun), holidays (nullable, array), holidays.* (date_format:Y-m-d).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Factory Calendar\",\n  \"is_default\": true,\n  \"working_days\": [\n    1,\n    2,\n    3,\n    4,\n    5\n  ],\n  \"holidays\": [\n    \"2026-07-04\",\n    \"2026-12-25\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Standard Factory Calendar\",\n    \"is_default\": true,\n    \"working_days\": [\n      1,\n      2,\n      3,\n      4,\n      5\n    ],\n    \"holidays\": [\n      \"2026-07-04\",\n      \"2026-12-25\"\n    ],\n    \"created_at\": \"2026-06-18T14:32:05.000000Z\",\n    \"updated_at\": \"2026-06-18T14:32:05.000000Z\"\n  }\n}"}]},{"name":"Get Planning Calendar","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]},"description":"Return a single planning calendar by id.\nAuth: requires Bearer token.\nPath param: planningCalendar = calendar id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Standard Factory Calendar\",\n    \"is_default\": true,\n    \"working_days\": [\n      1,\n      2,\n      3,\n      4,\n      5\n    ],\n    \"holidays\": [\n      \"2026-07-04\",\n      \"2026-12-25\"\n    ],\n    \"created_at\": \"2026-06-01T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-10T11:15:30.000000Z\"\n  }\n}"}]},{"name":"Update Planning Calendar","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]},"description":"Update a planning calendar (partial). Setting is_default truthy unsets default on all others.\nAuth: requires Bearer token.\nPath param: planningCalendar = calendar id.\nFormRequest: UpdatePlanningCalendarRequest.\nFields: name (sometimes, max:255), is_default (sometimes, boolean), working_days (nullable, array of int 1-7), holidays (nullable, array of Y-m-d).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Factory Calendar (Revised)\",\n  \"is_default\": false,\n  \"working_days\": [\n    1,\n    2,\n    3,\n    4,\n    5,\n    6\n  ],\n  \"holidays\": [\n    \"2026-07-04\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Standard Factory Calendar (Revised)\",\n    \"is_default\": false,\n    \"working_days\": [\n      1,\n      2,\n      3,\n      4,\n      5,\n      6\n    ],\n    \"holidays\": [\n      \"2026-07-04\"\n    ],\n    \"created_at\": \"2026-06-01T09:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T14:40:00.000000Z\"\n  }\n}"}]},{"name":"Delete Planning Calendar","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]},"description":"Delete a planning calendar. Returns 204 No Content.\nAuth: requires Bearer token.\nPath param: planningCalendar = calendar id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/planning-calendars/{planningCalendar}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","planning-calendars",":planningCalendar"],"variable":[{"key":"planningCalendar","value":"1","description":"The planning calendar ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Get Work Center Calendar","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/work-centers/{workCenter}/calendar","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","work-centers",":workCenter","calendar"],"variable":[{"key":"workCenter","value":"1","description":"The work center ID."}]},"description":"Return the work center's calendar with the related planning calendar eager-loaded. Returns data: null when none exists.\nAuth: requires Bearer token.\nPath param: workCenter = work center id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/work-centers/{workCenter}/calendar","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","work-centers",":workCenter","calendar"],"variable":[{"key":"workCenter","value":"1","description":"The work center ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"work_center_id\": 5,\n    \"planning_calendar_id\": 1,\n    \"planning_calendar\": {\n      \"id\": 1,\n      \"name\": \"Standard Factory Calendar\"\n    },\n    \"shifts\": [\n      {\n        \"start\": \"08:00\",\n        \"end\": \"12:00\"\n      },\n      {\n        \"start\": \"13:00\",\n        \"end\": \"17:00\"\n      }\n    ],\n    \"utilization_pct\": 85,\n    \"efficiency_pct\": 92.5,\n    \"finite_capacity\": true,\n    \"finite_time_fence_days\": 14,\n    \"created_at\": \"2026-06-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-12T08:30:00.000000Z\"\n  }\n}"}]},{"name":"Upsert Work Center Calendar","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/work-centers/{workCenter}/calendar","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","work-centers",":workCenter","calendar"],"variable":[{"key":"workCenter","value":"1","description":"The work center ID."}]},"description":"Create or update the single calendar for the work center (work_center_id comes from the route).\nAuth: requires Bearer token.\nPath param: workCenter = work center id.\nFormRequest: UpsertWorkCenterCalendarRequest.\nFields: planning_calendar_id (nullable, exists:planning_calendars), shifts (nullable, array), shifts.*.start & shifts.*.end (required_with:shifts, string), utilization_pct (sometimes, numeric, 0-100), efficiency_pct (sometimes, numeric, 0-100), finite_capacity (sometimes, boolean), finite_time_fence_days (nullable, integer, min:0).\nNote: the planning_calendar nested object is omitted from this response (relation not eager-loaded on upsert); only planning_calendar_id appears.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"planning_calendar_id\": 1,\n  \"shifts\": [\n    {\n      \"start\": \"08:00\",\n      \"end\": \"12:00\"\n    },\n    {\n      \"start\": \"13:00\",\n      \"end\": \"17:00\"\n    }\n  ],\n  \"utilization_pct\": 85,\n  \"efficiency_pct\": 92.5,\n  \"finite_capacity\": true,\n  \"finite_time_fence_days\": 14\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/work-centers/{workCenter}/calendar","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","work-centers",":workCenter","calendar"],"variable":[{"key":"workCenter","value":"1","description":"The work center ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"work_center_id\": 5,\n    \"planning_calendar_id\": 1,\n    \"shifts\": [\n      {\n        \"start\": \"08:00\",\n        \"end\": \"12:00\"\n      },\n      {\n        \"start\": \"13:00\",\n        \"end\": \"17:00\"\n      }\n    ],\n    \"utilization_pct\": 85,\n    \"efficiency_pct\": 92.5,\n    \"finite_capacity\": true,\n    \"finite_time_fence_days\": 14,\n    \"created_at\": \"2026-06-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T14:40:12.000000Z\"\n  }\n}"}]},{"name":"List Bill of Resources","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources"]},"description":"Paginated bill-of-resource rows (product x work center x hours_per_unit) with product and workCenter eager-loaded, newest first. No filtering.\nAuth: requires Bearer token.\nPagination defaults: per_page=10.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"product_id\": 101,\n      \"product\": {\n        \"id\": 101,\n        \"sku\": \"WIDGET-RED-01\",\n        \"name\": \"Red Widget\"\n      },\n      \"work_center_id\": 5,\n      \"work_center\": {\n        \"id\": 5,\n        \"name\": \"Assembly Line A\",\n        \"code\": \"ASM-A\"\n      },\n      \"hours_per_unit\": 0.75,\n      \"is_key_resource\": true,\n      \"created_at\": \"2026-06-15T12:00:00.000000Z\",\n      \"updated_at\": \"2026-06-15T12:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Bill of Resource","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources"]},"description":"Create a bill-of-resource link. Returns 201 with product and workCenter loaded.\nAuth: requires Bearer token.\nFormRequest: StoreBillOfResourceRequest.\nFields: product_id (required, exists:products), work_center_id (required, exists:work_centers), hours_per_unit (required, numeric, min:0), is_key_resource (sometimes, boolean).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 101,\n  \"work_center_id\": 5,\n  \"hours_per_unit\": 0.75,\n  \"is_key_resource\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8,\n    \"product_id\": 101,\n    \"product\": {\n      \"id\": 101,\n      \"sku\": \"WIDGET-RED-01\",\n      \"name\": \"Red Widget\"\n    },\n    \"work_center_id\": 5,\n    \"work_center\": {\n      \"id\": 5,\n      \"name\": \"Assembly Line A\",\n      \"code\": \"ASM-A\"\n    },\n    \"hours_per_unit\": 0.75,\n    \"is_key_resource\": true,\n    \"created_at\": \"2026-06-18T14:45:00.000000Z\",\n    \"updated_at\": \"2026-06-18T14:45:00.000000Z\"\n  }\n}"}]},{"name":"Get Bill of Resource","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]},"description":"Return a single bill-of-resource row with product and workCenter loaded.\nAuth: requires Bearer token.\nPath param: billOfResource = row id.\n\n**Required scope: `manufacturing:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"product_id\": 101,\n    \"product\": {\n      \"id\": 101,\n      \"sku\": \"WIDGET-RED-01\",\n      \"name\": \"Red Widget\"\n    },\n    \"work_center_id\": 5,\n    \"work_center\": {\n      \"id\": 5,\n      \"name\": \"Assembly Line A\",\n      \"code\": \"ASM-A\"\n    },\n    \"hours_per_unit\": 0.75,\n    \"is_key_resource\": true,\n    \"created_at\": \"2026-06-15T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-15T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Bill of Resource","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]},"description":"Update a bill-of-resource row (partial). Returns 200 with product and workCenter loaded.\nAuth: requires Bearer token.\nPath param: billOfResource = row id.\nFormRequest: UpdateBillOfResourceRequest.\nFields: product_id (sometimes, exists:products), work_center_id (sometimes, exists:work_centers), hours_per_unit (sometimes, numeric, min:0), is_key_resource (sometimes, boolean).\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"hours_per_unit\": 1.25,\n  \"is_key_resource\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"product_id\": 101,\n    \"product\": {\n      \"id\": 101,\n      \"sku\": \"WIDGET-RED-01\",\n      \"name\": \"Red Widget\"\n    },\n    \"work_center_id\": 5,\n    \"work_center\": {\n      \"id\": 5,\n      \"name\": \"Assembly Line A\",\n      \"code\": \"ASM-A\"\n    },\n    \"hours_per_unit\": 1.25,\n    \"is_key_resource\": false,\n    \"created_at\": \"2026-06-15T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T14:50:00.000000Z\"\n  }\n}"}]},{"name":"Delete Bill of Resource","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]},"description":"Delete a bill-of-resource row. Returns 204 No Content.\nAuth: requires Bearer token.\nPath param: billOfResource = row id.\n\n**Required scope: `manufacturing:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/manufacturing/mrp/bill-of-resources/{billOfResource}","host":["{{baseUrl}}"],"path":["api","manufacturing","mrp","bill-of-resources",":billOfResource"],"variable":[{"key":"billOfResource","value":"1","description":"The bill of resource ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]}]},{"name":"Sales Orders","item":[{"name":"Archive Sales Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/archive","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","archive"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Archives a sales order (stamps its archived timestamp so it is hidden from active lists), then runs the legacy archive-and-fulfill flow: a fulfillment is created for the order's remaining unfulfilled items and the tracking is submitted to the order's sales channel. The success message and returned `data` describe the created fulfillment.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTo archive orders without this fulfillment side effect, use the bulk endpoint `PUT /api/sales-orders/archive` with a single ID instead.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional — when omitted, a fulfillment is created for all remaining unfulfilled items):\n- fulfillment_type (string): `manual`, `shipstation`, `starshipit`, `shipmyorders`, `fba`, `walmart_wfs`, `veracore`, `shiphero`, `shipfusion`, `d3`, `trackstar`, `pickup`, or `sales_channel`.\n- fulfilled_at (date): Shipment date; required for `manual` fulfillments.\n- tracking_number (string, max 255).\n- requested_shipping_method_id (integer) / requested_shipping_method (string, max 255).\n- fulfilled_shipping_method_id (integer) / manual_fulfilled_shipping_method (string, max 255): For manual fulfillments.\n- cost (number, < 100,000): Shipping cost.\n- fulfillment_lines (array): Restrict the fulfillment to specific lines; each item needs sales_order_line_id (integer, required) and quantity (number, required, >= 0). Per-line `metadata.fba_seller_sku` (string) and `lot_allocation` (array of {fifo_layer_id, quantity}) are supported for lot-tracked products.\n- metadata.signature_required (boolean), metadata.saturday_delivery (boolean), metadata.shipping_speed (string), metadata.comments (string), metadata.veracore_packing_slip_comments (string, max 500), metadata.veracore_shipping_comments (string, max 500), metadata.veracore_third_party_account_number (string, max 100), metadata.veracore_third_party_type (integer, 1-3).\n- packing_slip_printed_at (date), status (string), submit_to_shipping_provider (boolean), submit_to_sales_channel (boolean).\n\nBehavior:\n- If the order is already archived, a warning is returned and no fulfillment is created.\n- Orders held until a future date (`hold_until_date`) cannot be fulfilled and return 400.\n- Draft orders and closed (non-out-of-sync) orders fail fulfillment validation.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"fulfillment_type\": \"manual\",\n  \"fulfilled_at\": \"2026-07-06\",\n  \"tracking_number\": \"9405511899561234567890\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/archive","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","archive"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order fulfillment created successfully\",\n  \"data\": {\n    \"id\": 91,\n    \"fulfillment_sequence\": 1,\n    \"ssi_imported\": false\n  }\n}"}]},{"name":"Unarchive Sales Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","unarchived"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Restores an archived sales order so it appears in active lists again (clears its archived timestamp). Returns the order in `data`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIf the order is not archived, a warning is returned (the order is still included in `data`).\n\nNote: the path segment is literally `unarchived`.\n\nAuthentication: Requires Bearer token.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","unarchived"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order '500' unarchived successfully\",\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-0158\",\n    \"customer_po_number\": \"PO-88213\",\n    \"sales_channel_id\": 3,\n    \"sub_sales_channel_id\": null,\n    \"sales_rep_id\": null,\n    \"accounting\": {},\n    \"order_date\": \"2026-06-18T14:23:11.000000Z\",\n    \"payment_date\": \"2026-06-18T14:25:02.000000Z\",\n    \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n    \"updated_at\": \"2026-07-06T11:20:31.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": \"2026-06-19T16:40:21.000000Z\",\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"order_status\": \"closed\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"payment_status\": \"paid\",\n    \"currency_code\": \"USD\",\n    \"exact_discount_total\": 0.95,\n    \"is_tax_included\": false,\n    \"tax_total\": 4.11,\n    \"calculated_tax_total\": 4.11,\n    \"exact_tax_total\": 4.11,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null\n  }\n}"}]},{"name":"Bulk Archive Sales Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/archive","host":["{{baseUrl}}"],"path":["api","sales-orders","archive"]},"description":"Archives multiple sales orders at once (stamps each order's archived timestamp so it disappears from active lists). Unlike the single-order archive endpoint, this performs a pure archive with no fulfillment side effects.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of `ids` or `filters` is required):\n- ids (array of integers, required without filters, min 1): Sales order IDs; each must exist.\n- filters (required without ids): Filter payload resolved against the sales-orders list — accepts the grouped `filter_groups` shape (base64-encoded JSON, same as the V2 sales-orders list) as well as the legacy JSON-string filter set.\n\nWhen targeting by `filters`, only currently non-archived matching orders are processed.\n\nBehavior:\n- Orders that are already archived are skipped and reported under `warnings`, keyed by `ids.{id}.id`.\n- The message reports `{archived}/{total}` counts. If every targeted order was already archived, the message is \"The sales orders maybe already archived\".\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/archive","host":["{{baseUrl}}"],"path":["api","sales-orders","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3/3 sales orders had been archived successfully\"\n}"}]},{"name":"Bulk Unarchive Sales Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/unarchive","host":["{{baseUrl}}"],"path":["api","sales-orders","unarchive"]},"description":"Restores multiple archived sales orders at once (clears each order's archived timestamp so it reappears in active lists).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of `ids` or `filters` is required):\n- ids (array of integers, required without filters, min 1): Sales order IDs; each must exist.\n- filters (required without ids): Filter payload resolved against the sales-orders list — accepts the grouped `filter_groups` shape (base64-encoded JSON, same as the V2 sales-orders list) as well as the legacy JSON-string filter set.\n\nWhen targeting by `filters`, only currently archived matching orders are processed.\n\nBehavior:\n- Orders that are not archived are skipped and reported under `warnings`, keyed by `ids.{id}.id`.\n- The message reports `{unarchived}/{total}` counts. If every targeted order was already active, the message is \"The sales orders are already un archived\".\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/unarchive","host":["{{baseUrl}}"],"path":["api","sales-orders","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2/2 sales orders had been un archived successfully\"\n}"}]},{"name":"Check Sales Orders Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/deletable","host":["{{baseUrl}}"],"path":["api","sales-orders","deletable"]},"description":"Checks whether the given sales orders can be deleted, returning one result per order. Use this before calling the delete endpoints to warn users about related records that will be removed along with each order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- ids (array of integers, required, min 1): Sales order IDs; each must exist.\n\nResponse: `data` is an array with one entry per order:\n- id (integer), sales_order_number (string)\n- deletable (boolean): Whether the order can be deleted. Deletion cascades related records, so this is true in normal cases.\n- reason (string|null): Populated when the order is not deletable.\n- warnings (object, present only when applicable): Informational warnings — e.g. `warnings.fulfillments` describes how many fulfillments will be removed with the order.\n\n**Requires permission:** `sales_orders.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    500,\n    501\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/deletable","host":["{{baseUrl}}"],"path":["api","sales-orders","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 500,\n      \"sales_order_number\": \"SO-0158\",\n      \"deletable\": true,\n      \"reason\": null,\n      \"warnings\": {\n        \"fulfillments\": \"There is 1 sales order fulfillment associated with this sales order (SO-0158).\"\n      }\n    },\n    {\n      \"id\": 501,\n      \"sales_order_number\": \"SO-0159\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Bulk Approve Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/approve","host":["{{baseUrl}}"],"path":["api","sales-orders","approve"]},"description":"Approves multiple draft (or reserved) sales orders, transitioning them to `open`. Newly opened orders are automatically routed for fulfillment.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of `ids` or `filters` is required):\n- ids (array of integers, required without filters): Sales order IDs to approve.\n- filters (required without ids): Filter payload resolved against the sales-orders list — accepts the grouped `filter_groups` shape (base64-encoded JSON, same as the V2 sales-orders list) as well as the legacy JSON-string filter set.\n- archived (integer, optional, default 0): Used with `filters` — set to 1 to include archived orders when resolving IDs.\n\nBehavior:\n- Only `draft` and `reserved` orders can be approved; other orders are reported as errors.\n- An order that cannot be approved (no line items, or unmapped products) is reported as an error.\n- Returns 200 when all orders approve; 200 with `warnings` when only some approve; 400 when none were selected or all failed.\n\n**Requires permission:** `sales_orders.approve`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/approve","host":["{{baseUrl}}"],"path":["api","sales-orders","approve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sales orders approved successfully\",\n  \"data\": {\n    \"7116\": \"The sales order 'SO-7116' approved successfully\",\n    \"7117\": \"The sales order 'SO-7117' approved successfully\"\n  }\n}"}]},{"name":"Bulk Mark Sales Orders as Draft","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/mark-as-draft","host":["{{baseUrl}}"],"path":["api","sales-orders","mark-as-draft"]},"description":"Reverts multiple sales orders back to `draft`. Reverting an order deletes its payments and fulfillments, reverses its inventory movements and cost layers, tears down its fulfillment routing, removes its accounting transaction, and resets order/fulfillment/payment statuses (including clearing any cancellation).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of `ids` or `filters` is required):\n- ids (array of integers, required without filters): Sales order IDs to revert.\n- filters (required without ids): Filter payload resolved against the sales-orders list — accepts the grouped `filter_groups` shape (base64-encoded JSON, same as the V2 sales-orders list) as well as the legacy JSON-string filter set.\n- archived (integer, optional, default 0): Used with `filters` — set to 1 to include archived orders when resolving IDs.\n\nBehavior:\n- Orders awaiting tracking cannot be reverted (remove their fulfillments first); closed orders cannot be reverted.\n- Returns 200 when all orders revert; 200 with per-order `warnings` (keyed by order ID) when only some revert; 400 when none were found or all failed.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/mark-as-draft","host":["{{baseUrl}}"],"path":["api","sales-orders","mark-as-draft"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully marked all sales orders as draft.\",\n  \"data\": {\n    \"7116\": \"Successfully marked sales order SO-7116 as draft.\",\n    \"7117\": \"Successfully marked sales order SO-7117 as draft.\"\n  }\n}"}]},{"name":"Duplicate Sales Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/duplicate","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","duplicate"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Creates a copy of a sales order as a new draft order and returns the new order's full detail. The copy gets the next local order number, `draft` status, `unfulfilled` / `unpaid` statuses, and is assigned to the local (SKU.io) sales channel. Line items are copied without any fulfillment progress or sales-channel linkage; reservation and packing-slip state are cleared.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo request body.\n\nPath parameters:\n- salesOrder (required): Sales order ID to duplicate.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/duplicate","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","duplicate"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order duplicated successfully\",\n  \"data\": {\n    \"id\": 612,\n    \"sales_order_number\": \"SO-01044\",\n    \"customer_po_number\": null,\n    \"sales_channel_id\": 3,\n    \"sales_channel_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": null,\n    \"sub_sales_channel\": null,\n    \"sub_sales_channel_name\": null,\n    \"integration_instance_id\": 2,\n    \"integration\": \"Shopify\",\n    \"integration_id\": 4,\n    \"integration_image\": \"https://cdn.sku.io/integrations/shopify.png\",\n    \"can_submit_fulfillments_to_channel\": true,\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_rep_id\": null,\n    \"sales_rep\": null,\n    \"accounting\": {\n      \"transaction\": null\n    },\n    \"order_date\": \"2026-07-06T10:15:00.000000Z\",\n    \"payment_date\": null,\n    \"created_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"discounts\": [],\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": null,\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"has_backorder\": false,\n    \"fulfillment\": [],\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 2310,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 11.42,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 2,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 0,\n        \"item_on_hand_allocated_quantity\": 0,\n        \"item_unallocated_quantity\": 2,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 812,\n          \"sku\": \"WB-32-BLU\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345678905,\n        \"item_weight\": 1.2,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 25.99,\n        \"item_price_with_tax\": 25.99,\n        \"item_name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 51.98,\n        \"price_after_line_discount\": 25.99,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 51.98,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": false,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 2,\n        \"remaining_to_fulfill_quantity\": 2,\n        \"available_to_fulfill\": 2,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 0,\n        \"inventory_allocation_id\": null,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": null,\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/wb-32-blu.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 24,\n            \"stock\": 150,\n            \"allocated\": 2,\n            \"on_hold\": 0,\n            \"available\": 148,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 24,\n              \"stock\": 150,\n              \"allocated\": 2,\n              \"on_hold\": 0,\n              \"available\": 148,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 148\n      }\n    ],\n    \"purchase_orders\": [],\n    \"adjustments\": [],\n    \"financial_lines\": [],\n    \"custom_field_values\": [],\n    \"order_status\": \"draft\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"fulfillment_sequence\": null,\n    \"payment_status\": \"unpaid\",\n    \"tax_revenue\": 0,\n    \"product_total\": 51.98,\n    \"total\": 51.98,\n    \"discount_total\": 0,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"wholesale\"\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    ],\n    \"can_fulfill\": false,\n    \"exact_discount_total\": 0,\n    \"is_tax_included\": false,\n    \"tax_total\": 0,\n    \"calculated_tax_total\": 0,\n    \"exact_tax_total\": 0,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"payments\": [],\n    \"notes\": [],\n    \"earliest_covered_ship_by_date\": null,\n    \"latest_covered_ship_by_date\": null,\n    \"has_backorder_lines\": false\n  }\n}"}]},{"name":"Resend Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/resend","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","resend"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Creates a $0 resend order for replacing items from an existing order (e.g. lost or damaged shipments), linked to the original order, and returns the new order's full detail.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe new order is a draft copy of the original with:\n- order number `{original}-R-{YYYYMMDD}` and order date set to now\n- only the requested lines, at the requested quantities, with line amounts zeroed (no charge)\n- a ship-by date computed from your default handling days and same-day shipping cutoff, skipping weekends; a deliver-by date is derived from the shipping method's maximum delivery days when available\n- a resend link back to the original order (the original shows the resend under its linked orders)\n\nApprove the returned draft order to release it for fulfillment.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- sales_order_lines (array, optional): Lines to resend. Each item: id (integer, required — must be a line of this order), quantity (number, required — must not exceed the original line quantity). When omitted or empty, the resend order is created with no lines.\n\nPath parameters:\n- salesOrder (required): Sales order ID to resend from.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"sales_order_lines\": [\n    {\n      \"id\": 2101,\n      \"quantity\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/resend","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","resend"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order resend successfully\",\n  \"data\": {\n    \"id\": 612,\n    \"sales_order_number\": \"SO-0158-R-20260706\",\n    \"customer_po_number\": null,\n    \"sales_channel_id\": 3,\n    \"sales_channel_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": null,\n    \"sub_sales_channel\": null,\n    \"sub_sales_channel_name\": null,\n    \"integration_instance_id\": 2,\n    \"integration\": \"Shopify\",\n    \"integration_id\": 4,\n    \"integration_image\": \"https://cdn.sku.io/integrations/shopify.png\",\n    \"can_submit_fulfillments_to_channel\": true,\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_rep_id\": null,\n    \"sales_rep\": null,\n    \"accounting\": {\n      \"transaction\": null\n    },\n    \"order_date\": \"2026-07-06T10:15:00.000000Z\",\n    \"payment_date\": null,\n    \"created_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"discounts\": [],\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": null,\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"has_backorder\": false,\n    \"fulfillment\": [],\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 2310,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 11.42,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 2,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 0,\n        \"item_on_hand_allocated_quantity\": 0,\n        \"item_unallocated_quantity\": 2,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 812,\n          \"sku\": \"WB-32-BLU\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345678905,\n        \"item_weight\": 1.2,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 0,\n        \"item_price_with_tax\": 0,\n        \"item_name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 0,\n        \"price_after_line_discount\": 0,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 0,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": false,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 2,\n        \"remaining_to_fulfill_quantity\": 2,\n        \"available_to_fulfill\": 2,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 0,\n        \"inventory_allocation_id\": null,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": null,\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/wb-32-blu.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 24,\n            \"stock\": 150,\n            \"allocated\": 2,\n            \"on_hold\": 0,\n            \"available\": 148,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 24,\n              \"stock\": 150,\n              \"allocated\": 2,\n              \"on_hold\": 0,\n              \"available\": 148,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 148\n      }\n    ],\n    \"purchase_orders\": [],\n    \"adjustments\": [],\n    \"financial_lines\": [],\n    \"custom_field_values\": [],\n    \"order_status\": \"draft\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"fulfillment_sequence\": null,\n    \"payment_status\": \"unpaid\",\n    \"tax_revenue\": 0,\n    \"product_total\": 0,\n    \"total\": 0,\n    \"discount_total\": 0,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"wholesale\"\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    ],\n    \"can_fulfill\": false,\n    \"exact_discount_total\": 0,\n    \"is_tax_included\": false,\n    \"tax_total\": 0,\n    \"calculated_tax_total\": 0,\n    \"exact_tax_total\": 0,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"payments\": [],\n    \"notes\": [],\n    \"earliest_covered_ship_by_date\": null,\n    \"latest_covered_ship_by_date\": null,\n    \"has_backorder_lines\": false\n  }\n}"}]},{"name":"Exchange Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/exchange","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","exchange"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Creates an exchange order for an existing order (e.g. swapping returned items), linked to the original order or to a sales credit, and returns the new order's full detail.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe new order is a copy of the original with:\n- order number `{original}-E-{YYYYMMDD}` and order date set to now\n- only the requested lines, at the requested quantities, keeping the original line prices\n- a sales-credit payment automatically recorded for the new order's total (the exchange is paid by credit), and the order is approved immediately\n- an exchange link to the sales credit when `sales_credit_id` is provided, otherwise to the original order\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- sales_order_lines (array, optional): Lines to exchange. Each item: id (integer, required — must be a line of this order), quantity (number, required).\n- sales_credit_id (integer, optional): Existing sales credit to link the exchange order to.\n\nPath parameters:\n- salesOrder (required): Sales order ID to exchange from.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"sales_order_lines\": [\n    {\n      \"id\": 2101,\n      \"quantity\": 2\n    }\n  ],\n  \"sales_credit_id\": 88\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/exchange","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","exchange"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order exchanged successfully\",\n  \"data\": {\n    \"id\": 612,\n    \"sales_order_number\": \"SO-0158-E-20260706\",\n    \"customer_po_number\": null,\n    \"sales_channel_id\": 3,\n    \"sales_channel_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": null,\n    \"sub_sales_channel\": null,\n    \"sub_sales_channel_name\": null,\n    \"integration_instance_id\": 2,\n    \"integration\": \"Shopify\",\n    \"integration_id\": 4,\n    \"integration_image\": \"https://cdn.sku.io/integrations/shopify.png\",\n    \"can_submit_fulfillments_to_channel\": true,\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_rep_id\": null,\n    \"sales_rep\": null,\n    \"accounting\": {\n      \"transaction\": null\n    },\n    \"order_date\": \"2026-07-06T10:15:00.000000Z\",\n    \"payment_date\": null,\n    \"created_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-06T10:15:00.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"discounts\": [],\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": null,\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"has_backorder\": false,\n    \"fulfillment\": [],\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 2310,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 11.42,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 2,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 0,\n        \"item_on_hand_allocated_quantity\": 0,\n        \"item_unallocated_quantity\": 2,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 812,\n          \"sku\": \"WB-32-BLU\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345678905,\n        \"item_weight\": 1.2,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 25.99,\n        \"item_price_with_tax\": 25.99,\n        \"item_name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 51.98,\n        \"price_after_line_discount\": 25.99,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 51.98,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": false,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 2,\n        \"remaining_to_fulfill_quantity\": 2,\n        \"available_to_fulfill\": 2,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 0,\n        \"inventory_allocation_id\": null,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": null,\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/wb-32-blu.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 24,\n            \"stock\": 150,\n            \"allocated\": 2,\n            \"on_hold\": 0,\n            \"available\": 148,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 24,\n              \"stock\": 150,\n              \"allocated\": 2,\n              \"on_hold\": 0,\n              \"available\": 148,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 148\n      }\n    ],\n    \"purchase_orders\": [],\n    \"adjustments\": [],\n    \"financial_lines\": [],\n    \"custom_field_values\": [],\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"fulfillment_sequence\": null,\n    \"payment_status\": \"paid\",\n    \"tax_revenue\": 0,\n    \"product_total\": 51.98,\n    \"total\": 51.98,\n    \"discount_total\": 0,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"wholesale\"\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    ],\n    \"can_fulfill\": false,\n    \"exact_discount_total\": 0,\n    \"is_tax_included\": false,\n    \"tax_total\": 0,\n    \"calculated_tax_total\": 0,\n    \"exact_tax_total\": 0,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"payments\": [\n      {\n        \"id\": 78,\n        \"amount\": 51.98,\n        \"cost\": null,\n        \"payment_date\": \"2026-07-06T10:15:00.000000Z\",\n        \"payment_type\": {\n          \"id\": 6,\n          \"name\": \"Sales Credit\"\n        },\n        \"external_reference\": null,\n        \"type\": \"payment\",\n        \"currency_code\": \"USD\",\n        \"sales_credit_allocation\": null\n      }\n    ],\n    \"notes\": [],\n    \"earliest_covered_ship_by_date\": null,\n    \"latest_covered_ship_by_date\": null,\n    \"has_backorder_lines\": false\n  }\n}"}]},{"name":"Refresh Sales Order Address Snapshots","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/refresh-address-snapshots","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","refresh-address-snapshots"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Re-copies the current contents of the order's shipping and billing address records into the order's own inline address snapshot columns. Use this after editing an address record's content (same address ID, different data) so the order's stored snapshot — which is what documents and the order detail display — reflects the corrected address.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOnly addresses linked by ID are refreshed; orders whose snapshot has no backing address record are left unchanged.\n\nAuthentication: Requires Bearer token.\n\nNo request body.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/refresh-address-snapshots","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","refresh-address-snapshots"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Address columns refreshed\"\n}"}]},{"name":"Fulfill Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfill","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfill"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Records a fulfillment (shipment) against a sales order, deducting inventory and, by default, submitting the fulfillment to the warehouse's shipping provider and reporting it to the originating sales channel.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- fulfillment_type (string, required): How the order was/will be fulfilled. One of: manual, shipstation, starshipit, shipmyorders, fba, walmart_wfs, veracore, shiphero, shipfusion, d3, trackstar, pickup, sales_channel.\n- warehouse_id (integer, optional): Warehouse to fulfill from. Auto-resolved when every product line on the order is routed to the same warehouse; required when lines span multiple warehouses, and it must be one of the order's line warehouses.\n- requested_shipping_method_id (integer, optional): Mapped shipping method to request from the provider.\n- requested_shipping_method (string, optional, max 255): Free-text requested shipping method.\n- fulfilled_shipping_method_id (integer, optional): The shipping method actually used (manual fulfillments).\n- manual_fulfilled_shipping_method (string, optional, max 255): Free-text actual shipping method (manual fulfillments).\n- fulfilled_at (date-time, required when fulfillment_type is manual): When the shipment left the warehouse.\n- cost (number, optional, < 100000): Shipping cost.\n- tracking_number (string, optional, max 255): Carrier tracking number.\n- fulfillment_sequence (integer, optional): Sequence number; must be unique within the sales order.\n- packing_slip_printed_at (date-time, optional): When the packing slip was printed.\n- status (string, optional): Initial fulfillment status.\n- submit_to_shipping_provider (boolean, optional, default true): Set false to record the fulfillment without notifying the shipping provider.\n- submit_to_sales_channel (boolean, optional, default true): Set false to record the fulfillment without reporting it to the sales channel.\n- fulfillment_lines (array, optional, min 1 when present): Lines and quantities to fulfill. When omitted, defaults to every unfulfilled product line in the resolved warehouse at its full remaining quantity.\n  - fulfillment_lines.*.sales_order_line_id (integer, required): Sales order line to fulfill; must belong to the order and to the resolved warehouse.\n  - fulfillment_lines.*.quantity (number, required, >= 0, < 100000): Quantity to fulfill; cannot exceed the line's remaining-to-fulfill quantity (already-shipped and in-flight quantities are subtracted).\n  - fulfillment_lines.*.metadata.fba_seller_sku (string, optional): Amazon seller SKU override for FBA fulfillments.\n  - fulfillment_lines.*.lot_allocation (array, optional): Per-line lot override for lot-tracked products. When omitted, lots are consumed first-expired-first-out. Entries must reconcile to the line quantity and reference active lots of the line's product and warehouse.\n    - fulfillment_lines.*.lot_allocation.*.fifo_layer_id (integer, required with lot_allocation): Inventory lot/layer to consume from.\n    - fulfillment_lines.*.lot_allocation.*.quantity (number, required with lot_allocation, > 0): Quantity to take from that lot.\n- metadata.signature_required (boolean, optional): Require a delivery signature.\n- metadata.saturday_delivery (boolean, optional): Request Saturday delivery.\n- metadata.shipping_speed (string, optional): Provider shipping speed hint.\n- metadata.comments (string, optional): Comments passed to the provider.\n- metadata.veracore_packing_slip_comments (string, optional, max 500): Packing slip comments (Veracore fulfillments).\n- metadata.veracore_shipping_comments (string, optional, max 500): Shipping comments (Veracore fulfillments).\n- metadata.veracore_third_party_account_number (string, optional, max 100): Third-party billing account number (Veracore fulfillments).\n- metadata.veracore_third_party_type (integer, optional, one of 1, 2, 3): Third-party billing type (Veracore fulfillments).\n\nBehavior:\n- The order must be approved (not draft). Closed orders can only be fulfilled while their fulfillment status is out_of_sync.\n- Fulfillments recorded with a Personal Access Token are treated as external/channel imports (the order was shipped outside SKU.io) rather than shipments dispatched from SKU.io.\n- Insufficient allocated inventory returns 422 with a structured `shortfalls` list, and the shortfall is also recorded as a note on the order.\n- If the shipping provider times out, the fulfillment is queued and processed in the background; the request still succeeds with a processing message.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"fulfillment_type\": \"manual\",\n  \"warehouse_id\": 2,\n  \"fulfilled_at\": \"2026-07-01 14:30:00\",\n  \"fulfilled_shipping_method_id\": 4,\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"cost\": 12.85,\n  \"fulfillment_lines\": [\n    {\n      \"sales_order_line_id\": 8912,\n      \"quantity\": 3,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 5521,\n          \"quantity\": 3\n        }\n      ]\n    }\n  ],\n  \"metadata\": {\n    \"signature_required\": false,\n    \"comments\": \"Leave at front desk\"\n  },\n  \"submit_to_shipping_provider\": true,\n  \"submit_to_sales_channel\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfill","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfill"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order created successfully\",\n  \"data\": {\n    \"id\": 9107\n  }\n}"}]},{"name":"Bulk Fulfill Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/fulfill","host":["{{baseUrl}}"],"path":["api","sales-orders","fulfill"]},"description":"Fulfills multiple sales orders at once by submitting each order's pending fulfillment work to the shipping provider or fulfillment service configured for its warehouse(s). This is an operator-initiated action, so warehouse auto-dispatch eligibility rules are bypassed.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids` or `filters` is required):\n- ids (array of integers, required without `filters`): Sales order IDs to fulfill.\n- filters (object, required without `ids`): Filter set that resolves to a list of sales order IDs (same shape used by the sales-orders listing endpoint).\n\nBehavior:\n- Orders on hold (a `hold_until_date` in the future) are skipped and reported in the result errors.\n- No shipment record is created at submit time — the provider's ship confirmation records the shipment later.\n- Per-order failures do not abort the batch; they are collected and returned.\n- Returns a summary with `total`, `success`, `errors`, and an overall `status` of `success` or `error`. When some orders fail, the response is returned as a warning with the per-order errors listed under `warnings`.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/fulfill","host":["{{baseUrl}}"],"path":["api","sales-orders","fulfill"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All fulfillable sales orders fulfilled successfully\",\n  \"data\": {\n    \"errors\": [],\n    \"total\": 3,\n    \"success\": 3,\n    \"status\": \"success\"\n  }\n}"}]},{"name":"Fulfill Sales Order via FBA","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfill-fba","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfill-fba"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Submits a Fulfilled-by-Amazon multi-channel fulfillment request for the sales order — Amazon picks, packs, and ships the selected lines out of FBA stock on your behalf. Only available in production environments.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- warehouse_id (integer, optional): The Amazon FBA warehouse to fulfill from (must be an FBA-type warehouse). Auto-resolved when every product line on the order is routed to the same warehouse; required when lines span multiple warehouses.\n- shipping_speed (string, required): Amazon shipping speed category. One of: Standard, Expedited, Priority.\n- comments (string, required): Displayable order comment passed to Amazon.\n- fulfillment_lines (array, optional, min 1 when present): Lines and quantities to fulfill. When omitted, defaults to every unfulfilled product line in the resolved warehouse at its full remaining quantity.\n  - fulfillment_lines.*.sales_order_line_id (integer, required): Sales order line to fulfill; must belong to the order and the resolved warehouse, and must not already be fulfilled.\n  - fulfillment_lines.*.quantity (number, required, >= 1): Quantity to fulfill; cannot exceed the line's remaining-to-fulfill quantity.\n  - fulfillment_lines.*.product_listing_id (integer, required): The Amazon product listing to ship for this line.\n\nBehavior:\n- The order must be approved (not draft) and not closed.\n- On success, the fulfillment order is created at Amazon and the response includes the new fulfillment record ID and Amazon's request identifier.\n- Outside production environments the request is rejected with an `IsUnacceptable` error and no fulfillment is created.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 7,\n  \"shipping_speed\": \"Standard\",\n  \"comments\": \"Multi-channel fulfillment for web order SO-1042\",\n  \"fulfillment_lines\": [\n    {\n      \"sales_order_line_id\": 8912,\n      \"quantity\": 2,\n      \"product_listing_id\": 4410\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfill-fba","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfill-fba"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order fulfillment created successfully\",\n  \"data\": {\n    \"resource\": \"sales order fulfillment\",\n    \"id\": 9111,\n    \"request_id\": \"8f2a6c1e-3d4b-4f6a-9b21-77d0c3a51e90\"\n  }\n}"}]},{"name":"Mark Sales Order for Pickup","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/mark-for-pickup","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","mark-for-pickup"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Stages a subset of the order's allocated line quantities for customer pickup. The order's pending fulfillment work is parked in an awaiting-pickup state — no shipment record is created until the customer actually collects — and the request records who marked the items, when, and the expected pickup date. Partial quantities are supported, so some units can be marked for pickup while the rest are fulfilled normally.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- warehouse_id (integer, required): Warehouse the customer will collect from. Every listed line must be routed to this warehouse.\n- expected_pickup_at (date-time, optional): When the customer is expected to collect.\n- note (string, optional, max 2000): Free-text note; recorded on the order as \"Marked for pickup: &lt;note>\".\n- items (array, required, min 1): Lines and quantities to mark for pickup.\n  - items.*.sales_order_line_id (integer, required): Sales order line; must belong to the order and the given warehouse.\n  - items.*.quantity (number, required, > 0, < 100000): Quantity to mark; cannot exceed the line's unfulfilled quantity.\n\nBehavior:\n- Returns the ID of the pickup-staged fulfillment order in `fulfillment_order_id`.\n- Items with a zero quantity are ignored; if no item has a positive quantity the request fails with 400.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 2,\n  \"expected_pickup_at\": \"2026-07-10 15:00:00\",\n  \"note\": \"Customer will collect at the will-call window\",\n  \"items\": [\n    {\n      \"sales_order_line_id\": 8912,\n      \"quantity\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/mark-for-pickup","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","mark-for-pickup"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The pickup fulfillment created successfully\",\n  \"data\": {\n    \"fulfillment_order_id\": 3312\n  }\n}"}]},{"name":"Reset Sales Order Fulfillment Status","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/reset-fulfillment-status","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","reset-fulfillment-status"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Recalculates a sales order's fulfillment status from its actual fulfillment data. Only allowed while the order's current fulfillment status is `out_of_sync`; the recomputed status is one of unfulfilled, partially_fulfilled, fulfilled, or over_fulfilled based on the quantities actually fulfilled per line.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo request body.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/reset-fulfillment-status","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","reset-fulfillment-status"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment status has been recalculated.\",\n  \"data\": {\n    \"fulfillment_status\": \"fulfilled\"\n  }\n}"}]},{"name":"Compare Fulfillments with Sales Channel","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/compare-fulfillments-with-sales-channel","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","compare-fulfillments-with-sales-channel"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Compares the fulfillments recorded in SKU.io against the fulfillments reported by the order's originating sales channel. Currently only orders linked to a Shopify order are compared; orders from other channels return an empty success response.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo query parameters.\n\nResponse payload (for orders linked to a Shopify order):\n- fulfillmentsToSubmit (array): Fulfillments recorded in SKU.io that have not been reported to the sales channel.\n- fulfillmentToCreate (array): Channel fulfillments not yet recorded in SKU.io.\n- differences (array): Field-level differences between matched fulfillments.\n\nThe current Shopify integration reports fulfillments to the channel automatically as part of order sync, so all three lists are typically empty.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/compare-fulfillments-with-sales-channel","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","compare-fulfillments-with-sales-channel"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"fulfillmentsToSubmit\": [],\n    \"fulfillmentToCreate\": [],\n    \"differences\": []\n  }\n}"}]},{"name":"Dispatch Fulfillments for Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dispatch-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dispatch-fulfillments"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Runs the fulfillment dispatcher for a single sales order: validates that the order is dispatchable (approved, fulfillment status in sync, all lines mapped to products, a shipping method selected, valid addresses), groups the fulfillable allocated lines by warehouse, and submits each warehouse's pending fulfillment order to the shipping provider or fulfillment service configured for that warehouse.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional; each flag bypasses one pre-dispatch check):\n- overrideOutOfSync (boolean, default false): Dispatch even when the order's fulfillment status is out of sync with the sales channel.\n- overrideSelectShippingMethod (boolean, default false): Dispatch even when no shipping method has been selected or mapped for the order.\n- overrideUnmappedLines (boolean, default false): Dispatch even when some order lines are not mapped to products (only mapped lines are dispatched).\n- overrideManualDispatch (boolean, default false): Dispatch warehouses that are configured for manual dispatch only.\n- overridePartialDispatch (boolean, default false): Allow dispatching when only part of the order's quantity is currently fulfillable.\n\nBehavior:\n- Dispatch is treated as user-requested, so warehouse auto-dispatch eligibility rules are bypassed.\n- Orders with a pickup shipping method are staged for customer pickup instead of being submitted to a carrier.\n- Submitting a fulfillment order to a provider does not create a shipment record; the provider's ship confirmation records the shipment later. The `data` array therefore contains only fulfillment records created immediately during dispatch and is often empty even after a successful dispatch.\n- Failed pre-dispatch checks do not error — the order is skipped and a note explaining why is recorded on the order; the response returns an empty `data` array.\n- Concurrent dispatch requests for the same order are serialized; if another dispatch is already running the request fails with 409.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"overrideOutOfSync\": false,\n  \"overrideSelectShippingMethod\": false,\n  \"overrideUnmappedLines\": false,\n  \"overrideManualDispatch\": true,\n  \"overridePartialDispatch\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dispatch-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dispatch-fulfillments"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Bulk Dispatch Fulfillments for Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/dispatch-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders","dispatch-fulfillments"]},"description":"Runs the fulfillment dispatcher for multiple sales orders — each order is validated and its pending fulfillment orders are submitted to the shipping provider or fulfillment service configured for its warehouse(s).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (provide `ids` or `filters`):\n- ids (array of integers, optional, min 1): Sales order IDs to dispatch. Dispatched synchronously; the response reports how many fulfillment orders were dispatched.\n- filters (string, optional): Filter query that resolves to a list of sales order IDs (same format used by the sales-orders listing endpoint). When provided, dispatching is queued and processed in the background and the response returns immediately.\n- overrideData (object, optional): Pre-dispatch check overrides applied to every order. Keys: overrideOutOfSync, overrideSelectShippingMethod, overrideUnmappedLines, overrideManualDispatch, overridePartialDispatch (all boolean, default false).\n\nBehavior:\n- Dispatch is treated as user-requested, so warehouse auto-dispatch eligibility rules are bypassed.\n- The success message counts fulfillment orders dispatched to providers. Shipment records are created later when each provider confirms shipment.\n- Orders skipped because another dispatch already holds their lock are listed in the message; if every requested order is skipped this way the request fails with 409 so it can be retried.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    500,\n    501,\n    502\n  ],\n  \"overrideData\": {\n    \"overrideManualDispatch\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/dispatch-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders","dispatch-fulfillments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"3 Fulfillment Orders dispatched.\"\n}"}]},{"name":"Preview Dropship Request","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dropship-preview?warehouse_id=9","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dropship-preview"],"query":[{"key":"warehouse_id","value":"9","description":"Dropship (supplier) warehouse ID to preview supplier costs for (required)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Previews the supplier cost for each of the order's product lines routed to a dropship (supplier) warehouse, before creating the dropship purchase order.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- warehouse_id (integer, required): The dropship warehouse to preview against. Only lines routed to this warehouse are returned.\n\nResponse fields (per line):\n- sales_order_line_id (integer): The sales order line.\n- product_id (integer): The product on the line.\n- supplier_cost (number): The product's unit cost for the warehouse's supplier, rounded to 4 decimal places.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dropship-preview?warehouse_id=9","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dropship-preview"],"query":[{"key":"warehouse_id","value":"9","description":"Dropship (supplier) warehouse ID to preview supplier costs for (required)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_order_line_id\": 8912,\n      \"product_id\": 341,\n      \"supplier_cost\": 12.5\n    },\n    {\n      \"sales_order_line_id\": 8913,\n      \"product_id\": 355,\n      \"supplier_cost\": 4.75\n    }\n  ]\n}"}]},{"name":"Create Dropship Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dropship-request","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dropship-request"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Creates a dropship request for the sales order: a purchase order is created and submitted to the supplier behind the given dropship warehouse for the selected lines, priced at supplier cost, with the sales order's shipping address as the delivery destination.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- warehouse_id (integer, required): The supplier (dropship) warehouse to order from. Must have the dropship setting enabled, otherwise the request fails with 400.\n- sales_order_lines (array, required): The order lines to dropship.\n  - sales_order_lines.*.id (integer, required): Sales order line ID.\n  - sales_order_lines.*.quantity (integer, optional): Quantity to dropship. Defaults to the full line quantity; values above the line quantity are capped.\n- requested_shipping_method_id (integer, optional): Mapped shipping method to request from the supplier.\n- requested_shipping_method (string, optional): Free-text requested shipping method.\n- supplier_notes (string, optional): Notes shown to the supplier on the purchase order.\n- internal_notes (string, optional): Internal notes on the purchase order.\n\nBehavior:\n- The purchase order is linked to the sales order and submitted immediately.\n- The order's pending fulfillment work for that warehouse is marked as ordered, and the order's fulfillment status is recalculated.\n- The response returns the created purchase order.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.fulfill`","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 9,\n  \"requested_shipping_method_id\": 4,\n  \"supplier_notes\": \"Ship directly to the customer in plain packaging\",\n  \"internal_notes\": \"Customer requested expedited handling\",\n  \"sales_order_lines\": [\n    {\n      \"id\": 8912,\n      \"quantity\": 2\n    },\n    {\n      \"id\": 8913\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/dropship-request","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","dropship-request"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2101,\n    \"po_number\": \"PO-02101\",\n    \"purchase_order_date\": \"2026-07-01\",\n    \"other_date\": null,\n    \"payment_term_id\": 1,\n    \"payment_term\": \"Net 30\",\n    \"incoterm_id\": null,\n    \"incoterm\": null,\n    \"submission_format\": \"email\",\n    \"currency_id\": 1,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"created_at\": \"2026-07-06T18:40:12.000000Z\",\n    \"updated_at\": \"2026-07-06T18:40:12.000000Z\",\n    \"created_by\": \"Kalvin Mizzi\",\n    \"last_updated_by\": \"Kalvin Mizzi\",\n    \"archived_at\": null,\n    \"is_dropship\": true,\n    \"tracking_number\": null,\n    \"supplier_id\": 5,\n    \"supplier_name\": {\n      \"id\": 5,\n      \"name\": \"Acme Supplies\"\n    },\n    \"supplier_email\": \"orders@acme.com\",\n    \"destination_warehouse_id\": null,\n    \"destination_warehouse_type\": null,\n    \"order_status\": \"open\",\n    \"submission_status\": \"sent\",\n    \"submission_blocked_no_email\": false,\n    \"receipt_status\": \"unreceived\",\n    \"shipment_status\": \"pending\",\n    \"invoice_status\": \"uninvoiced\",\n    \"additional_cost\": 0,\n    \"discount\": 0,\n    \"product_total\": 29.75,\n    \"total\": 29.75,\n    \"subtotal\": 29.75,\n    \"tax_cost\": 0,\n    \"is_tax_included\": false,\n    \"total_quantity\": 3,\n    \"supplier_notes\": \"Ship directly to the customer in plain packaging\",\n    \"estimated_delivery_date\": null,\n    \"fully_received_at\": null,\n    \"tags\": [],\n    \"store_id\": 1,\n    \"items\": [\n      {\n        \"id\": 5201,\n        \"product_id\": 341,\n        \"description\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"amount\": 12.5,\n        \"received_quantity\": 0\n      },\n      {\n        \"id\": 5202,\n        \"product_id\": 355,\n        \"description\": \"Red Widget\",\n        \"quantity\": 1,\n        \"amount\": 4.75,\n        \"received_quantity\": 0\n      }\n    ],\n    \"summary_info\": {\n      \"total_lines\": 2,\n      \"total_product_lines\": 2,\n      \"total_units\": 3,\n      \"total_quantity_pending_receipt\": 3\n    },\n    \"financial_lines\": [],\n    \"bills\": [],\n    \"invoices\": [],\n    \"amazon_pending_inbound\": null,\n    \"has_active_allocations\": false,\n    \"walmart_wfs_inbound_shipment\": null\n  }\n}"}]},{"name":"Preview Bulk Allocate Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-allocate/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-allocate","preview"]},"description":"Previews a bulk allocate action without changing any data. For each targeted sales order the response reports per-line eligibility, the quantities involved, and the allocation impact, plus aggregate totals — use it to confirm what a bulk allocate will do before running it.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids` or `filters` is required):\n- ids (array of integers, required without `filters`): Sales order IDs to target. Each ID must exist.\n- filters (object or string, required without `ids`): Resolves to the matching sales order IDs — the same targeting the sales-orders list uses. Two shapes are accepted:\n  - Grouped filters: `{ \"filter_groups\": \"<base64-encoded JSON tree>\" }`. The decoded tree looks like `{\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"order_status\",\"operator\":\"is\",\"value\":\"open\"}}]}`.\n  - Legacy filter set (JSON string) for older clients.\n\nResponse fields:\n- orders[] — one entry per targeted order:\n  - sales_order_id (integer), sales_order_number (string)\n  - status (string|null): Raw status value of the order, when available.\n  - eligibility (string): `eligible`, `partially_eligible`, or `ineligible`.\n  - reason (string|null): Populated only when the order is ineligible, with the shared line-level reason or an order-level summary.\n  - lines[] — one entry per warehoused product line:\n    - sales_order_line_id (integer), product_sku (string|null), product_name (string|null), warehouse_name (string|null)\n    - eligible (boolean), reason (string|null)\n    - processable_quantity (integer): Ordered quantity net of cancellations.\n    - fulfilled_quantity (integer): Quantity already committed to non-cancelled fulfillments.\n    - currently_allocated (integer): Units already covered by active allocations.\n    - impact_quantity (integer): Units this action would change on the line.\n- totals — orders_total, orders_eligible, orders_partially_eligible, orders_ineligible, lines_total, lines_eligible, lines_impact_quantity (all integers).\n\nBehavior notes:\n- Only lines stocked in warehouses that track inventory allocations are considered; lines in warehouses that do not are reported with reason \"Warehouse does not require inventory allocation\".\n- Lines already fully allocated or fulfilled are ineligible with reason \"Already fully allocated or fulfilled\".\n- impact_quantity is the remaining unallocated demand that a bulk allocate would newly allocate.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-allocate/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-allocate","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders\": [\n      {\n        \"sales_order_id\": 7116,\n        \"sales_order_number\": \"SO-7116\",\n        \"status\": null,\n        \"eligibility\": \"eligible\",\n        \"reason\": null,\n        \"lines\": [\n          {\n            \"sales_order_line_id\": 90211,\n            \"product_sku\": \"WID-BLU-M\",\n            \"product_name\": \"Blue Widget (Medium)\",\n            \"warehouse_name\": \"Main Warehouse\",\n            \"eligible\": true,\n            \"reason\": null,\n            \"processable_quantity\": 5,\n            \"fulfilled_quantity\": 0,\n            \"currently_allocated\": 2,\n            \"impact_quantity\": 3\n          }\n        ]\n      },\n      {\n        \"sales_order_id\": 7117,\n        \"sales_order_number\": \"SO-7117\",\n        \"status\": null,\n        \"eligibility\": \"ineligible\",\n        \"reason\": \"Already fully allocated or fulfilled\",\n        \"lines\": [\n          {\n            \"sales_order_line_id\": 90315,\n            \"product_sku\": \"WID-RED-S\",\n            \"product_name\": \"Red Widget (Small)\",\n            \"warehouse_name\": \"Main Warehouse\",\n            \"eligible\": false,\n            \"reason\": \"Already fully allocated or fulfilled\",\n            \"processable_quantity\": 2,\n            \"fulfilled_quantity\": 0,\n            \"currently_allocated\": 2,\n            \"impact_quantity\": 0\n          }\n        ]\n      }\n    ],\n    \"totals\": {\n      \"orders_total\": 2,\n      \"orders_eligible\": 1,\n      \"orders_partially_eligible\": 0,\n      \"orders_ineligible\": 1,\n      \"lines_total\": 2,\n      \"lines_eligible\": 1,\n      \"lines_impact_quantity\": 3\n    }\n  }\n}"}]},{"name":"Bulk Allocate Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-allocate","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-allocate"]},"description":"Starts an asynchronous bulk allocate operation for the targeted sales orders and returns immediately with a `tracked_job_log_id` to poll for progress and results.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids` or `filters` is required):\n- ids (array of integers, required without `filters`): Sales order IDs to target. Each ID must exist.\n- filters (object or string, required without `ids`): Resolves to the matching sales order IDs — the same targeting the sales-orders list uses. Two shapes are accepted:\n  - Grouped filters: `{ \"filter_groups\": \"<base64-encoded JSON tree>\" }`. The decoded tree looks like `{\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"order_status\",\"operator\":\"is\",\"value\":\"open\"}}]}`.\n  - Legacy filter set (JSON string) for older clients.\n\nBehavior:\n- For each order, inventory is allocated to every eligible line's remaining unallocated demand. Lines whose warehouse does not track allocations, and lines already fully allocated or fulfilled, are skipped.\n- The operation runs in the background. Poll the tracked job log endpoints with the returned ID for progress and the completion summary (orders processed / fully allocated / partially allocated / skipped; lines allocated / already allocated / failed) plus any per-order errors.\n- Call the preview endpoint (`POST /api/sales-orders/bulk-allocate/preview`) first to see exactly which orders and lines will be affected.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-allocate","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-allocate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84291\n  },\n  \"message\": \"Bulk allocate started. Track progress using the returned ID.\"\n}"}]},{"name":"Preview Bulk Unallocate Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-unallocate/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-unallocate","preview"]},"description":"Previews a bulk unallocate action without changing any data. For each targeted sales order the response reports per-line eligibility and how many allocated units would be released, plus aggregate totals — use it to confirm what a bulk unallocate will do before running it.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids` or `filters` is required):\n- ids (array of integers, required without `filters`): Sales order IDs to target. Each ID must exist.\n- filters (object or string, required without `ids`): Resolves to the matching sales order IDs — the same targeting the sales-orders list uses. Two shapes are accepted:\n  - Grouped filters: `{ \"filter_groups\": \"<base64-encoded JSON tree>\" }`. The decoded tree looks like `{\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"order_status\",\"operator\":\"is\",\"value\":\"open\"}}]}`.\n  - Legacy filter set (JSON string) for older clients.\n\nResponse fields:\n- orders[] — one entry per targeted order:\n  - sales_order_id (integer), sales_order_number (string)\n  - status (string|null): Raw status value of the order, when available.\n  - eligibility (string): `eligible`, `partially_eligible`, or `ineligible`.\n  - reason (string|null): Populated only when the order is ineligible, with the shared line-level reason or an order-level summary.\n  - lines[] — one entry per warehoused product line:\n    - sales_order_line_id (integer), product_sku (string|null), product_name (string|null), warehouse_name (string|null)\n    - eligible (boolean), reason (string|null)\n    - processable_quantity (integer): Ordered quantity net of cancellations.\n    - fulfilled_quantity (integer): Quantity already committed to non-cancelled fulfillments.\n    - currently_allocated (integer): Units already covered by active allocations.\n    - impact_quantity (integer): Units this action would change on the line.\n- totals — orders_total, orders_eligible, orders_partially_eligible, orders_ineligible, lines_total, lines_eligible, lines_impact_quantity (all integers).\n\nBehavior notes:\n- Only lines stocked in warehouses that track inventory allocations are considered.\n- Lines with any non-cancelled fulfillment activity are ineligible with reason \"Line has fulfillment activity — cannot unallocate\".\n- Lines without active allocations are ineligible with reason \"No active allocations to reverse\".\n- impact_quantity is the number of actively allocated units that would be released. Only active allocations are reversed — allocations already fulfilled or cancelled are untouched.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7118\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-unallocate/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-unallocate","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders\": [\n      {\n        \"sales_order_id\": 7116,\n        \"sales_order_number\": \"SO-7116\",\n        \"status\": null,\n        \"eligibility\": \"partially_eligible\",\n        \"reason\": null,\n        \"lines\": [\n          {\n            \"sales_order_line_id\": 90211,\n            \"product_sku\": \"WID-BLU-M\",\n            \"product_name\": \"Blue Widget (Medium)\",\n            \"warehouse_name\": \"Main Warehouse\",\n            \"eligible\": true,\n            \"reason\": null,\n            \"processable_quantity\": 5,\n            \"fulfilled_quantity\": 0,\n            \"currently_allocated\": 5,\n            \"impact_quantity\": 5\n          },\n          {\n            \"sales_order_line_id\": 90212,\n            \"product_sku\": \"WID-GRN-L\",\n            \"product_name\": \"Green Widget (Large)\",\n            \"warehouse_name\": \"Main Warehouse\",\n            \"eligible\": false,\n            \"reason\": \"Line has fulfillment activity — cannot unallocate\",\n            \"processable_quantity\": 3,\n            \"fulfilled_quantity\": 3,\n            \"currently_allocated\": 0,\n            \"impact_quantity\": 0\n          }\n        ]\n      },\n      {\n        \"sales_order_id\": 7118,\n        \"sales_order_number\": \"SO-7118\",\n        \"status\": null,\n        \"eligibility\": \"ineligible\",\n        \"reason\": \"No active allocations to reverse\",\n        \"lines\": [\n          {\n            \"sales_order_line_id\": 90410,\n            \"product_sku\": \"WID-RED-S\",\n            \"product_name\": \"Red Widget (Small)\",\n            \"warehouse_name\": \"Main Warehouse\",\n            \"eligible\": false,\n            \"reason\": \"No active allocations to reverse\",\n            \"processable_quantity\": 2,\n            \"fulfilled_quantity\": 0,\n            \"currently_allocated\": 0,\n            \"impact_quantity\": 0\n          }\n        ]\n      }\n    ],\n    \"totals\": {\n      \"orders_total\": 2,\n      \"orders_eligible\": 0,\n      \"orders_partially_eligible\": 1,\n      \"orders_ineligible\": 1,\n      \"lines_total\": 3,\n      \"lines_eligible\": 1,\n      \"lines_impact_quantity\": 5\n    }\n  }\n}"}]},{"name":"Bulk Unallocate Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-unallocate","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-unallocate"]},"description":"Starts an asynchronous bulk unallocate operation for the targeted sales orders and returns immediately with a `tracked_job_log_id` to poll for progress and results.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids` or `filters` is required):\n- ids (array of integers, required without `filters`): Sales order IDs to target. Each ID must exist.\n- filters (object or string, required without `ids`): Resolves to the matching sales order IDs — the same targeting the sales-orders list uses. Two shapes are accepted:\n  - Grouped filters: `{ \"filter_groups\": \"<base64-encoded JSON tree>\" }`. The decoded tree looks like `{\"conjunction\":\"and\",\"children\":[{\"type\":\"condition\",\"condition\":{\"column\":\"order_status\",\"operator\":\"is\",\"value\":\"open\"}}]}`.\n  - Legacy filter set (JSON string) for older clients.\n\nBehavior:\n- For each order, active inventory allocations on eligible lines are released. Lines with any non-cancelled fulfillment activity are skipped, as are lines with no active allocations. Allocations that are already fulfilled or cancelled are never touched.\n- The operation runs in the background. Poll the tracked job log endpoints with the returned ID for progress and the completion summary plus any per-order errors.\n- Call the preview endpoint (`POST /api/sales-orders/bulk-unallocate/preview`) first to see exactly which orders and lines will be affected.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7118\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-unallocate","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-unallocate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84292\n  },\n  \"message\": \"Bulk unallocate started. Track progress using the returned ID.\"\n}"}]},{"name":"Mark Sales Order as Printed","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/mark-as-printed","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","mark-as-printed"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Marks a sales order's packing slip as printed by setting the order's `packing_slip_printed_at` timestamp to the current time. Orders already marked as printed are simply re-stamped.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo request body.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.print`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/mark-as-printed","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","mark-as-printed"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The selected sales order fulfillment marked as printed successfully.\"\n}"}]},{"name":"Bulk Print Packing Slips","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-print-packing-slips","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-print-packing-slips"]},"description":"Generates packing slips for the targeted sales orders as a single merged PDF. The generation runs as an asynchronous background operation; the response returns a `tracked_job_log_id` to poll for progress, and the finished job's results contain the PDF download URL.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (one of `ids`, `filters`, or `apply_to_all` is required):\n- ids (array of integers, required without `filters`/`apply_to_all`): Sales order IDs to print. Each ID must exist.\n- filters (string, required without `ids`/`apply_to_all`): Legacy JSON-string filter payload; resolves to the matching sales order IDs.\n- apply_to_all (boolean, optional): When true, targets every order matching the request's active filters instead of an explicit ID list.\n- engine (string, optional, default `snappy`): PDF renderer — `snappy` (current pipeline) or `jasper` (legacy pipeline).\n\nBehavior:\n- Returns the tracked job log ID immediately; PDF generation runs in the background.\n- If the job finishes before the response is sent (small batches / fast queues), the response additionally includes `file` (the PDF download URL), `printed_count`, and `failed_count` so the file can be opened right away.\n- Otherwise, poll the tracked job log endpoints with the returned ID; the completed job's results include the download URL and per-order failures.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ],\n  \"engine\": \"snappy\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-print-packing-slips","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-print-packing-slips"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84310\n  },\n  \"message\": \"Packing slip generation started. Track progress in the job tray.\"\n}"}]},{"name":"List Sales Order Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Lists the notes on a sales order, newest first, as a paginated set (15 per page).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- page (integer, optional, default 1): Page number.\n\nEach note includes:\n- id (integer), note (string), is_pinned (boolean), created_at (date-time)\n- link_type / link_id: The sales order the note belongs to.\n- user_id (integer|null) and user (object|null): The note's author.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3412,\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 500,\n      \"user_id\": 7,\n      \"note\": \"Customer requested signature on delivery.\",\n      \"is_pinned\": false,\n      \"created_at\": \"2026-07-06T15:04:11.000000Z\",\n      \"user\": {\n        \"id\": 7,\n        \"name\": \"Jane Smith\",\n        \"email\": \"jane@example.com\"\n      }\n    },\n    {\n      \"id\": 3398,\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 500,\n      \"user_id\": 3,\n      \"note\": \"Confirmed replacement item with the customer by phone.\",\n      \"is_pinned\": true,\n      \"created_at\": \"2026-07-02T09:41:27.000000Z\",\n      \"user\": {\n        \"id\": 3,\n        \"name\": \"Sam Ortiz\",\n        \"email\": \"sam@example.com\"\n      }\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/sales-orders/500/notes?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/sales-orders/500/notes?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/sales-orders/500/notes\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Add Sales Order Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Adds a note to a sales order. The authenticated user is recorded as the note's author.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- note (string, required): The note text.\n\nBehavior:\n- The created note is returned with its author (`user`).\n- Notes are created unpinned; use the toggle-pin endpoint to pin one.\n- Adding a note queues the order's packing slip for regeneration so printed slips reflect the latest notes.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"note\": \"Customer requested signature on delivery.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"note\": \"Customer requested signature on delivery.\",\n    \"link_id\": 500,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"user_id\": 7,\n    \"created_at\": \"2026-07-06T15:04:11.000000Z\",\n    \"id\": 3412,\n    \"user\": {\n      \"id\": 7,\n      \"name\": \"Jane Smith\",\n      \"email\": \"jane@example.com\"\n    }\n  },\n  \"message\": \"The note created successfully\"\n}"}]},{"name":"Delete Sales Order Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes",":noteId"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"noteId","value":"3412","description":"Note ID"}]},"description":"Deletes a note from a sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBehavior:\n- The delete is idempotent — a 200 is returned even if the note no longer exists on the order.\n- Deleting a note queues the order's packing slip for regeneration so printed slips reflect the latest notes.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- noteId (required): Note ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes",":noteId"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"noteId","value":"3412","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The note 3412 deleted successfully\"\n}"}]},{"name":"Toggle Sales Order Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes",":noteId","toggle-pin"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"noteId","value":"3412","description":"Note ID"}]},"description":"Toggles the pinned state of a sales order note. Pinned notes surface at the top of the order's notes.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBehavior:\n- Flips `is_pinned` and returns the updated note with its author.\n- The response message is \"Note pinned\" or \"Note unpinned\" depending on the new state.\n- Returns 404 if the note does not exist on this sales order.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- noteId (required): Note ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","notes",":noteId","toggle-pin"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"noteId","value":"3412","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3412,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"link_id\": 500,\n    \"user_id\": 7,\n    \"note\": \"Customer requested signature on delivery.\",\n    \"is_pinned\": true,\n    \"created_at\": \"2026-07-06T15:04:11.000000Z\",\n    \"user\": {\n      \"id\": 7,\n      \"name\": \"Jane Smith\",\n      \"email\": \"jane@example.com\"\n    }\n  },\n  \"message\": \"Note pinned\"\n}"}]},{"name":"List Sales Order Discounts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Lists every discount applied to a sales order, ordered by `sequence` (the order in which discounts are applied). Includes line-level discounts — tied to a product line via `sales_order_line_id`, or to a charge line such as shipping via `financial_line_id` — and order-level discounts.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse fields (per discount):\n- id (integer): Discount ID.\n- sales_order_id (integer): Owning sales order.\n- sales_order_line_id (integer|null): Product line the discount applies to (line scope).\n- financial_line_id (integer|null): Charge line (e.g. shipping) the discount applies to (line scope).\n- scope (string): `line` or `order`.\n- type (string): `percentage` or `fixed_amount`.\n- rate (number|null): Percentage rate (0-100) for percentage discounts; null for fixed amounts.\n- amount (number): Discount total in the order currency. For percentage discounts this is the computed amount.\n- name (string): Display label.\n- source_type (string): Where the discount came from — `manual` for user-entered discounts, or a sales-channel identifier for imported ones.\n- source_id (integer|null), source_reference (string|null): External identifiers, e.g. a coupon code.\n- channel_discount_type (string|null), allocation_method (string|null), target_type (string|null): Raw sales-channel discount metadata, set only on imported discounts.\n- apply_before_tax (boolean): Whether the discount is applied before tax is calculated.\n- sequence (integer): Application order — lower values apply first.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"sales_order_id\": 500,\n      \"sales_order_line_id\": 8801,\n      \"financial_line_id\": null,\n      \"scope\": \"line\",\n      \"type\": \"percentage\",\n      \"rate\": 10,\n      \"amount\": 25.5,\n      \"name\": \"Loyalty discount\",\n      \"source_type\": \"manual\",\n      \"source_id\": null,\n      \"source_reference\": null,\n      \"channel_discount_type\": null,\n      \"allocation_method\": null,\n      \"target_type\": null,\n      \"apply_before_tax\": true,\n      \"sequence\": 0,\n      \"created_at\": \"2026-07-01T14:22:05.000000Z\",\n      \"updated_at\": \"2026-07-06T09:10:41.000000Z\"\n    },\n    {\n      \"id\": 13,\n      \"sales_order_id\": 500,\n      \"sales_order_line_id\": null,\n      \"financial_line_id\": null,\n      \"scope\": \"order\",\n      \"type\": \"fixed_amount\",\n      \"rate\": null,\n      \"amount\": 20,\n      \"name\": \"SUMMER20\",\n      \"source_type\": \"shopify\",\n      \"source_id\": 918273,\n      \"source_reference\": \"SUMMER20\",\n      \"channel_discount_type\": \"fixed_amount\",\n      \"allocation_method\": \"across\",\n      \"target_type\": \"line_item\",\n      \"apply_before_tax\": true,\n      \"sequence\": 1,\n      \"created_at\": \"2026-06-30T08:03:19.000000Z\",\n      \"updated_at\": \"2026-06-30T08:03:19.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Sales Order Discount","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Adds a discount to a sales order and recalculates the order's discount totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- scope (string, required): `line` (applies to one product line or charge line) or `order` (applies to the whole order).\n- type (string, required): `percentage` or `fixed_amount`.\n- rate (number, required when type is `percentage`): Percentage rate, 0-100.\n- amount (number, required when type is `fixed_amount`): Discount amount in the order currency, minimum 0. Defaults to 0 when omitted.\n- name (string, required, max 255): Display label.\n- sales_order_line_id (integer, required when scope is `line`): Existing product line on the order the discount applies to.\n- financial_line_id (integer, optional): Existing charge line (e.g. shipping) the discount applies to instead of a product line.\n- source_type (string, optional, max 50): Origin of the discount. Defaults to `manual`.\n- source_reference (string, optional, max 255): External reference such as a coupon code.\n- apply_before_tax (boolean, optional, default true): Whether the discount applies before tax is calculated.\n- sequence (integer, optional, min 0, default 0): Application order — lower values apply first.\n\nBehavior:\n- Creating a discount immediately recalculates the order: per-line discount totals, proportional allocation of order-level discounts across product lines (any rounding remainder goes to the largest line), and the order's denormalized discount totals.\n- For percentage discounts the effective `amount` is computed during this recalculation and returned in the response.\n- Order-level percentage discounts are based on the order subtotal after line discounts; tax is included in the base when the order is configured to discount the grand total.\n\nThe response is the created discount object (no envelope), returned with status 201.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"scope\": \"line\",\n  \"type\": \"percentage\",\n  \"rate\": 10,\n  \"name\": \"Loyalty discount\",\n  \"sales_order_line_id\": 8801,\n  \"apply_before_tax\": true,\n  \"sequence\": 0\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"sales_order_id\": 500,\n  \"sales_order_line_id\": 8801,\n  \"financial_line_id\": null,\n  \"scope\": \"line\",\n  \"type\": \"percentage\",\n  \"rate\": 10,\n  \"amount\": 25.5,\n  \"name\": \"Loyalty discount\",\n  \"source_type\": \"manual\",\n  \"source_id\": null,\n  \"source_reference\": null,\n  \"channel_discount_type\": null,\n  \"allocation_method\": null,\n  \"target_type\": null,\n  \"apply_before_tax\": true,\n  \"sequence\": 0,\n  \"created_at\": \"2026-07-01T14:22:05.000000Z\",\n  \"updated_at\": \"2026-07-06T09:10:41.000000Z\"\n}"}]},{"name":"Get Sales Order Discount","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]},"description":"Returns a single discount on a sales order. The response body is the discount object itself — it is not wrapped in a `data` envelope.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- discount (required): Discount ID.\n\nReturns 404 when the sales order or discount does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"sales_order_id\": 500,\n  \"sales_order_line_id\": 8801,\n  \"financial_line_id\": null,\n  \"scope\": \"line\",\n  \"type\": \"percentage\",\n  \"rate\": 10,\n  \"amount\": 25.5,\n  \"name\": \"Loyalty discount\",\n  \"source_type\": \"manual\",\n  \"source_id\": null,\n  \"source_reference\": null,\n  \"channel_discount_type\": null,\n  \"allocation_method\": null,\n  \"target_type\": null,\n  \"apply_before_tax\": true,\n  \"sequence\": 0,\n  \"created_at\": \"2026-07-01T14:22:05.000000Z\",\n  \"updated_at\": \"2026-07-06T09:10:41.000000Z\"\n}"}]},{"name":"Update Sales Order Discount","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]},"description":"Updates an existing discount on a sales order and recalculates the order's discount totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional — omitted fields keep their current values):\n- scope (string): `line` or `order`.\n- type (string): `percentage` or `fixed_amount`.\n- rate (number): Percentage rate, 0-100.\n- amount (number): Discount amount in the order currency, minimum 0.\n- name (string, max 255): Display label.\n- sales_order_line_id (integer): Existing product line the discount applies to.\n- financial_line_id (integer): Existing charge line the discount applies to.\n- source_type (string, max 50): Origin of the discount.\n- source_reference (string, max 255): External reference such as a coupon code.\n- apply_before_tax (boolean): Whether the discount applies before tax is calculated.\n- sequence (integer, min 0): Application order.\n\nBehavior:\n- The update triggers the same full discount recalculation as creating a discount — line totals, order-level allocation across lines, and the order's discount totals are refreshed.\n- For percentage discounts the effective `amount` is recomputed and returned in the response.\n\nThe response is the updated discount object (no envelope).\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- discount (required): Discount ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"rate\": 15,\n  \"name\": \"Loyalty discount (increased)\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"sales_order_id\": 500,\n  \"sales_order_line_id\": 8801,\n  \"financial_line_id\": null,\n  \"scope\": \"line\",\n  \"type\": \"percentage\",\n  \"rate\": 15,\n  \"amount\": 38.25,\n  \"name\": \"Loyalty discount (increased)\",\n  \"source_type\": \"manual\",\n  \"source_id\": null,\n  \"source_reference\": null,\n  \"channel_discount_type\": null,\n  \"allocation_method\": null,\n  \"target_type\": null,\n  \"apply_before_tax\": true,\n  \"sequence\": 0,\n  \"created_at\": \"2026-07-01T14:22:05.000000Z\",\n  \"updated_at\": \"2026-07-06T15:02:12.000000Z\"\n}"}]},{"name":"Delete Sales Order Discount","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]},"description":"Deletes a discount from a sales order and recalculates the order's discount totals (line totals, order-level allocation across lines, and the order's denormalized totals are refreshed without the removed discount).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- discount (required): Discount ID.\n\nReturns 404 when the sales order or discount does not exist.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/discounts/{discount}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","discounts",":discount"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"discount","value":"12","description":"Discount ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Discount deleted successfully.\"\n}"}]},{"name":"List Sales Order Financial Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Lists the financial lines attached to a sales order — shipping, handling, fees, and other non-product revenue or cost lines.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response body is a plain JSON array of financial line objects. It is NOT wrapped in a `data` envelope. Each line includes a nested `financial_line_type` object carrying the type's `classification` (`revenue` or `cost`).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- filter[financialLineType.classification] (string, optional): Restrict to lines whose type is classified `revenue` or `cost`.\n\nResponse fields (per line):\n- id (integer): Financial line ID.\n- financial_line_type_id (integer): The line type (e.g. Shipping, Handling).\n- link_type (string), link_id (integer): The owning document — always the sales order for this endpoint.\n- nominal_code_id (integer|null): Accounting nominal code.\n- description (string): Display description.\n- quantity (integer): Quantity.\n- amount (number): Unit amount in the order currency.\n- discount_rate (number): Fractional discount (0-1) applied to the extended amount.\n- extended_amount (number): Computed as quantity x amount x (1 - discount_rate).\n- tax_allocation (number): Tax amount attributed to this line.\n- tax_rate_id (integer|null), tax_rate (number): Tax rate reference and percentage.\n- allocate_to_products (boolean): Whether the line's value is prorated across the order's product lines.\n- proration_strategy (string): How the value is prorated — one of revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual.\n- allocate_to_id (integer|null), allocate_to_type (string|null): Target line when proration_strategy is specific_line.\n- sales_channel_line_id (string|null): Channel line reference for lines imported from a sales channel.\n- external_source_type (string|null), external_source_id (integer|null): External record that produced the line.\n- financial_line_type (object): `{id, classification}` of the line type.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 310,\n    \"financial_line_type_id\": 3,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"link_id\": 500,\n    \"nominal_code_id\": 41,\n    \"description\": \"Shipping\",\n    \"quantity\": 1,\n    \"amount\": 15,\n    \"discount_rate\": 0,\n    \"extended_amount\": 15,\n    \"tax_allocation\": 1.2375,\n    \"tax_rate_id\": 2,\n    \"tax_rate\": 8.25,\n    \"allocate_to_products\": true,\n    \"proration_strategy\": \"quantity_based\",\n    \"allocate_to_id\": null,\n    \"allocate_to_type\": null,\n    \"line_discounts\": null,\n    \"sales_channel_line_id\": null,\n    \"hash\": null,\n    \"external_source_type\": null,\n    \"external_source_id\": null,\n    \"created_at\": \"2026-07-01T14:22:05.000000Z\",\n    \"updated_at\": \"2026-07-06T09:10:41.000000Z\",\n    \"financial_line_type\": {\n      \"id\": 3,\n      \"classification\": \"revenue\"\n    }\n  },\n  {\n    \"id\": 311,\n    \"financial_line_type_id\": 9,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"link_id\": 500,\n    \"nominal_code_id\": null,\n    \"description\": \"Marketplace commission\",\n    \"quantity\": 1,\n    \"amount\": 8.7,\n    \"discount_rate\": 0,\n    \"extended_amount\": 8.7,\n    \"tax_allocation\": 0,\n    \"tax_rate_id\": null,\n    \"tax_rate\": 0,\n    \"allocate_to_products\": true,\n    \"proration_strategy\": \"revenue_based\",\n    \"allocate_to_id\": null,\n    \"allocate_to_type\": null,\n    \"line_discounts\": null,\n    \"sales_channel_line_id\": null,\n    \"hash\": null,\n    \"external_source_type\": null,\n    \"external_source_id\": null,\n    \"created_at\": \"2026-07-02T10:15:44.000000Z\",\n    \"updated_at\": \"2026-07-02T10:15:44.000000Z\",\n    \"financial_line_type\": {\n      \"id\": 9,\n      \"classification\": \"cost\"\n    }\n  }\n]"}]},{"name":"Create Sales Order Financial Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Adds a financial line (shipping, handling, fee, or other non-product revenue/cost line) to a sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- financial_line_type_id (integer, required): Existing financial line type.\n- amount (number, required, min 0): Unit amount in the order currency.\n- description (string, optional): Display description. Defaults to the line type's name when omitted.\n- quantity (integer, optional, min 1): Quantity.\n- discount_rate (number, optional, 0-1): Fractional discount applied to the extended amount.\n- tax_allocation (number, optional, min 0): Tax amount for the line. When omitted and a tax_rate is set, it is computed automatically from the extended amount (and backed out of the amount on tax-inclusive orders).\n- tax_rate_id (integer, optional): Existing tax rate.\n- tax_rate (number, optional, min 0): Tax percentage used for the automatic tax_allocation computation.\n- allocate_to_products (boolean, optional): Whether the line's value is prorated across the order's product lines. Defaults from the line type.\n- proration_strategy (string, optional): One of revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual. Defaults from the line type.\n- allocate_to_id (integer, optional), allocate_to_type (string, optional): The specific line to allocate to when proration_strategy is specific_line.\n- nominal_code_id (integer, optional): Existing accounting nominal code. Defaults from the line type.\n\nThe response is the created financial line as a bare JSON object (no envelope), returned with status 201. Computed columns such as extended_amount appear when the line is next read via the list endpoint.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"financial_line_type_id\": 3,\n  \"description\": \"Shipping\",\n  \"quantity\": 1,\n  \"amount\": 15,\n  \"tax_rate_id\": 2,\n  \"tax_rate\": 8.25,\n  \"nominal_code_id\": 41,\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"quantity_based\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"financial_line_type_id\": 3,\n  \"nominal_code_id\": 41,\n  \"description\": \"Shipping\",\n  \"quantity\": 1,\n  \"amount\": 15,\n  \"tax_rate_id\": 2,\n  \"tax_rate\": 8.25,\n  \"proration_strategy\": \"quantity_based\",\n  \"allocate_to_products\": true,\n  \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n  \"link_id\": 500,\n  \"tax_allocation\": 1.2375,\n  \"updated_at\": \"2026-07-06T14:22:05.000000Z\",\n  \"created_at\": \"2026-07-06T14:22:05.000000Z\",\n  \"id\": 310\n}"}]},{"name":"Update Sales Order Financial Line","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines/{financialLine}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines",":financialLine"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"financialLine","value":"310","description":"Financial line ID"}]},"description":"Updates a financial line on a sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns `true` on success — the response body is literally the JSON boolean `true`, not the updated record. Re-read the line via the list endpoint to see the stored values.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional on update — same meanings as on create):\n- financial_line_type_id (integer): Existing financial line type.\n- amount (number, min 0): Unit amount in the order currency.\n- description (string): Display description.\n- quantity (integer, min 1): Quantity.\n- discount_rate (number, 0-1): Fractional discount applied to the extended amount.\n- tax_allocation (number, min 0): Tax amount for the line; recomputed from tax_rate when not explicitly provided.\n- tax_rate_id (integer): Existing tax rate.\n- tax_rate (number, min 0): Tax percentage.\n- allocate_to_products (boolean): Whether the line's value is prorated across product lines.\n- proration_strategy (string): One of revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual.\n- allocate_to_id (integer), allocate_to_type (string): Target line when proration_strategy is specific_line.\n- nominal_code_id (integer): Existing accounting nominal code.\n\nImportant — omitted nullable fields are cleared:\n- If you do not send nominal_code_id, allocate_to_id, or allocate_to_type, they are reset to null on the line.\n- Channel and external source references on the line (sales_channel_line_id, external_source_type, external_source_id) are also cleared by every update.\n- Send every value you want to keep.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- financialLine (required): Financial line ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"financial_line_type_id\": 3,\n  \"description\": \"Shipping (expedited)\",\n  \"quantity\": 1,\n  \"amount\": 22.5,\n  \"tax_rate_id\": 2,\n  \"tax_rate\": 8.25,\n  \"nominal_code_id\": 41,\n  \"allocate_to_products\": true,\n  \"proration_strategy\": \"quantity_based\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines/{financialLine}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines",":financialLine"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"financialLine","value":"310","description":"Financial line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"true"}]},{"name":"Delete Sales Order Financial Line","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines/{financialLine}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines",":financialLine"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"financialLine","value":"310","description":"Financial line ID"}]},"description":"Deletes a financial line from a sales order. The order's product-line financial figures are flagged for recalculation so the removed amount drops out of prorated revenue/cost on the next computation.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 204 No Content with an empty body on success.\n\nAuthentication: Requires Bearer token.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n- financialLine (required): Financial line ID.\n\nReturns 404 when the sales order or financial line does not exist.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financial-lines/{financialLine}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financial-lines",":financialLine"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"},{"key":"financialLine","value":"310","description":"Financial line ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Sales Order Accounting Transaction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/accounting","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","accounting"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Gets the accounting transaction (invoice journal) generated for a sales order, including its lines with nominal codes and tax rates, any child transactions, and a summary of its parent batch transaction. Returns `data: null` when no accounting transaction has been generated for the order yet.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse fields:\n- id (integer), transaction_date (date-time), reference (string): The order number the transaction posts against.\n- type (object): name (e.g. `sales_order_invoice`), link_type / link_id (the source record), link_type_label (human-friendly label), link_route (in-app path to the source record).\n- name (string|null): The counterparty name (customer).\n- integration_invoice_number_override (string|null): Invoice number override used when posting to the accounting integration.\n- is_tax_included (boolean), total (number).\n- parent_type (object): Summary of the parent batch transaction; all values are null when the transaction has no parent.\n- children (array): Child transactions in the same structure (e.g. fulfillment journals), empty when none.\n- last_synced_at (date-time|null) and link (string|null): Last sync time and deep link into the connected accounting system, present when an accounting integration is connected.\n- last_sync_error (string|object|null): The most recent sync error, if any.\n- is_sync_enabled (boolean): Whether this transaction is allowed to sync.\n- is_type_sync_enabled (boolean): Whether this transaction type is enabled in the accounting sync settings.\n- lines (array): id, type (`debit` or `credit`), nominal_code {id, code, name}, description, quantity, amount (unit amount), subtotal (amount x quantity), tax_amount, tax {id, name, rate} (null when no tax rate applies), created_at, updated_at.\n- status (string): `toSync`, `synced`, `hasErrors`, `submissionInProgress`, or `ineligibleToSync`.\n- is_locked (boolean): Locked transactions cannot be regenerated or edited.\n- is_batchable (boolean), created_at, updated_at.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/accounting","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","accounting"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9210,\n    \"transaction_date\": \"2026-06-18T00:00:00.000000Z\",\n    \"type\": {\n      \"name\": \"sales_order_invoice\",\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 500,\n      \"link_type_label\": \"Sales Order Invoice\",\n      \"link_route\": \"/orders/sales-orders/500\"\n    },\n    \"integration_invoice_number_override\": null,\n    \"name\": \"Acme Retail Group\",\n    \"is_tax_included\": false,\n    \"total\": 258.9,\n    \"reference\": \"SO-0158\",\n    \"parent_type\": {\n      \"id\": null,\n      \"reference\": null,\n      \"name\": null,\n      \"link_type\": null,\n      \"link_id\": null,\n      \"link_type_label\": null,\n      \"link_route\": null\n    },\n    \"children\": [],\n    \"last_synced_at\": \"2026-06-18T14:22:05.000000Z\",\n    \"link\": \"https://app.qbo.intuit.com/app/invoice?txnId=145\",\n    \"last_sync_error\": null,\n    \"is_sync_enabled\": true,\n    \"is_type_sync_enabled\": true,\n    \"lines\": [\n      {\n        \"id\": 30411,\n        \"type\": \"credit\",\n        \"nominal_code\": {\n          \"id\": 12,\n          \"code\": \"4000\",\n          \"name\": \"Sales Revenue\"\n        },\n        \"description\": \"Blue Widget (Medium) x 5\",\n        \"quantity\": 5,\n        \"amount\": 45,\n        \"subtotal\": 225,\n        \"tax_amount\": 18.9,\n        \"tax\": {\n          \"id\": 4,\n          \"name\": \"CA Sales Tax\",\n          \"rate\": 8.4\n        },\n        \"updated_at\": \"2026-06-18T14:22:05.000000Z\",\n        \"created_at\": \"2026-06-18T14:20:44.000000Z\"\n      },\n      {\n        \"id\": 30412,\n        \"type\": \"credit\",\n        \"nominal_code\": {\n          \"id\": 18,\n          \"code\": \"4400\",\n          \"name\": \"Shipping Income\"\n        },\n        \"description\": \"Shipping\",\n        \"quantity\": 1,\n        \"amount\": 15,\n        \"subtotal\": 15,\n        \"tax_amount\": 0,\n        \"tax\": null,\n        \"updated_at\": \"2026-06-18T14:22:05.000000Z\",\n        \"created_at\": \"2026-06-18T14:20:44.000000Z\"\n      }\n    ],\n    \"status\": \"synced\",\n    \"is_locked\": false,\n    \"is_batchable\": true,\n    \"updated_at\": \"2026-06-18T14:22:05.000000Z\",\n    \"created_at\": \"2026-06-18T14:20:44.000000Z\"\n  }\n}"}]},{"name":"Generate Sales Order Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","generate-accounting-transaction"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Generates — or regenerates — the accounting transaction (invoice journal) for a sales order from its current lines and financial data. Use this after correcting an order to refresh the journal without waiting for the next scheduled accounting sync.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBehavior:\n- No request body is required.\n- The response returns the generated transaction with its lines and nominal codes. Tax rate details, parent/children, and accounting-integration sync metadata are not expanded on this response — fetch `GET /api/sales-orders/{salesOrder}/accounting` for the fully expanded transaction.\n- Regeneration replaces the transaction's lines to match the order's current state.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","generate-accounting-transaction"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9210,\n    \"transaction_date\": \"2026-07-06T00:00:00.000000Z\",\n    \"type\": {\n      \"name\": \"sales_order_invoice\",\n      \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"link_id\": 500,\n      \"link_type_label\": \"Sales Order Invoice\",\n      \"link_route\": \"/orders/sales-orders/500\"\n    },\n    \"integration_invoice_number_override\": null,\n    \"name\": \"Acme Retail Group\",\n    \"is_tax_included\": false,\n    \"total\": 258.9,\n    \"reference\": \"SO-0158\",\n    \"last_sync_error\": null,\n    \"is_sync_enabled\": true,\n    \"is_type_sync_enabled\": true,\n    \"lines\": [\n      {\n        \"id\": 30411,\n        \"type\": \"credit\",\n        \"nominal_code\": {\n          \"id\": 12,\n          \"code\": \"4000\",\n          \"name\": \"Sales Revenue\"\n        },\n        \"description\": \"Blue Widget (Medium) x 5\",\n        \"quantity\": 5,\n        \"amount\": 45,\n        \"subtotal\": 225,\n        \"tax_amount\": 18.9,\n        \"updated_at\": \"2026-07-06T16:10:02.000000Z\",\n        \"created_at\": \"2026-06-18T14:20:44.000000Z\"\n      }\n    ],\n    \"status\": \"toSync\",\n    \"is_locked\": false,\n    \"is_batchable\": true,\n    \"updated_at\": \"2026-07-06T16:10:02.000000Z\",\n    \"created_at\": \"2026-06-18T14:20:44.000000Z\"\n  },\n  \"message\": \"Accounting transaction generated successfully.\"\n}"}]},{"name":"Recalculate Sales Order Financials","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/recalculate-financials","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","recalculate-financials"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Recalculates the line-level financial figures (revenue, cost of goods sold, fees, and profit) for every line on the sales order and refreshes the dependent daily financial aggregates.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBehavior:\n- No request body is required.\n- The recalculation normally runs synchronously under a short per-order lock so concurrent recalculations do not conflict.\n- If another recalculation currently holds the lock, the order's lines are flagged for recalculation and picked up in the background instead; the response is still a 200.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/recalculate-financials","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","recalculate-financials"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Financials recalculated successfully.\"\n}"}]},{"name":"Get Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns core sales order data for the V2 show page. Includes essential fields, addresses, channel info, totals, counts, custom fields, financial lines, tags, discounts, credits, RMAs, and purchase orders.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nLine items are loaded separately via the lineItems endpoint for parallel loading.\n\nAlso returns the top-level flag `use_sales_order_line_nominal_codes` (boolean) — sibling to `data` — indicating whether the per-line nominal code editor should be enabled in the UI. Mirrors the `accounting.use_sales_order_line_nominal_codes` config value.\n\nPayment / credit totals:\n- `total_paid`: aggregated sum of `payments.amount` for the order — lets the UI render Paid/Balance Due without lazy-loading the payments array.\n- Each entry in `sales_credits[]` includes `refund_payments_total` (sum of cash/card refunds against the credit, always positive), `applied_to_other_total` (sum of credit consumed by Loop Returns EXC-* exchange orders, always positive), `fees_retained_total` (sum of fees Loop withheld out of the customer's credit — return shipping, restocking, etc., always positive), and `outstanding_amount` (= total − refund_payments_total − applied_to_other_total − fees_retained_total, clamped to zero). The frontend uses `outstanding_amount` for the Credits line so partially-refunded credits no longer double-count against Balance Due. Each credit also includes `metadata` (nullable object) — a minimal source subset `{source, sales_channel_refund_id}` used to render the channel-source chip (e.g. eBay refund-synced credits); null for manually created credits.\n\nAuthentication: Requires Bearer token.\n\n**Address override fields:** `shipping_overridden_at` is an ISO-8601 UTC timestamp (or null) set when an operator manually corrects the ship-to/billing address; `is_shipping_overridden` is the boolean equivalent. When set, sales-channel resyncs (e.g. Amazon) will not overwrite the corrected inline address columns."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-20240115-500\",\n    \"order_status\": \"fulfilled\",\n    \"order_date\": \"2024-01-15\",\n    \"ship_by_date\": \"2024-01-20\",\n    \"deliver_by_date\": \"2024-01-25\",\n    \"hold_until_date\": \"2024-01-18\",\n    \"customer_id\": 10,\n    \"customer\": {\n      \"id\": 10,\n      \"name\": \"Acme Corp\"\n    },\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_channel\": {\n      \"id\": 5,\n      \"name\": \"Shopify Store\"\n    },\n    \"shipping_address\": {\n      \"name\": \"John Doe\",\n      \"address1\": \"456 Ship Lane\",\n      \"city\": \"Los Angeles\",\n      \"province\": \"California\",\n      \"zip\": \"90001\",\n      \"country\": \"United States\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"billing_address\": {\n      \"name\": \"Acme Corp\",\n      \"address1\": \"123 Main St\"\n    },\n    \"subtotal\": \"89.97\",\n    \"tax_total\": \"7.65\",\n    \"total\": \"97.62\",\n    \"currency\": {\n      \"code\": \"USD\"\n    },\n    \"notes_count\": 2,\n    \"payments_count\": 1,\n    \"total_paid\": 97.62,\n    \"sales_order_fulfillments_count\": 1,\n    \"activities_count\": 5,\n    \"tags\": [\n      {\n        \"id\": 3,\n        \"name\": \"priority\"\n      }\n    ],\n    \"discounts\": [],\n    \"sales_credits\": [\n      {\n        \"id\": 55,\n        \"sales_credit_number\": \"SC-00055\",\n        \"credit_date\": \"2024-01-20\",\n        \"total\": 30,\n        \"refund_payments_total\": 14.4,\n        \"applied_to_other_total\": 4.09,\n        \"fees_retained_total\": 0,\n        \"outstanding_amount\": 11.51,\n        \"statuses\": {\n          \"credit_status\": \"open\"\n        },\n        \"metadata\": {\n          \"source\": \"ebay\",\n          \"sales_channel_refund_id\": \"5000012345\"\n        }\n      }\n    ],\n    \"purchase_orders\": [],\n    \"created_at\": \"2024-01-15T08:00:00.000000Z\",\n    \"updated_at\": \"2024-01-18T14:00:00.000000Z\",\n    \"incoterm_id\": 4,\n    \"incoterm_place\": \"Rotterdam\",\n    \"incoterm_version\": 2020,\n    \"incoterm_code\": \"DAP\",\n    \"incoterm_display\": \"DAP Rotterdam, Incoterms 2020\",\n    \"importer_of_record\": \"Buyer\",\n    \"seller_must_insure\": false,\n    \"incoterm\": {\n      \"id\": 4,\n      \"code\": \"DAP\",\n      \"name\": \"Delivered at Place\",\n      \"transport_mode\": \"any\",\n      \"family\": \"D\",\n      \"seller_pays_main_carriage\": true,\n      \"export_cleared_by\": \"seller\",\n      \"import_cleared_by\": \"buyer\",\n      \"seller_insurance\": \"none\",\n      \"risk_transfer_point\": \"At the named destination, on the arriving vehicle ready for unloading.\",\n      \"is_standard\": true,\n      \"is_deprecated\": false,\n      \"sort_order\": 9\n    }\n  },\n  \"use_sales_order_line_nominal_codes\": false\n}"}]},{"name":"Get Sales Order Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns the complete order graph for a single sales order: header fields, line items with inventory and cost-of-goods breakdowns, fulfillments (with shipment lines and tracking), payments, notes, financial lines, discounts, addresses, linked purchase orders, and backorder coverage dates.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis is the full detail endpoint. For a lighter order summary, use `GET /api/v2/sales-orders/{id}` instead.\n\nAuthentication: Requires Bearer token.\n\nResponse notes:\n- `item_info` contains the order lines, each with allocation/fulfillment quantities, product info, warehouse, per-warehouse inventory, and a `cogs` object aggregating the inventory cost layers consumed by the line.\n- `fulfillment` contains the order's shipments, each with its shipment lines, tracking, warehouse, and provider sync timestamps.\n- `sales_order_shipping_address` / `sales_order_billing_address` are the order's own address snapshots (they survive later edits to the underlying address records).\n- `customer_name`, `customer_email`, `customer_company`, `customer_phone` render the order's buyer snapshot; channel orders without a stored customer record still populate these.\n- Monetary totals (`total`, `product_total`, `tax_total`, `discount_total`, etc.) are in the order currency.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-0158\",\n    \"customer_po_number\": \"PO-88213\",\n    \"sales_channel_id\": 3,\n    \"sales_channel_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": null,\n    \"sub_sales_channel\": null,\n    \"sub_sales_channel_name\": null,\n    \"integration_instance_id\": 2,\n    \"integration\": \"Shopify\",\n    \"integration_id\": 4,\n    \"integration_image\": \"https://cdn.sku.io/integrations/shopify.png\",\n    \"can_submit_fulfillments_to_channel\": true,\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_rep_id\": null,\n    \"sales_rep\": null,\n    \"accounting\": {\n      \"transaction\": null\n    },\n    \"order_date\": \"2026-06-18T14:23:11.000000Z\",\n    \"payment_date\": \"2026-06-18T14:25:02.000000Z\",\n    \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n    \"updated_at\": \"2026-06-20T09:12:44.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"discounts\": [],\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": \"2026-06-19T16:40:21.000000Z\",\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"has_backorder\": false,\n    \"fulfillment\": [\n      {\n        \"id\": 91,\n        \"fulfillment_number\": \"SO-0158-F1\",\n        \"sales_order_id\": 500,\n        \"fulfillment_order_id\": 120,\n        \"fulfillment_type\": \"shipstation\",\n        \"fulfillment_status\": \"fulfilled\",\n        \"shipping_method_id\": 7,\n        \"requested_shipping_method\": \"Standard Shipping\",\n        \"requested_shipping_method_id\": 7,\n        \"fulfilled_shipping_method\": null,\n        \"fulfilled_shipping_method_id\": null,\n        \"fulfilled_date\": \"2026-06-19T16:40:21.000000Z\",\n        \"tracking_number\": \"9405511899561234567890\",\n        \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9405511899561234567890\",\n        \"tracking_link\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9405511899561234567890\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"supplier_id\": null,\n          \"is_dropship\": false\n        },\n        \"warehouse_id\": 3,\n        \"fulfilled_by\": {\n          \"id\": 4,\n          \"name\": \"Alex Rivera\"\n        },\n        \"fulfilled_quantity\": 3,\n        \"fulfillment_lines\": [\n          {\n            \"id\": 301,\n            \"sales_order_line_id\": 2101,\n            \"sales_order_fulfillment_id\": 91,\n            \"quantity\": 2,\n            \"unit_cost\": 11.42,\n            \"metadata\": null,\n            \"sales_order_line\": {\n              \"id\": 2101,\n              \"product_id\": 812,\n              \"quantity\": 2,\n              \"amount\": 25.99,\n              \"description\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n              \"warehouse_id\": 3,\n              \"product\": {\n                \"id\": 812,\n                \"sku\": \"WB-32-BLU\",\n                \"name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n                \"weight\": 1.2,\n                \"weight_unit\": \"lb\",\n                \"height\": 11,\n                \"width\": 3.5,\n                \"length\": 3.5,\n                \"dimension_unit\": \"in\",\n                \"is_lot_tracked\": false,\n                \"lot_tracking_method\": null,\n                \"shelf_life_days\": null,\n                \"near_expiry_threshold_days\": null,\n                \"min_remaining_shelf_life_days\": null\n              }\n            }\n          },\n          {\n            \"id\": 302,\n            \"sales_order_line_id\": 2102,\n            \"sales_order_fulfillment_id\": 91,\n            \"quantity\": 1,\n            \"unit_cost\": 3.8,\n            \"metadata\": null,\n            \"sales_order_line\": {\n              \"id\": 2102,\n              \"product_id\": 954,\n              \"quantity\": 1,\n              \"amount\": 9.5,\n              \"description\": \"Bottle Cleaning Brush Kit\",\n              \"warehouse_id\": 3,\n              \"product\": {\n                \"id\": 954,\n                \"sku\": \"BR-KIT-01\",\n                \"name\": \"Bottle Cleaning Brush Kit\",\n                \"weight\": 0.3,\n                \"weight_unit\": \"lb\",\n                \"height\": 8,\n                \"width\": 4,\n                \"length\": 2,\n                \"dimension_unit\": \"in\",\n                \"is_lot_tracked\": false,\n                \"lot_tracking_method\": null,\n                \"shelf_life_days\": null,\n                \"near_expiry_threshold_days\": null,\n                \"min_remaining_shelf_life_days\": null\n              }\n            }\n          }\n        ],\n        \"cost\": 6.42,\n        \"status\": \"fulfilled\",\n        \"voided_at\": null,\n        \"void_reason\": null,\n        \"voided_by\": null,\n        \"fulfilled_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"marked_for_pickup_at\": null,\n        \"marked_for_pickup_by\": null,\n        \"expected_pickup_at\": null,\n        \"packing_slip_printed_at\": null,\n        \"submitted_to_sales_channel_at\": \"2026-06-19T16:41:03.000000Z\",\n        \"last_synced_to_provider_at\": \"2026-06-19T16:40:25.000000Z\",\n        \"last_synced_from_provider_at\": \"2026-06-19T18:02:10.000000Z\",\n        \"metadata\": null,\n        \"fulfillment_sequence\": 1,\n        \"is_parent\": false,\n        \"parent_id\": null,\n        \"created_at\": \"2026-06-19T09:15:02.000000Z\",\n        \"provider_order_id\": \"SS-40912311\",\n        \"sales_channel_fulfillment_link\": null\n      }\n    ],\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 2101,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 11.42,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 2,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 2,\n        \"item_on_hand_allocated_quantity\": 2,\n        \"item_unallocated_quantity\": 0,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 2,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 812,\n          \"sku\": \"WB-32-BLU\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345678905,\n        \"item_weight\": 1.2,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 25.99,\n        \"item_price_with_tax\": 25.99,\n        \"item_name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 51.98,\n        \"price_after_line_discount\": 25.99,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 51.98,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": true,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 0,\n        \"remaining_to_fulfill_quantity\": 0,\n        \"available_to_fulfill\": 0,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 2,\n        \"inventory_allocation_id\": 5120,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": {\n          \"base_unit_cost\": 11.42,\n          \"cost_lines_total\": 0,\n          \"cost_lines\": [],\n          \"landed_costs_total\": 0,\n          \"landed_costs\": [],\n          \"unallocated_total\": 0,\n          \"unallocated\": [],\n          \"fifo_layers\": [\n            {\n              \"fifo_layer_id\": 3301,\n              \"fifo_layer_date\": \"2026-05-02\",\n              \"quantity\": 2,\n              \"source_label\": \"PO Receipt\",\n              \"source_id\": 1207,\n              \"unit_cost\": 11.42\n            }\n          ],\n          \"total_cost\": 22.84,\n          \"unit_cost\": 11.42,\n          \"is_finalized\": true\n        },\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/wb-32-blu.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 24,\n            \"stock\": 150,\n            \"allocated\": 2,\n            \"on_hold\": 0,\n            \"available\": 148,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 24,\n              \"stock\": 150,\n              \"allocated\": 2,\n              \"on_hold\": 0,\n              \"available\": 148,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 148\n      },\n      {\n        \"sales_order_line_id\": 2102,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 3.8,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 1,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 1,\n        \"item_on_hand_allocated_quantity\": 1,\n        \"item_unallocated_quantity\": 0,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 1,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 954,\n          \"sku\": \"BR-KIT-01\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345671231,\n        \"item_weight\": 0.3,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 9.5,\n        \"item_price_with_tax\": 9.5,\n        \"item_name\": \"Bottle Cleaning Brush Kit\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 9.5,\n        \"price_after_line_discount\": 9.5,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 9.5,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": true,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 0,\n        \"remaining_to_fulfill_quantity\": 0,\n        \"available_to_fulfill\": 0,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 1,\n        \"inventory_allocation_id\": 5121,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": {\n          \"base_unit_cost\": 3.8,\n          \"cost_lines_total\": 0,\n          \"cost_lines\": [],\n          \"landed_costs_total\": 0,\n          \"landed_costs\": [],\n          \"unallocated_total\": 0,\n          \"unallocated\": [],\n          \"fifo_layers\": [\n            {\n              \"fifo_layer_id\": 3312,\n              \"fifo_layer_date\": \"2026-05-02\",\n              \"quantity\": 1,\n              \"source_label\": \"PO Receipt\",\n              \"source_id\": 1207,\n              \"unit_cost\": 3.8\n            }\n          ],\n          \"total_cost\": 3.8,\n          \"unit_cost\": 3.8,\n          \"is_finalized\": true\n        },\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/br-kit-01.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 0,\n            \"stock\": 61,\n            \"allocated\": 1,\n            \"on_hold\": 0,\n            \"available\": 60,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 0,\n              \"stock\": 61,\n              \"allocated\": 1,\n              \"on_hold\": 0,\n              \"available\": 60,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 60\n      }\n    ],\n    \"purchase_orders\": [],\n    \"adjustments\": [],\n    \"financial_lines\": [\n      {\n        \"id\": 610,\n        \"description\": \"Shipping\",\n        \"quantity\": 1,\n        \"amount\": 6.99,\n        \"extended_amount\": 6.99,\n        \"discount_rate\": 0,\n        \"amount_in_tenant_currency\": 6.99,\n        \"tax_allocation\": 0,\n        \"tax_allocation_in_tenant_currency\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"allocate_to_products\": false,\n        \"proration_strategy\": null,\n        \"allocate_to_id\": null,\n        \"allocate_to_type\": null,\n        \"link_type\": null,\n        \"link_id\": null,\n        \"financial_line_type\": {\n          \"id\": 2,\n          \"name\": \"Shipping\",\n          \"classification\": \"revenue\",\n          \"nominal_code_id\": 12\n        },\n        \"nominal_code\": {\n          \"id\": 12,\n          \"name\": \"Shipping Income\",\n          \"code\": \"4020\"\n        },\n        \"credited_amount\": 0,\n        \"remaining_amount\": 6.99\n      }\n    ],\n    \"custom_field_values\": [],\n    \"order_status\": \"closed\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"fulfillment_sequence\": 1,\n    \"payment_status\": \"paid\",\n    \"tax_revenue\": 4.11,\n    \"product_total\": 61.48,\n    \"total\": 63.08,\n    \"discount_total\": 0.95,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"wholesale\"\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    ],\n    \"can_fulfill\": false,\n    \"exact_discount_total\": 0.95,\n    \"is_tax_included\": false,\n    \"tax_total\": 4.11,\n    \"calculated_tax_total\": 4.11,\n    \"exact_tax_total\": 4.11,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"payments\": [\n      {\n        \"id\": 77,\n        \"amount\": 63.08,\n        \"cost\": 1.86,\n        \"payment_date\": \"2026-06-18T14:25:02.000000Z\",\n        \"payment_type\": {\n          \"id\": 2,\n          \"name\": \"Credit Card\"\n        },\n        \"external_reference\": \"ch_3PQx8L2eZvKYlo2C1kT9qXaB\",\n        \"type\": \"payment\",\n        \"currency_code\": \"USD\",\n        \"sales_credit_allocation\": null\n      }\n    ],\n    \"notes\": [\n      {\n        \"id\": 44,\n        \"note\": \"Customer asked for the package to be left at the side door.\",\n        \"created_at\": \"2026-06-18T15:02:40.000000Z\",\n        \"user_name\": \"Alex Rivera\"\n      }\n    ],\n    \"earliest_covered_ship_by_date\": null,\n    \"latest_covered_ship_by_date\": null,\n    \"has_backorder_lines\": false\n  }\n}"}]},{"name":"Update Sales Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Updates a sales order. Accepts a partial payload — only the provided fields are applied.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nCommon use cases:\n- Reopen a closed order: send `{\"order_status\": \"open\", \"force_reopen\": true}`\n- Close an open order: send `{\"order_status\": \"closed\"}`\n- Cancel an order: send `{\"canceled_at\": \"2026-05-08T12:00:00Z\"}`\n- Update lines, addresses, or other fields by including only the keys you want to change.\n\nReopen behavior (force_reopen):\n- A closed order is normally not reopened by `order_status: open` if its `fulfillment_status` is `fulfilled` or `over_fulfilled`. This guard suppresses spurious reopens from sales-channel sync paths (e.g. Walmart Seller-Fulfilled \"Shipped\") that would leave the order stuck in `open` after `updateFulfillmentStatus` runs.\n- Manual UI reopens express explicit user intent and pass `force_reopen: true` to bypass the guard.\n\nSelected request body fields (all optional unless noted):\n- order_status (string): One of draft, open, reserved, closed, cancelled, refunded, completed.\n- force_reopen (bool, default false): When true, allow reopening a closed order even if it is fulfilled / over-fulfilled. Only meaningful when `order_status: open` is sent on a currently `closed` order.\n- fulfillment_status (string): unfulfilled, partially_fulfilled, fulfilled, over_fulfilled, out_of_sync.\n- payment_status (string|null): unpaid, partially_paid, paid, refunded.\n- canceled_at (date-time|null): Cancel the order by setting; uncancel by setting to null.\n- sales_order_number (string), customer_po_number (string|null), order_date (date), payment_date (date|null), ship_by_date (date|null), hold_until_date (date|null) — \"do not ship before\" release date for preorders / holds, deliver_by_date (date|null), fulfilled_at (date-time|null), tracking_number (string|null).\n- store_id (int|null), sales_channel_id (int), shipping_method_id (int|null), customer_id (int|null), sales_rep_id (int|null), sales_rep_name (string|null), shipping_address_id (int|null), billing_address_id (int|null), currency_id (int), currency_code (string|null), tax_rate_id (int|null), sub_sales_channel_id (int|null).\n- requested_shipping_method (string|null), packing_slip_printed_at (date-time|null), last_synced_from_sales_channel_at (date-time|null), is_tax_included (bool|null).\n- tags (array|null), discount_lines (array|null), sales_order_lines (array of SalesOrderLineData), financial_lines (array of FinancialLineData), custom_field_values (array), notes (array of NoteData), customer (CustomerData|null), shipping_address (AddressData|null), billing_address (AddressData|null).\n- Quote fields: is_quote (bool), memo_for_customer (string|null), quote_sent_at (date-time|null), quote_approved_by_customer_at (date-time|null), quote_expires_at (date-time|null).\n- Behavioral flags: shouldDeleteFulfillments (bool, default false), shippingAddressChanged (bool, default false), on_hold (bool, default false), deleteFulfillmentsReason (string).\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"order_status\": \"open\",\n  \"force_reopen\": true,\n  \"incoterm_id\": 12,\n  \"incoterm_place\": \"Port of Los Angeles, CA\",\n  \"incoterm_version\": 2020\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order ':id' updated successfully\",\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-0158\",\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"payment_status\": null,\n    \"order_date\": \"2026-05-06T00:00:00.000000Z\",\n    \"canceled_at\": null,\n    \"updated_at\": \"2026-05-08T17:14:33.000000Z\"\n  }\n}"}]},{"name":"Delete Sales Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Deletes a sales order along with its dependent records (lines, fulfillments, allocations, payments). Inventory consumed by the order is released back to stock.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe order cannot be deleted when any of its return receipts produced inventory that has already been consumed by other transactions — deleting it would orphan those downstream costs. In that case the request fails with 422 and the response `data` details which return receipts and quantities are blocking the delete.\n\nUse `POST /api/sales-orders/deletable` to pre-check deletability, and the bulk delete endpoints to remove many orders in the background.\n\nAuthentication: Requires Bearer token.\n\nPath parameters:\n- salesOrder (required): Sales order ID.\n\n**Requires permission:** `sales_orders.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order SO-0158 deleted successfully\"\n}"}]},{"name":"Get Sales Order Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/line-items","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","line-items"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns line items with full product details, inventory, allocations, and warehouse info. Pre-loads realtime inventory for all products in a single query. Loaded in parallel with show.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUnmapped channel lines (product_id is null) include a `listing` object describing the raw sales-channel listing (Amazon, Shopify, eBay, WooCommerce) used by the \"Link Line Item to Product\" modal. For Amazon lines whose seller SKU matches a synced AmazonProduct, the `listing` object also includes the internal `id` and `integration_instance_id`, which the UI uses to deep-link to the Amazon product detail page.\n\nEach line item includes `bundle_proration_basis` (\"cost\" | \"price\" | \"quantity\" | null). For bundle component lines this indicates the methodology used to prorate the bundle’s price across its components: \"cost\" — proportional to component unit costs (used when all components have unit_cost > 0); \"price\" — proportional to component prices (fallback when any component is missing a cost but all have price > 0); \"quantity\" — equal split per component quantity (last-resort fallback). Null for non-component lines and for legacy component lines expanded before this feature (those were price-based).\n\nEach line item also carries immutable order-line provenance: `channel_product_external_id` (string|null) is the sales-channel listing identifier the line came in as, snapshotted the first time the line is mapped to a product listing — it is never overwritten by a later remap, and survives deletion of the convenience `listing` pointer. `sales_channel_product_id` (int|null) is reserved for the forthcoming sales_channel_products supertype and is null until that phase ships. Lines that have not yet been mapped report both as null.\n\nAuthentication: Requires Bearer token.\n\n**Allocation lock:** `allocation_locked` (bool) is true when the line is tied to a fulfillment order beyond open+unsubmitted — submitted to a carrier, or a channel-imported/manual/pickup fulfillment. When true, `allocation_locked_reason` (string) explains why the line can no longer be allocated/re-allocated (e.g. add stock to reconcile an imported fulfillment). The UI disables the \"Allocate\" action and shows the reason."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/line-items","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","line-items"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3001,\n      \"product_id\": 42,\n      \"channel_product_external_id\": \"JGR-JAPANESE-GO_2PK\",\n      \"sales_channel_product_id\": null,\n      \"quantity\": 3,\n      \"amount\": \"29.99\",\n      \"description\": \"Premium Widget\",\n      \"bundle_proration_basis\": null,\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\",\n        \"barcode\": 12345678901,\n        \"weight\": 1.5,\n        \"weight_unit\": \"lb\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"inventory_allocations\": [],\n      \"sales_order_fulfillment_lines_count\": 1,\n      \"sales_credit_lines_count\": 0,\n      \"allocation_locked\": false,\n      \"allocation_locked_reason\": null\n    },\n    {\n      \"id\": 3002,\n      \"product_id\": null,\n      \"channel_product_external_id\": null,\n      \"sales_channel_product_id\": null,\n      \"quantity\": 2,\n      \"amount\": \"19.99\",\n      \"description\": \"JGR Japanese Go 2-Pack\",\n      \"product\": null,\n      \"listing\": {\n        \"seller-sku\": \"JGR-JAPANESE-GO_2PK\",\n        \"item-name\": \"JGR Japanese Go 2-Pack\",\n        \"asin1\": \"B0DFZJXP6C\",\n        \"QuantityOrdered\": 2,\n        \"ConditionId\": \"New\",\n        \"ConditionSubtypeId\": \"New\",\n        \"id\": 88123,\n        \"integration_instance_id\": 7,\n        \"unique_sales_channel_product_id\": \"JGR-JAPANESE-GO_2PK\",\n        \"skuAlias\": \"JGR-2PK\",\n        \"PartNumber\": \"JGR-2PK\",\n        \"item-condition\": \"New\",\n        \"Model\": \"GO-2PK\",\n        \"image_url\": \"https://m.media-amazon.com/images/I/example.jpg\",\n        \"brand\": \"JGR\",\n        \"manufacturer\": \"JGR\",\n        \"product_type\": \"TOYS_AND_GAMES\",\n        \"color\": \"Multicolor\",\n        \"size\": \"2-Pack\",\n        \"style\": \"Standard\",\n        \"fulfillment_channel\": \"AFN\",\n        \"item_description\": \"Two-pack of Japanese Go board game sets.\"\n      },\n      \"warehouse\": null,\n      \"inventory_allocations\": [],\n      \"sales_order_fulfillment_lines_count\": 0,\n      \"sales_credit_lines_count\": 0,\n      \"allocation_locked\": false,\n      \"allocation_locked_reason\": null\n    }\n  ]\n}"}]},{"name":"Get Customer Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/customer-details","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","customer-details"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns customer details for the customer drawer. Includes total orders, lifetime value, recent orders, and all addresses. Loaded on-demand when the user clicks the customer name.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/customer-details","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","customer-details"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Acme Corp\",\n    \"email\": \"orders@acme.com\",\n    \"phone\": \"+1-555-1234\",\n    \"company\": \"Acme Corp\",\n    \"customer_since\": \"2023-06-01T00:00:00.000000Z\",\n    \"total_orders\": 42,\n    \"lifetime_value\": 15234.5,\n    \"recent_orders\": [\n      {\n        \"id\": 499,\n        \"order_number\": \"SO-20240110-499\",\n        \"date\": \"2024-01-10\",\n        \"total\": 156\n      }\n    ],\n    \"addresses\": [\n      {\n        \"id\": 1,\n        \"label\": \"billing\",\n        \"name\": \"Acme Corp\",\n        \"address1\": \"123 Main St\",\n        \"city\": \"New York\",\n        \"province\": \"New York\",\n        \"zip\": \"10001\",\n        \"country\": \"United States\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns paginated activity log for the sales order, including activities on the order, its lines, and fulfillments.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8001,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"SalesOrder\",\n      \"subject_id\": 500,\n      \"properties\": {\n        \"old\": {\n          \"order_status\": \"open\"\n        },\n        \"attributes\": {\n          \"order_status\": \"fulfilled\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2024-01-18T14:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns paginated inventory movements for the sales order. Includes movements from order lines, fulfillments, fulfillment lines, and related adjustments.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"type\": \"sale\",\n      \"inventory_status\": \"available\",\n      \"quantity\": -3,\n      \"reference\": \"SO-20240115-500.1\",\n      \"inventory_movement_date\": \"2024-01-18\",\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Premium Widget\",\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": \"15.00\",\n      \"unit_cost_provisional\": false,\n      \"created_at\": \"2024-01-18T14:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/allocations?per_page=10","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","allocations"],"query":[{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Returns paginated inventory allocations for all lines in the sales order.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nStatus filter values:\n- active: planned + awaiting_receipt + allocated (excludes cancelled/fulfilled)\n- all: all statuses\n- planned, awaiting_receipt, allocated, fulfilled, cancelled: specific status\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/allocations?per_page=10","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","allocations"],"query":[{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4001,\n      \"status\": \"allocated\",\n      \"quantity\": 3,\n      \"product\": {\n        \"id\": 42,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Premium Widget\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Widget Co\"\n      },\n      \"created_at\": \"2024-01-15T08:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Get Channel Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/channel-items","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","channel-items"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Fetches raw marketplace order item data for the channel tab. Returns original order item data from the sales channel (Amazon order items, Shopify line items, etc.) keyed by marketplace order item ID.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/channel-items","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","channel-items"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"12345\": {\n      \"title\": \"Premium Widget\",\n      \"sku\": \"WIDGET-001\",\n      \"quantity\": 3,\n      \"price\": \"29.99\"\n    }\n  }\n}"}]},{"name":"Update Channel Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/channel-mappings","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","channel-mappings"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Updates the sales channel line ID mappings for sales order lines. Set sales_channel_line_id to null to unlink a line from its channel item.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- mappings (required, array): Array of mapping objects\n  - mappings.*.line_id (required, integer): Sales order line ID (must belong to this order)\n  - mappings.*.sales_channel_line_id (nullable, string): Marketplace order item ID to link, or null to unlink","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"line_id\": 3001,\n      \"sales_channel_line_id\": \"12345\"\n    },\n    {\n      \"line_id\": 3002,\n      \"sales_channel_line_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/channel-mappings","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","channel-mappings"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Channel mappings updated successfully\"\n}"}]},{"name":"Get Sales Order Financials (Proforma)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financials","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financials"],"variable":[{"key":"salesOrder","value":"7760","description":"Sales order ID"}]},"description":"Recalculates and returns proforma (on-the-fly) line-level financials for a single sales order. The endpoint runs the API::calculate for the order before responding, so figures always reflect current FIFO cost assignments — including the bundle cost-based revenue correction.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse (wrapped in {data}):\n- id: Sales order ID\n- is_tax_included, currency (code cached at time of sale), currency_rate\n- sales_order_lines[]: per-line proforma P&L:\n  - product: {id, sku, name} (present when the line is a product line)\n  - description, quantity, price (per-unit amount in tenant currency), tax_allocation, tax_rate_id\n  - revenue: recognized revenue for the line (after any bundle cost-based correction)\n  - revenue_allocation_basis: \"document\" (revenue follows the order document) or \"cost_corrected\" (bundle-group revenue re-allocated in proportion to actual COGS so no component shows a phantom line-level loss)\n  - document_revenue: pre-correction revenue computed from the order document (quantity × amount − included tax); equals revenue unless revenue_allocation_basis is cost_corrected\n  - bundle_id: parent bundle product ID when the line was expanded from a bundle (null otherwise)\n  - bundle_proration_basis: how the bundle's price was prorated across components at order entry — \"cost\", \"price\", or \"quantity\" (null for non-bundle or legacy lines)\n  - bundle: {id, sku, name} (present when bundle_id is set)\n  - revenue_allocated, credits, discount, total_revenue\n  - cogs, cost_allocated, cogs_returned, total_cost\n  - profit, profit_margin\n  - per_unit: {revenue, revenue_allocated, credits, discount, total_revenue, cogs, cost_allocated, cogs_returned, total_cost, profit}\n  - cost_breakdown: cost category → amount map\n  - cost_breakdown_layers[]: FIFO layer-level cost detail (layer_kind, fifo_layer_id, fifo_layer_date, quantity, source_type, source_label, source_id, breakdown, total, unit_cost)\n  - fifo_layers[]: {id, name, quantity, unit_cost, total_cost, layer_date}\n\n**Returns-pending COGS:** each line splits returned cost into `cogs_returned_realized` (cost reversed by physical return receipts) and `cogs_returned_pending` (imputed expected cost of refunded units still awaiting return), with a `return_pending` boolean; the same split is available under `per_unit.*`. The order-level `has_return_pending` flag is true when any line has a return still in flight. A refunded-but-un-received order nets to ~0 while `return_pending` is true; closing or canceling the RMA without receiving the goods clears the pending imputation and reveals the real loss.\n\nEach line includes indirect_cost_allocated (the line's revenue-weighted share of cost-entry / overhead allocations), contribution_profit (profit minus that share) and contribution_margin (a fraction of revenue), plus their per_unit variants. These are standalone — profit, total_cost and profit_margin are unchanged by them."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/financials","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","financials"],"variable":[{"key":"salesOrder","value":"7760","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 123,\n    \"sales_order_lines\": [\n      {\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WGT-001\",\n          \"name\": \"Widget A\"\n        },\n        \"description\": \"Widget A\",\n        \"quantity\": 3,\n        \"price\": 50,\n        \"revenue\": 150,\n        \"total_revenue\": 150,\n        \"cogs\": 60,\n        \"cost_allocated\": 12,\n        \"cogs_returned\": 0,\n        \"total_cost\": 72,\n        \"profit\": 78,\n        \"profit_margin\": 0.52,\n        \"indirect_cost_allocated\": 9.5,\n        \"contribution_profit\": 68.5,\n        \"contribution_margin\": 0.4567,\n        \"per_unit.revenue\": 50,\n        \"per_unit.total_cost\": 24,\n        \"per_unit.profit\": 26,\n        \"per_unit.indirect_cost_allocated\": 3.17,\n        \"per_unit.contribution_profit\": 22.83\n      }\n    ],\n    \"is_tax_included\": false,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1\n  }\n}"}]},{"name":"Get Backorder Detail for Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/sales-order-lines/{salesOrderLine}/backorder-detail","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","sales-order-lines",":salesOrderLine","backorder-detail"],"variable":[{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]},"description":"Returns lazy-loaded backorder detail for a sales order line. Includes release sources (what freed up stock), PO coverage info, and remaining backorder breakdown. Called on badge click — not on list load.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/sales-order-lines/{salesOrderLine}/backorder-detail","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","sales-order-lines",":salesOrderLine","backorder-detail"],"variable":[{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"released\": {\n      \"total\": 2,\n      \"sources\": [\n        {\n          \"quantity\": 2,\n          \"source_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceiptLine\",\n          \"source_id\": 100,\n          \"source_label\": \"PO PO-2024-001 receipt\",\n          \"released_at\": \"2024-01-18T00:00:00.000000Z\"\n        }\n      ]\n    },\n    \"covered\": {\n      \"total\": 1,\n      \"sources\": [\n        {\n          \"quantity\": 1,\n          \"purchase_order_id\": 55,\n          \"purchase_order_number\": \"PO-2024-002\",\n          \"is_tight_coverage\": false\n        }\n      ]\n    },\n    \"uncovered\": {\n      \"total\": 0\n    },\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Widget Co\",\n      \"next_schedule\": null\n    }\n  }\n}"}]},{"name":"Get Next Backorder Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/backorder/next-schedule","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","backorder","next-schedule"]},"description":"Returns the next scheduled fill_backorders runs (up to 3) for countdown display. Optionally filtered by supplier to find schedules relevant to a specific product's supplier.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/backorder/next-schedule","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","backorder","next-schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Daily Backorder Fill\",\n      \"next_run_at\": \"2024-01-21T02:00:00+00:00\",\n      \"schedule_time\": \"02:00\",\n      \"auto_create_po\": false,\n      \"po_status\": \"draft\",\n      \"last_run_at\": \"2024-01-20T02:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create PO from Backorder","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/backorder/create-po","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","backorder","create-po"]},"description":"Creates a draft purchase order from a backordered sales order line. Uses the line's product's primary supplier and the shortage quantity (planned allocations without PO coverage).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- sales_order_line_id (required, integer): The sales order line with the backorder shortage","body":{"mode":"raw","raw":"{\n  \"sales_order_line_id\": 3001\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/backorder/create-po","host":["{{baseUrl}}"],"path":["api","v2","sales-orders","backorder","create-po"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"purchase_order_number\": \"PO-2024-055\"\n  },\n  \"message\": \"Draft PO created successfully\"\n}"}]},{"name":"List Sales Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/list","host":["{{baseUrl}}"],"path":["api","sales-orders","list"]},"description":"Paginated sales order listing for the list view (Spatie QueryBuilder).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach row includes `ship_by_date` (the ship-by deadline / ceiling), `deliver_by_date`, and `hold_until_date` (the earliest date the order may ship — a release floor used for preorders / held orders). Held orders also expose `opens_at` and `hold_reason` when reserved via a Shopify channel.\n\nThe response is standard Laravel pagination with an extra top-level `unfiltered_total` (total count ignoring filters).\n\nAuthentication: Requires Bearer token. Scope: orders (read).\n\nFiltering (API integrations — start here): use flat `filter[...]` params. Any listed column works as `filter[<column>]=<value>` (implicit `is`) or `filter[<column>.<operator>]=<value>` for an explicit operator; e.g. `filter[to_fulfill_warehouse_id]=1`, `filter[order_status.is]=open`, `filter[total.greater_than]=100`, `filter[order_date.between]=2026-04-01,2026-04-30`. Multiple flat filters AND together, and `.is_one_of`/`.between` take a comma-separated value. These params are individually documented (see the disabled query params below). The `filter_groups` param is a base64 JSON tree used by the web UI's Advanced Filters and is only needed for OR / nested groups — avoid it for API use.\n\nRelated-record id filters (for support/debugging — trace a sales order by any id in the fulfillment chain): filter[sales_order_line_id] (SOL), filter[fulfillment_order_id] (FO), filter[fulfillment_order_line_id] (FOL), filter[sales_order_fulfillment_id] (SOF), filter[sales_order_fulfillment_line_id] (SOFL). All numeric, optional, and support operators (.is_one_of, etc.) plus comma-separated multi-match."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/list","host":["{{baseUrl}}"],"path":["api","sales-orders","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 186408,\n      \"sales_order_number\": \"GML426864\",\n      \"customer_po_number\": null,\n      \"order_status\": \"open\",\n      \"canceled_at\": null,\n      \"approved_at\": null,\n      \"reserved_at\": null,\n      \"fulfilled_at\": null,\n      \"ship_by_date\": \"2026-04-10\",\n      \"deliver_by_date\": \"2026-04-15\",\n      \"hold_until_date\": \"2026-04-01\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"payment_status\": \"paid\",\n      \"customer_name\": {\n        \"id\": 1234,\n        \"name\": \"Jane Smith\"\n      },\n      \"customer_email\": \"jane@example.com\",\n      \"customer_company\": \"Acme Corp\",\n      \"customer_phone\": \"+1 555 123 4567\",\n      \"sales_rep_name\": null,\n      \"currency_rate\": 1,\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"shipping_name\": \"Jane Doe\",\n      \"shipping_company\": \"Acme Retail LLC\",\n      \"shipping_address\": \"123 Main St\",\n      \"shipping_address2\": \"Suite 200\",\n      \"shipping_address3\": \"Building C\",\n      \"shipping_overridden_at\": null,\n      \"is_shipping_overridden\": false,\n      \"shipping_city\": \"Brooklyn\",\n      \"shipping_province\": \"NY\",\n      \"shipping_zip\": \"11201\",\n      \"shipping_country\": \"United States\",\n      \"billing_name\": \"Jane Doe\",\n      \"billing_company\": \"Acme Retail LLC\",\n      \"billing_address\": \"123 Main St\",\n      \"billing_address2\": \"Suite 200\",\n      \"billing_address3\": \"Building C\",\n      \"billing_city\": \"Brooklyn\",\n      \"billing_province\": \"NY\",\n      \"billing_zip\": \"11201\",\n      \"billing_country\": \"United States\",\n      \"store\": {\n        \"id\": 1,\n        \"name\": \"Main Store\"\n      },\n      \"sales_channel_name\": \"Manual\",\n      \"sub_sales_channel_name\": null,\n      \"integration\": null,\n      \"is_fba\": false,\n      \"order_date\": \"2026-03-28T00:00:00.000000Z\",\n      \"created_at\": \"2026-03-28T14:02:11.000000Z\",\n      \"updated_at\": \"2026-03-29T09:15:00.000000Z\",\n      \"archived_at\": null,\n      \"total\": 219.88,\n      \"subtotal\": 199.9,\n      \"tax_total\": 19.98,\n      \"discount_total\": 0,\n      \"currency_code\": \"USD\",\n      \"shipping_method\": \"UPS Ground\",\n      \"tags\": [\n        \"priority\",\n        \"b2b\"\n      ],\n      \"warehouse_names\": \"Main Warehouse\",\n      \"warehouse_count\": 1,\n      \"line_item_count\": 2,\n      \"total_quantity\": 10,\n      \"is_quote\": false,\n      \"has_dropship\": false,\n      \"has_submitted_dropship_po\": false,\n      \"unmapped_line_count\": 0,\n      \"allocation_required_quantity\": 10,\n      \"allocation_covered_quantity\": 10,\n      \"allocation_percentage\": 100,\n      \"opens_at\": null,\n      \"hold_reason\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10,\n  \"unfiltered_total\": 1203\n}"}]},{"name":"Export Sales Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/list/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","sales-orders","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export file format: xlsx (default) or csv.","disabled":true},{"key":"content_mode","value":"summary","description":"summary = one row per sales order (default); line_items = one row per line item.","disabled":true},{"key":"scope","value":"filtered","description":"Which orders to export: filtered (default — current filters/sort), all (ignores filters), current_page, or selected.","disabled":true}]},"description":"Exports the sales order list view as an XLSX or CSV file download.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAccepts the same `filter`, `filter_groups`, and `sort` query params as the List endpoint (the active list view filters). The `Hold Until Date` column is included in the export (alongside `Ship By Date` and `Deliver By Date`); date columns are converted from UTC to the tenant timezone.\n\nResponse: a binary file download (Content-Type `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for xlsx, `text/csv` for csv) — not JSON.\n\nAuthentication: Requires Bearer token. Scope: orders (read).\n\n**Requires permission:** `sales_orders.export`"}},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/import/template","host":["{{baseUrl}}"],"path":["api","sales-orders","import","template"]},"description":"Downloads an XLSX import template with headers, sample data, a field guide, and reference data from the tenant's account.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe template's `Import Here` sheet and `Field Guide` sheet both include the `hold_until_date` column — the earliest date an order is allowed to ship (held until this date, e.g. for preorders). Format: YYYY-MM-DD.\n\nResponse: a binary XLSX file download — not JSON.\n\nAuthentication: Requires Bearer token. Scope: orders (read/write).\n\n**Requires permission:** `sales_orders.import`"}},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/import/validate","host":["{{baseUrl}}"],"path":["api","sales-orders","import","validate"]},"description":"Validates mapped import rows and returns a grouped preview. No side effects — safe to call repeatedly.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body: `rows` (array, 1–50000). Each row accepts these nullable string fields: id, sales_order_number, order_date, customer_email, customer_id, customer_name, customer_company, customer_phone, customer_po_number, sales_channel_name, sub_sales_channel_name, store_name, currency_code, requested_shipping_method, ship_by_date, deliver_by_date, hold_until_date, tags, order_discount_amount, order_discount_rate, shipping_amount, shipping_address/city/province/zip/country, billing_address/city/province/zip/country, sku, description, quantity, unit_price, discount, tax_rate, warehouse_name, nominal_code.\n\n`hold_until_date` is the earliest ship date — the order is held until this date (preorders). Format: YYYY-MM-DD.\n\nRows sharing an order number + customer are grouped into one sales order in the preview.\n\nAuthentication: Requires Bearer token. Scope: orders (read/write).\n\n**Requires permission:** `sales_orders.import`","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"id\": null,\n      \"sales_order_number\": \"SO-001\",\n      \"order_date\": \"2026-04-01\",\n      \"customer_email\": \"jane@example.com\",\n      \"sales_channel_name\": \"Manual\",\n      \"ship_by_date\": \"2026-04-10\",\n      \"deliver_by_date\": \"2026-04-15\",\n      \"hold_until_date\": \"2026-04-01\",\n      \"sku\": \"WIDGET-001\",\n      \"quantity\": \"2\",\n      \"unit_price\": \"19.99\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/import/validate","host":["{{baseUrl}}"],"path":["api","sales-orders","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"sales_orders\": [\n    {\n      \"group_key\": \"SO-001|jane@example.com\",\n      \"action\": \"create\",\n      \"match_reason\": null,\n      \"sales_order_number\": \"SO-001\",\n      \"order_date\": \"2026-04-01\",\n      \"ship_by_date\": \"2026-04-10\",\n      \"deliver_by_date\": \"2026-04-15\",\n      \"hold_until_date\": \"2026-04-01\",\n      \"customer\": {\n        \"email\": \"jane@example.com\",\n        \"name\": null\n      },\n      \"sales_channel\": {\n        \"id\": 5,\n        \"name\": \"Manual\"\n      },\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 88,\n          \"quantity\": 2,\n          \"unit_price\": 19.99\n        }\n      ],\n      \"errors\": [],\n      \"warnings\": []\n    }\n  ],\n  \"summary\": {\n    \"total_rows\": 1,\n    \"valid_orders\": 1,\n    \"orders_with_errors\": 0\n  }\n}"}]},{"name":"Import Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/import","host":["{{baseUrl}}"],"path":["api","sales-orders","import"]},"description":"Executes the import — creates or updates sales orders from validated/grouped data (the output of the Validate Import endpoint).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body: `sales_orders` (array, min 1) and optional `continue_on_error` (boolean). Each sales order accepts: group_key, id, action (create|update|blocked), sales_order_number, order_date, customer{id,email,name,company,phone}, sales_channel{id} (required), sub_sales_channel, store, currency, shipping_method, requested_shipping_method, customer_po_number, ship_by_date, deliver_by_date, hold_until_date, tags, order_discount_amount, order_discount_rate, shipping_amount, shipping_address, billing_address, and lines[] {sku, product_id, product_name, description, quantity, unit_price, discount, tax_rate, warehouse_id, nominal_code_id}.\n\n`hold_until_date` (YYYY-MM-DD) sets the earliest ship date — the order is held until this date. Incoming dates are treated as tenant-timezone and stored as UTC.\n\nReturns 201 when anything was newly created, 200 when the import only updated existing records.\n\nAuthentication: Requires Bearer token. Scope: orders (read/write).\n\n**Requires permission:** `sales_orders.import`","body":{"mode":"raw","raw":"{\n  \"continue_on_error\": false,\n  \"sales_orders\": [\n    {\n      \"group_key\": \"SO-001|jane@example.com\",\n      \"action\": \"create\",\n      \"sales_order_number\": \"SO-001\",\n      \"order_date\": \"2026-04-01\",\n      \"customer\": {\n        \"email\": \"jane@example.com\",\n        \"name\": \"Jane Smith\"\n      },\n      \"sales_channel\": {\n        \"id\": 5\n      },\n      \"ship_by_date\": \"2026-04-10\",\n      \"deliver_by_date\": \"2026-04-15\",\n      \"hold_until_date\": \"2026-04-01\",\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 88,\n          \"quantity\": 2,\n          \"unit_price\": 19.99\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/import","host":["{{baseUrl}}"],"path":["api","sales-orders","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"created\": [\n    {\n      \"id\": 186500,\n      \"sales_order_number\": \"SO-001\"\n    }\n  ],\n  \"updated\": [],\n  \"failed\": [],\n  \"summary\": {\n    \"created_count\": 1,\n    \"updated_count\": 0,\n    \"failed_count\": 0\n  }\n}"}]},{"name":"Bulk Close Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/close","host":["{{baseUrl}}"],"path":["api","sales-orders","close"]},"description":"Bulk closes one or more sales orders by transitioning their order_status to `closed`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (one of `ids` or `filters` is required):\n- `ids` (array of integers, required without `filters`): Sales order IDs to close.\n- `filters` (object, required without `ids`): Filter set that resolves to a list of sales order IDs (same shape used by the V2 sales-orders listing endpoint). It accepts the grouped `filter_groups` shape (`{ \\\"filter_groups\\\": \\\"<base64 JSON>\\\" }`, same as the V2 list) as well as the legacy JSON-string filter set.\n- `archived` (integer, optional, default 0): Used with `filters` — set to 1 to include archived orders when resolving IDs.\n\nBehavior:\n- Each order is closed individually via `SalesOrder::close`.\n- Orders with active backorders (Planned or AwaitingReceipt allocations) or unmapped product lines are skipped and returned as warnings.\n- Returns 200 if all orders close, 200/warning if some are skipped, 400 if none can close.\n\n**Requires permission:** `sales_orders.cancel`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/close","host":["{{baseUrl}}"],"path":["api","sales-orders","close"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"7116\": \"Successfully closed sales order SO-7116.\",\n    \"7117\": \"Successfully closed sales order SO-7117.\",\n    \"7118\": \"Successfully closed sales order SO-7118.\"\n  },\n  \"message\": \"Successfully closed all sales orders.\"\n}"}]},{"name":"Bulk Delete Sales Orders (Tracked)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/tracked","host":["{{baseUrl}}"],"path":["api","sales-orders","tracked"]},"description":"Bulk deletes sales orders with progress tracking. Dispatches a background job and returns a `tracked_job_log_id` to poll via the tracked job log endpoints.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (scope: one of `ids` or `filters` is required):\n- `ids` (array of int, required without `filters`): Explicit sales order IDs to delete.\n- `filters` (object, required without `ids`): Resolves to a list of sales order IDs via the same Spatie QueryBuilder pipeline the V2 sales-orders list/export use. Two shapes are accepted:\n  - Grouped filters (current list): `{ \\\"filter_groups\\\": \\\"<base64-encoded JSON tree>\\\" }`. The decoded tree looks like `{\\\"conjunction\\\":\\\"and\\\",\\\"children\\\":[{\\\"type\\\":\\\"condition\\\",\\\"condition\\\":{\\\"column\\\":\\\"order_status\\\",\\\"operator\\\":\\\"is\\\",\\\"value\\\":\\\"open\\\"}}]}`.\n  - legacy filter set (JSON string) for older clients.\n- `apply_to_all` (bool, optional): When true the action targets every order matching the active `filters` rather than an explicit `ids` list.\n\nBehavior:\n- Returns the tracked job log ID immediately; deletion runs asynchronously.\n- Sending `filters` as the grouped `filter_groups` object is fully supported (previously returned a 500).\n\n**Requires permission:** `sales_orders.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/tracked","host":["{{baseUrl}}"],"path":["api","sales-orders","tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 84213\n  },\n  \"message\": \"Bulk delete started. Track progress using the returned ID.\"\n}"}]},{"name":"Create Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders","host":["{{baseUrl}}"],"path":["api","sales-orders"]},"description":"Creates a sales order, optionally with an embedded customer, shipping/billing addresses, line items, line-level discounts, and financial lines (shipping, fees, etc.). Orders can be created as drafts and approved later, or opened immediately.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- order_status (string, required): One of `draft`, `reserved`, `open`, `closed`. Line items are required unless the status is `draft`. When `closed`, `fulfilled_at` becomes required.\n- order_date (date-time, required): Order placement date. If the value parses to today's date (a date-only value from a date picker), it is replaced with the exact current timestamp so the order reflects when it was actually placed. Back-dated or forward-dated values are kept as sent.\n- currency_id (integer, required without currency_code): Currency record ID.\n- currency_code (string, required without currency_id): ISO currency code, e.g. `USD`.\n- sales_order_number (string, optional, max 255): Must be unique within the sales channel. Auto-generated from your order-number settings when omitted.\n- customer_po_number (string, optional, max 255): The customer's own purchase-order reference.\n- store_id (integer, optional) / store_name (string, optional): Store to attribute the order to.\n- sales_channel_id (integer, optional): Sales channel the order belongs to; defaults to the local channel.\n- shipping_method_id (integer, optional), requested_shipping_method (string, optional, max 255).\n- customer_id (integer, optional): Existing customer ID. Alternatively send the `customer` object below.\n- sales_rep_id (integer, optional) / sales_rep_name (string, optional, max 255): Provide at most one; a new sales rep is created from the name if it doesn't exist.\n- shipping_address_id / billing_address_id (integer, optional): Existing address IDs; each must belong to the order's customer.\n- payment_status (string, optional): `unpaid`, `partially_paid`, `paid`, `refunded`.\n- payment_date, ship_by_date, hold_until_date (do-not-ship-before release date), deliver_by_date, packing_slip_printed_at (dates, optional).\n- fulfilled_at (date, required when order_status is `closed`), tracking_number (string, optional, max 255; only accepted when order_status is `closed`).\n- discount (number, optional, < 1,000,000): Order-level discount amount.\n- is_tax_included (boolean, optional): Whether line amounts already include tax.\n- tax_rate_id (number, optional).\n- tags (array of strings, optional).\n- memo_for_customer (string, optional, max 65,535).\n- custom_field_values (array, optional): Custom field values keyed by custom field.\n\nsales_order_lines (array; required unless order_status is `draft`). Duplicate lines are rejected — every line must be unique by product/SKU + sales_channel_line_id + description + quantity + amount + bundle_id; provide a `sales_channel_line_id` per line for channel-sourced orders. Each line:\n- description (string, required, max 255)\n- product_id (integer, optional) or sku (string, optional): Identifies the product; omit both for a non-product line.\n- amount (number, required, < 100,000,000): Unit price.\n- quantity (number, required, >= 0 and < 100,000)\n- canceled_quantity (number, required when quantity is 0)\n- externally_fulfilled_quantity (number, optional)\n- tax_rate_id (number, optional)\n- sales_channel_line_id (optional): The channel's own line identifier.\n- nominal_code_id / nominal_code_name / nominal_code (optional): Ledger code by ID, name, or code.\n- is_product (boolean, optional)\n- warehouse_routing_method (string, optional): `dropship`, `warehouse`, `advanced`, or `unassigned`.\n- warehouse_id (integer, optional; required when warehouse_routing_method is `warehouse`)\n- bundle_id (integer, optional): Parent bundle product ID when the line is a bundle component.\n- subscription_edition_id (integer, optional): Subscription edition to allocate from; edition allocation limits are enforced.\n- line_discounts (array, optional): Each with name (string, required, max 255), type (required: `percentage` or `fixed_amount`), rate (number 0-100, optional), amount (number >= 0, optional), scope (optional, `line`).\n\nfinancial_lines (array, optional). Each line:\n- financial_line_type_id (integer, optional), nominal_code_id (integer, optional), description (string, optional), quantity (number, optional, >= 0), amount (number, optional), tax_allocation (number, optional), allocate_to_products (boolean, optional), proration_strategy (string, optional: `revenue_based`, `cost_based`, `weight_based`, `volume_based`, `quantity_based`, `specific_line`, `manual`), allocate_to_id (integer, optional: sales order line ID to allocate to), allocate_to_type (string, optional).\n\ndiscount_lines (array, optional): Each with name (string, required, max 255), rate (number, optional), amount (number, optional).\n\ntax_lines (array, optional): Each with name (string, required, max 255), rate (number, optional).\n\ncustomer (object, optional): company, name, email, phone, fax, address1, address2, address3, city, province, province_code, zip, country, country_code (valid ISO country code), label — all optional strings (max 255).\n\nshipping_address / billing_address (objects, optional): company, name, email, phone, fax, address1, address2, address3, city, province, province_code, zip, county, country_code (valid ISO country code), label — all optional strings (max 255).\n\nReturns the complete created order, including lines, fulfillment state, totals, and addresses. Returns 400 when a line's warehouse routing cannot resolve a valid warehouse for the product.\n\n**Requires permission:** `sales_orders.create`","body":{"mode":"raw","raw":"{\n  \"order_status\": \"open\",\n  \"order_date\": \"2026-07-06 10:15:00\",\n  \"currency_code\": \"USD\",\n  \"customer_po_number\": \"PO-88213\",\n  \"store_id\": 1,\n  \"shipping_method_id\": 7,\n  \"ship_by_date\": \"2026-07-07\",\n  \"is_tax_included\": false,\n  \"tags\": [\n    \"wholesale\"\n  ],\n  \"memo_for_customer\": \"Thank you for your order!\",\n  \"customer\": {\n    \"name\": \"Jane Cooper\",\n    \"email\": \"jane.cooper@example.com\",\n    \"phone\": \"+1 555-201-4477\",\n    \"company\": null\n  },\n  \"shipping_address\": {\n    \"name\": \"Jane Cooper\",\n    \"phone\": \"+1 555-201-4477\",\n    \"address1\": \"982 Maple Avenue\",\n    \"address2\": \"Apt 4B\",\n    \"city\": \"Portland\",\n    \"province\": \"Oregon\",\n    \"province_code\": \"OR\",\n    \"zip\": \"97205\",\n    \"country_code\": \"US\"\n  },\n  \"billing_address\": {\n    \"name\": \"Jane Cooper\",\n    \"phone\": \"+1 555-201-4477\",\n    \"address1\": \"982 Maple Avenue\",\n    \"address2\": \"Apt 4B\",\n    \"city\": \"Portland\",\n    \"province\": \"Oregon\",\n    \"province_code\": \"OR\",\n    \"zip\": \"97205\",\n    \"country_code\": \"US\"\n  },\n  \"sales_order_lines\": [\n    {\n      \"description\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n      \"sku\": \"WB-32-BLU\",\n      \"quantity\": 2,\n      \"amount\": 25.99,\n      \"is_product\": true,\n      \"warehouse_routing_method\": \"advanced\"\n    },\n    {\n      \"description\": \"Bottle Cleaning Brush Kit\",\n      \"sku\": \"BR-KIT-01\",\n      \"quantity\": 1,\n      \"amount\": 9.5,\n      \"is_product\": true,\n      \"line_discounts\": [\n        {\n          \"name\": \"Bundle discount\",\n          \"type\": \"percentage\",\n          \"rate\": 10\n        }\n      ]\n    }\n  ],\n  \"financial_lines\": [\n    {\n      \"description\": \"Shipping\",\n      \"financial_line_type_id\": 2,\n      \"quantity\": 1,\n      \"amount\": 6.99\n    }\n  ],\n  \"incoterm_id\": 12,\n  \"incoterm_place\": \"Port of Los Angeles, CA\",\n  \"incoterm_version\": 2020\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders","host":["{{baseUrl}}"],"path":["api","sales-orders"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order created successfully\",\n  \"data\": {\n    \"id\": 612,\n    \"sales_order_number\": \"SO-01043\",\n    \"customer_po_number\": \"PO-88213\",\n    \"sales_channel_id\": 3,\n    \"sales_channel_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": null,\n    \"sub_sales_channel\": null,\n    \"sub_sales_channel_name\": null,\n    \"integration_instance_id\": 2,\n    \"integration\": \"Shopify\",\n    \"integration_id\": 4,\n    \"integration_image\": \"https://cdn.sku.io/integrations/shopify.png\",\n    \"can_submit_fulfillments_to_channel\": true,\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    },\n    \"sales_rep_id\": null,\n    \"sales_rep\": null,\n    \"accounting\": {\n      \"transaction\": null\n    },\n    \"order_date\": \"2026-07-06T10:15:00.000000Z\",\n    \"payment_date\": null,\n    \"created_at\": \"2026-07-06T10:15:01.000000Z\",\n    \"updated_at\": \"2026-07-06T10:15:01.000000Z\",\n    \"archived_at\": null,\n    \"canceled_at\": null,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"discount_lines\": null,\n    \"discounts\": [],\n    \"order_discounts\": null,\n    \"line_discount_total\": 0,\n    \"order_discount_total\": 0,\n    \"total_discount_amount\": 0,\n    \"apply_order_discount_on\": null,\n    \"tax_lines\": null,\n    \"packing_slip_printed_at\": null,\n    \"is_fba\": false,\n    \"is_replacement_order\": false,\n    \"need_mapping\": false,\n    \"memo_for_customer\": null,\n    \"reserved_at\": null,\n    \"payment_hold_status\": null,\n    \"reservation_expires_at\": null,\n    \"ship_by_date\": \"2026-06-19T00:00:00.000000Z\",\n    \"hold_until_date\": null,\n    \"is_held\": false,\n    \"deliver_by_date\": null,\n    \"fulfilled_at\": null,\n    \"shipping_method_id\": 7,\n    \"shipping_method\": \"USPS Priority Mail\",\n    \"is_pickup\": false,\n    \"shipped_is_pickup\": false,\n    \"address_check\": {\n      \"has_warning\": true,\n      \"has_block\": false,\n      \"highest_severity\": \"warning\",\n      \"warnings\": [\n        {\n          \"rule_id\": \"missing-required\",\n          \"severity\": \"warning\",\n          \"message\": \"Shipping address is missing required fields (name, street, city, postcode or country).\"\n        }\n      ]\n    },\n    \"requested_shipping_method\": \"Standard Shipping\",\n    \"mapped_shipping_method\": \"USPS Priority Mail\",\n    \"has_backorder\": false,\n    \"fulfillment\": [],\n    \"fulfillment_channel\": null,\n    \"customer_name\": {\n      \"id\": null,\n      \"name\": \"Jane Cooper\"\n    },\n    \"customer_email\": \"jane.cooper@example.com\",\n    \"customer_company\": null,\n    \"customer_phone\": \"+1 555-201-4477\",\n    \"sales_order_shipping_address\": {\n      \"id\": 1201,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_overridden_at\": null,\n    \"is_shipping_overridden\": false,\n    \"sales_order_billing_address\": {\n      \"id\": 1202,\n      \"name\": \"Jane Cooper\",\n      \"email\": \"jane.cooper@example.com\",\n      \"company\": null,\n      \"phone\": \"+1 555-201-4477\",\n      \"address1\": \"982 Maple Avenue\",\n      \"address2\": \"Apt 4B\",\n      \"address3\": null,\n      \"city\": \"Portland\",\n      \"province\": \"Oregon\",\n      \"province_code\": \"OR\",\n      \"zip\": \"97205\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 2310,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 11.42,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 2,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 2,\n        \"item_on_hand_allocated_quantity\": 2,\n        \"item_unallocated_quantity\": 0,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 812,\n          \"sku\": \"WB-32-BLU\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345678905,\n        \"item_weight\": 1.2,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 25.99,\n        \"item_price_with_tax\": 25.99,\n        \"item_name\": \"Stainless Steel Water Bottle 32oz - Ocean Blue\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 51.98,\n        \"price_after_line_discount\": 25.99,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 51.98,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": false,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 2,\n        \"remaining_to_fulfill_quantity\": 2,\n        \"available_to_fulfill\": 2,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 0,\n        \"inventory_allocation_id\": 5120,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": null,\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/wb-32-blu.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 24,\n            \"stock\": 150,\n            \"allocated\": 2,\n            \"on_hold\": 0,\n            \"available\": 148,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 24,\n              \"stock\": 150,\n              \"allocated\": 2,\n              \"on_hold\": 0,\n              \"available\": 148,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 148\n      },\n      {\n        \"sales_order_line_id\": 2102,\n        \"sales_channel_line_id\": null,\n        \"bundle_quantity_cache\": null,\n        \"unit_cost\": 3.8,\n        \"tax_rate\": 0,\n        \"tax_rate_id\": null,\n        \"item_tax_value\": 0,\n        \"fifo_layer_id\": null,\n        \"item_quantity\": 1,\n        \"item_canceled_quantity\": 0,\n        \"item_allocated_quantity\": 1,\n        \"item_on_hand_allocated_quantity\": 1,\n        \"item_unallocated_quantity\": 0,\n        \"sales_channel_fulfillment_out_of_sync\": false,\n        \"item_externally_fulfilled_quantity\": 0,\n        \"fulfilled_quantity\": 1,\n        \"submitted_quantity\": 0,\n        \"item_dropshipped_quantity\": 0,\n        \"item_sku\": {\n          \"id\": 954,\n          \"sku\": \"BR-KIT-01\"\n        },\n        \"item_bundle_sku\": null,\n        \"item_barcode\": 812345671231,\n        \"item_weight\": 0.3,\n        \"item_weight_unit\": \"lb\",\n        \"item_brand\": {\n          \"id\": 14,\n          \"name\": \"HydraPeak\"\n        },\n        \"bundle\": null,\n        \"bundle_proration_basis\": null,\n        \"item_price\": 9.5,\n        \"item_price_with_tax\": 9.5,\n        \"item_name\": \"Bottle Cleaning Brush Kit\",\n        \"item_nominal_code_id\": null,\n        \"item_nominal_code\": null,\n        \"item_nominal_code_code\": null,\n        \"item_discount\": 0,\n        \"item_line_discounts\": [],\n        \"item_line_discount_total\": 0,\n        \"item_net_total\": 9.5,\n        \"price_after_line_discount\": 9.5,\n        \"line_discount_total\": 0,\n        \"allocated_order_discount\": 0,\n        \"net_total\": 9.5,\n        \"item_has_backorder\": false,\n        \"allocation_locked\": false,\n        \"allocation_locked_reason\": null,\n        \"is_product\": true,\n        \"is_bundle\": false,\n        \"is_variation\": false,\n        \"credited_quantity\": 0,\n        \"credit_sources\": [\n          {\n            \"vendor_credit_id\": 42,\n            \"vendor_credit_number\": \"VC-1001\",\n            \"quantity\": 5,\n            \"credit_status\": \"open\",\n            \"restock_inventory\": false\n          }\n        ],\n        \"warehouse_routing_method\": \"advanced\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\",\n          \"supplier_id\": null,\n          \"supplier_name\": null\n        },\n        \"is_fulfilled\": true,\n        \"no_audit_trail\": false,\n        \"unfulfilled_quantity\": 0,\n        \"remaining_to_fulfill_quantity\": 0,\n        \"available_to_fulfill\": 0,\n        \"committed_to_fulfillment_quantity\": 0,\n        \"returnable_quantity\": 1,\n        \"inventory_allocation_id\": 5121,\n        \"backordered_quantity\": 0,\n        \"listing\": null,\n        \"channel_product_external_id\": null,\n        \"sales_channel_product_id\": null,\n        \"subscription_edition_id\": null,\n        \"subscription_edition\": null,\n        \"subscription_offering\": null,\n        \"created_at\": \"2026-06-18T14:23:15.000000Z\",\n        \"updated_at\": \"2026-06-19T16:40:21.000000Z\",\n        \"cogs\": {\n          \"base_unit_cost\": 3.8,\n          \"cost_lines_total\": 0,\n          \"cost_lines\": [],\n          \"landed_costs_total\": 0,\n          \"landed_costs\": [],\n          \"unallocated_total\": 0,\n          \"unallocated\": [],\n          \"fifo_layers\": [\n            {\n              \"fifo_layer_id\": 3312,\n              \"fifo_layer_date\": \"2026-05-02\",\n              \"quantity\": 1,\n              \"source_label\": \"PO Receipt\",\n              \"source_id\": 1207,\n              \"unit_cost\": 3.8\n            }\n          ],\n          \"total_cost\": 3.8,\n          \"unit_cost\": 3.8,\n          \"is_finalized\": true\n        },\n        \"estimated_decoration_cost\": 0,\n        \"actual_decoration_cost\": 0,\n        \"decoration_cost_breakdown\": null,\n        \"is_taxable\": true,\n        \"default_tax_rate_id\": null,\n        \"item_img_url\": \"https://cdn.sku.io/products/br-kit-01.jpg\",\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 0,\n            \"stock\": 61,\n            \"allocated\": 1,\n            \"on_hold\": 0,\n            \"available\": 60,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 0,\n              \"stock\": 61,\n              \"allocated\": 1,\n              \"on_hold\": 0,\n              \"available\": 60,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"item_stock\": 60\n      }\n    ],\n    \"purchase_orders\": [],\n    \"adjustments\": [],\n    \"financial_lines\": [\n      {\n        \"id\": 610,\n        \"description\": \"Shipping\",\n        \"quantity\": 1,\n        \"amount\": 6.99,\n        \"extended_amount\": 6.99,\n        \"discount_rate\": 0,\n        \"amount_in_tenant_currency\": 6.99,\n        \"tax_allocation\": 0,\n        \"tax_allocation_in_tenant_currency\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"allocate_to_products\": false,\n        \"proration_strategy\": null,\n        \"allocate_to_id\": null,\n        \"allocate_to_type\": null,\n        \"link_type\": null,\n        \"link_id\": null,\n        \"financial_line_type\": {\n          \"id\": 2,\n          \"name\": \"Shipping\",\n          \"classification\": \"revenue\",\n          \"nominal_code_id\": 12\n        },\n        \"nominal_code\": {\n          \"id\": 12,\n          \"name\": \"Shipping Income\",\n          \"code\": \"4020\"\n        },\n        \"credited_amount\": 0,\n        \"remaining_amount\": 6.99\n      }\n    ],\n    \"custom_field_values\": [],\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"fulfillment_sequence\": null,\n    \"payment_status\": \"unpaid\",\n    \"tax_revenue\": 4.11,\n    \"product_total\": 61.48,\n    \"total\": 63.08,\n    \"discount_total\": 0.95,\n    \"currency_code\": \"USD\",\n    \"tags\": [\n      \"wholesale\"\n    ],\n    \"warehouses\": [\n      {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    ],\n    \"can_fulfill\": true,\n    \"exact_discount_total\": 0.95,\n    \"is_tax_included\": false,\n    \"tax_total\": 4.11,\n    \"calculated_tax_total\": 4.11,\n    \"exact_tax_total\": 4.11,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"payments\": [],\n    \"notes\": [],\n    \"earliest_covered_ship_by_date\": null,\n    \"latest_covered_ship_by_date\": null,\n    \"has_backorder_lines\": false\n  }\n}"}]},{"name":"Bulk Delete Sales Orders","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders","host":["{{baseUrl}}"],"path":["api","sales-orders"]},"description":"Bulk deletes sales orders in the background. IDs are resolved either from an explicit `ids` array or from a `filters` payload, then chunked (1000 per job) and dispatched as a job batch. Orders without return receipts are deleted first; orders with return receipts are deleted in a second batch.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (scope: one of `ids` or `filters` is required):\n- `ids` (array of int, required without `filters`): Explicit sales order IDs to delete.\n- `filters` (object, required without `ids`): Resolves to a list of sales order IDs via the same Spatie QueryBuilder pipeline the V2 sales-orders list/export use. Two shapes are accepted:\n  - Grouped filters (current list): `{ \\\"filter_groups\\\": \\\"<base64-encoded JSON tree>\\\" }`. The decoded tree looks like `{\\\"conjunction\\\":\\\"and\\\",\\\"children\\\":[{\\\"type\\\":\\\"condition\\\",\\\"condition\\\":{\\\"column\\\":\\\"order_status\\\",\\\"operator\\\":\\\"is\\\",\\\"value\\\":\\\"open\\\"}}]}`.\n  - legacy filter set (JSON string) for older clients.\n- `apply_to_all` (bool, optional): When true the action targets every order matching the active `filters` rather than an explicit `ids` list.\n\nBehavior:\n- Returns 200 immediately; deletion runs asynchronously via a background job batches.\n- Sending `filters` as the grouped `filter_groups` object is fully supported (previously returned a 500).\n\n**Requires permission:** `sales_orders.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders","host":["{{baseUrl}}"],"path":["api","sales-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sales orders are being deleted in the background.\"\n}"}]},{"name":"Bulk Email Customers About Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-email","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-email"]},"description":"Dispatches a tracked background job that emails customers about their selected sales orders. Multiple orders for the same customer (same store + email, case-insensitive) are grouped into a single email (Cin7 Omni model). Recipients without a resolvable email and opted-out customers are suppressed. The send is capped at `config('mail.bulk_sales_order_recipient_cap')` distinct recipients (default 5000); overflow recipients are reported via the job's `skipped_overflow` result and a warning log — never silently dropped. Every send is written to the order's activity log under one batch.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (scope: one of `ids` or `filters` is required):\n- `ids` (array of int, required without `filters`): Sales order IDs to email about.\n- `filters` (object, required without `ids`): Filter set that resolves to a list of sales order IDs (same shape used by the V2 sales-orders listing endpoint). It accepts the grouped `filter_groups` shape (`{ \\\"filter_groups\\\": \\\"<base64 JSON>\\\" }`, same as the V2 list) as well as the legacy JSON-string filter set. Combine with `apply_to_all`.\n- `apply_to_all` (bool, optional): When true, the action targets every order matching the active `filters` rather than an explicit `ids` list.\n- `template_id` (int|null, optional): The `bulk_sales_order` store email template the content was loaded from. Null when the body was composed ad hoc.\n- `subject` (string, required, max 998): Email subject. Supports `{{customer_name}}`, `{{order_count}}`, `{{store_name}}` tokens.\n- `html_body` (string, required): Email body HTML. Supports the same tokens plus `{{orders_table}}` (renders the customer's grouped orders as a table).\n- `cc` (array of email, optional, max 25): CC addresses added to every email.\n- `attachments` (array of string, optional, max 25): Attachable-document keys to include (e.g. `[\"invoice_pdf\"]`).\n- `group_by_customer` (bool, optional, default true): Group every selected order for one customer (same store + email) into a single email (Cin7 Omni model). When false, one email per order.\n- `skip_without_email` (bool, optional, default true): Orders with no resolvable email are always skipped. Must be true — sending `false` is rejected (422).\n- `respect_opt_out` (bool, optional, default true): Skip customers flagged `email_opt_out`.\n\nBehavior:\n- Returns immediately with the tracked job log ID; poll job progress via the tracked job log endpoints (job name `Bulk Email Sales Orders`).\n- The job records per-recipient sent/skipped/failed counts and an `activity_batch_uuid` in its results.\n- The job has `tries = 1` and never auto-retries (prevents double-sends).\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ],\n  \"template_id\": 42,\n  \"subject\": \"An update on your orders, {{customer_name}}\",\n  \"html_body\": \"<p>Hi {{customer_name}},</p><p>Here is a summary of your recent orders:</p>{{orders_table}}\",\n  \"cc\": [\n    \"ops@acme.com\"\n  ],\n  \"attachments\": [\n    \"invoice_pdf\"\n  ],\n  \"group_by_customer\": true,\n  \"skip_without_email\": true,\n  \"respect_opt_out\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-email","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-email"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90210\n  },\n  \"message\": \"Bulk email started for 2 customers (3 orders).\"\n}"}]},{"name":"Preview Bulk Customer Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-email/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-email","preview"]},"description":"Resolves and groups a bulk-email selection without sending anything, powering the confirmation dialog's recipient summary and a masked sample render. Accepts the exact same body as `POST /sales-orders/bulk-email`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body (scope: one of `ids` or `filters` is required):\n- `ids` (array of int, required without `filters`): Sales order IDs to email about.\n- `filters` (object, required without `ids`): Filter set that resolves to a list of sales order IDs (same shape used by the V2 sales-orders listing endpoint). Combine with `apply_to_all`.\n- `apply_to_all` (bool, optional): When true, the action targets every order matching the active `filters` rather than an explicit `ids` list.\n- `template_id` (int|null, optional): The `bulk_sales_order` store email template the content was loaded from. Null when the body was composed ad hoc.\n- `subject` (string, required, max 998): Email subject. Supports `{{customer_name}}`, `{{order_count}}`, `{{store_name}}` tokens.\n- `html_body` (string, required): Email body HTML. Supports the same tokens plus `{{orders_table}}` (renders the customer's grouped orders as a table).\n- `cc` (array of email, optional, max 25): CC addresses added to every email.\n- `attachments` (array of string, optional, max 25): Attachable-document keys to include (e.g. `[\"invoice_pdf\"]`).\n- `group_by_customer` (bool, optional, default true): Group every selected order for one customer (same store + email) into a single email (Cin7 Omni model). When false, one email per order.\n- `skip_without_email` (bool, optional, default true): Orders with no resolvable email are always skipped. Must be true — sending `false` is rejected (422).\n- `respect_opt_out` (bool, optional, default true): Skip customers flagged `email_opt_out`.\n\nResponse data:\n- `order_count` (int): Total orders resolved from the selection.\n- `email_count` (int): Distinct emails that will be sent (after grouping + cap).\n- `skipped_no_email` (array of int): Order IDs with no resolvable email.\n- `skipped_opted_out` (array of int): Order IDs whose customer opted out.\n- `skipped_overflow` (int): Recipients beyond the cap that would be dropped.\n- `groups_preview` (array, max 50): Per-recipient summary with a masked `email`, `order_count`, and `order_numbers`.\n- `sample` (object|null): First group's masked `recipient` plus the rendered `subject` and `body` HTML; null when no group is emailable.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    7116,\n    7117,\n    7118\n  ],\n  \"template_id\": 42,\n  \"subject\": \"An update on your orders, {{customer_name}}\",\n  \"html_body\": \"<p>Hi {{customer_name}},</p><p>Here is a summary of your recent orders:</p>{{orders_table}}\",\n  \"cc\": [\n    \"ops@acme.com\"\n  ],\n  \"attachments\": [\n    \"invoice_pdf\"\n  ],\n  \"group_by_customer\": true,\n  \"skip_without_email\": true,\n  \"respect_opt_out\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/bulk-email/preview","host":["{{baseUrl}}"],"path":["api","sales-orders","bulk-email","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order_count\": 3,\n    \"email_count\": 2,\n    \"skipped_no_email\": [\n      7119\n    ],\n    \"skipped_opted_out\": [\n      7120\n    ],\n    \"skipped_overflow\": 0,\n    \"groups_preview\": [\n      {\n        \"email\": \"j***@acme.com\",\n        \"order_count\": 2,\n        \"order_numbers\": [\n          \"SO-7116\",\n          \"SO-7117\"\n        ]\n      },\n      {\n        \"email\": \"s***@globex.com\",\n        \"order_count\": 1,\n        \"order_numbers\": [\n          \"SO-7118\"\n        ]\n      }\n    ],\n    \"sample\": {\n      \"recipient\": \"j***@acme.com\",\n      \"subject\": \"An update on your orders, Jane Doe\",\n      \"body\": \"<p>Hi Jane Doe,</p><p>Here is a summary of your recent orders:</p><table class='et-sales-order-table'>...</table>\"\n    }\n  }\n}"}]},{"name":"List Order Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfillments"],"variable":[{"key":"salesOrder","value":"123","description":"Sales order ID"}]},"description":"Lists ALL shipments (SalesOrderFulfillments) for a sales order, used by the order's Fulfillment tab. Includes VOIDED shipments: a voided shipment carries a non-null `voided_at` (plus `void_reason` and `voided_by`) and `status=canceled` — it was reversed and its fulfillment order reopened, but is kept for history. The UI buckets voided shipments into a read-only \"Voided\" filter and excludes them from the active lifecycle counts. Each shipment exposes its `fulfillment_lines`, warehouse, shipping method, tracking, and provider-sync timestamps.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSales-channel cross-links: each shipment exposes `sales_channel_fulfillment_link` — non-null only when the shipment originated from a sales channel (Shopify or Faire), discriminated by `channel`. For `channel: \"shopify\"` it carries a `fulfillment` object (deep-link to the Shopify Fulfillment detail page) and a `fulfillment_orders` array (deep-links to each related Shopify Fulfillment Order detail page); its `link_route` already includes the required `?filter[integration_instance_ids]=N` query param. For `channel: \"faire\"` it carries an `order` object (deep-link to the Faire order detail page) and a `shipments` array — one entry per package, since Faire splits an order into one label per box, each with its own `carrier`, `tracking_number`, and `shipping_type`. Every link object has `link_id`, `link_reference`, `link_type_label`, and a `link_route`. Manual / 3PL / FBA shipments return `null` for this field.\n\nMulti-parcel shipments: each shipment also exposes a `parcels` array — one entry per shipped carton. A single shipment can span multiple boxes, each with its own carrier tracking number; `tracking_number` is only the primary (first) carton, while `parcels` is the full deduped list with the primary first. Each entry has `tracking_number`, plus `delivery_status` and `carrier` when live delivery tracking is connected (otherwise null). Only the tracking numbers are exposed — there is no per-carton line-item breakdown, since carriers return tracking numbers with no item-to-carton mapping. Single-parcel shipments return a one-element `parcels` array."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfillments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfillments"],"variable":[{"key":"salesOrder","value":"123","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1002,\n      \"fulfillment_number\": \"SO-0123.2\",\n      \"sales_order_id\": 123,\n      \"fulfillment_order_id\": 452,\n      \"fulfillment_type\": \"sales_channel\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"status\": \"fulfilled\",\n      \"requested_shipping_method\": \"Standard\",\n      \"fulfilled_date\": \"2026-06-10T14:22:00+00:00\",\n      \"tracking_number\": \"9400100000000000000000\",\n      \"tracking_link\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400100000000000000000\",\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"direct\",\n        \"supplier_id\": null,\n        \"is_dropship\": false\n      },\n      \"warehouse_id\": 7,\n      \"fulfilled_by\": {\n        \"id\": 5,\n        \"name\": \"John Smith\"\n      },\n      \"fulfilled_quantity\": 1,\n      \"cost\": 0,\n      \"voided_at\": null,\n      \"void_reason\": null,\n      \"voided_by\": null,\n      \"fulfillment_lines\": [\n        {\n          \"id\": 9002,\n          \"sales_order_line_id\": 55348,\n          \"quantity\": 1\n        }\n      ],\n      \"sales_channel_fulfillment_link\": {\n        \"channel\": \"shopify\",\n        \"fulfillment\": {\n          \"link_id\": 8841,\n          \"link_reference\": \"#63756.1\",\n          \"link_type_label\": \"Shopify Fulfillment\",\n          \"link_route\": \"/integrations/shopify/fulfillments/8841?filter[integration_instance_ids]=2\",\n          \"status\": \"success\",\n          \"status_label\": \"Success\",\n          \"tracking_company\": \"USPS\",\n          \"tracking_number\": \"9400111899223817365534\",\n          \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899223817365534\",\n          \"items\": [\n            {\n              \"sku\": \"RWS20Z\",\n              \"name\": \"Royal White Sturgeon Caviar - 2.0 oz\",\n              \"quantity\": 1\n            }\n          ],\n          \"item_match\": {\n            \"matches\": true,\n            \"lines\": [\n              {\n                \"sku\": \"RWS20Z\",\n                \"name\": \"Royal White Sturgeon Caviar - 2.0 oz\",\n                \"our_qty\": 1,\n                \"channel_qty\": 1,\n                \"state\": \"ok\"\n              }\n            ]\n          }\n        },\n        \"fulfillment_orders\": [\n          {\n            \"link_id\": 14040,\n            \"link_reference\": \"#6189571510390\",\n            \"link_type_label\": \"Shopify Fulfillment Order\",\n            \"link_route\": \"/integrations/shopify/fulfillment-orders/14040?filter[integration_instance_ids]=2\",\n            \"status\": \"closed\",\n            \"status_label\": \"Closed\",\n            \"tracking_company\": null,\n            \"tracking_number\": null,\n            \"tracking_url\": null,\n            \"items\": [\n              {\n                \"sku\": \"RWS20Z\",\n                \"name\": \"Royal White Sturgeon Caviar - 2.0 oz\",\n                \"quantity\": 1\n              }\n            ],\n            \"item_match\": {\n              \"matches\": true,\n              \"lines\": [\n                {\n                  \"sku\": \"GIFTBOX-VARIETY\",\n                  \"name\": \"Variety Flight Gift Box\",\n                  \"our_qty\": 10,\n                  \"channel_qty\": 1,\n                  \"state\": \"bundle\"\n                }\n              ]\n            }\n          }\n        ]\n      },\n      \"parcels\": [\n        {\n          \"tracking_number\": \"9400100000000000000000\",\n          \"delivery_status\": \"in_transit\",\n          \"carrier\": \"USPS\"\n        },\n        {\n          \"tracking_number\": \"9400100000000000000017\",\n          \"delivery_status\": \"delivered\",\n          \"carrier\": \"USPS\"\n        }\n      ]\n    },\n    {\n      \"id\": 1001,\n      \"fulfillment_number\": \"SO-0123.1\",\n      \"sales_order_id\": 123,\n      \"fulfillment_order_id\": 451,\n      \"fulfillment_type\": \"starshipit\",\n      \"fulfillment_status\": \"submitted\",\n      \"status\": \"submitted\",\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"fulfilled_date\": null,\n      \"tracking_number\": null,\n      \"tracking_link\": null,\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"direct\",\n        \"supplier_id\": null,\n        \"is_dropship\": false\n      },\n      \"warehouse_id\": 7,\n      \"fulfilled_by\": {\n        \"id\": 5,\n        \"name\": \"John Smith\"\n      },\n      \"fulfilled_quantity\": 2,\n      \"cost\": 0,\n      \"voided_at\": null,\n      \"void_reason\": null,\n      \"voided_by\": null,\n      \"fulfillment_lines\": [\n        {\n          \"id\": 9001,\n          \"sales_order_line_id\": 55347,\n          \"quantity\": 2\n        }\n      ],\n      \"sales_channel_fulfillment_link\": null,\n      \"parcels\": [\n        {\n          \"tracking_number\": \"9400100000000000000000\",\n          \"delivery_status\": \"in_transit\",\n          \"carrier\": \"USPS\"\n        },\n        {\n          \"tracking_number\": \"9400100000000000000017\",\n          \"delivery_status\": \"delivered\",\n          \"carrier\": \"USPS\"\n        }\n      ]\n    },\n    {\n      \"id\": 1000,\n      \"fulfillment_number\": \"SO-0123.0\",\n      \"sales_order_id\": 123,\n      \"fulfillment_order_id\": 451,\n      \"fulfillment_type\": \"starshipit\",\n      \"fulfillment_status\": \"canceled\",\n      \"status\": \"canceled\",\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"fulfilled_date\": null,\n      \"tracking_number\": null,\n      \"tracking_link\": null,\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"direct\",\n        \"supplier_id\": null,\n        \"is_dropship\": false\n      },\n      \"warehouse_id\": 7,\n      \"fulfilled_by\": {\n        \"id\": 5,\n        \"name\": \"John Smith\"\n      },\n      \"fulfilled_quantity\": 2,\n      \"cost\": 0,\n      \"voided_at\": \"2026-06-02T20:45:00+00:00\",\n      \"void_reason\": \"wrong warehouse selected\",\n      \"voided_by\": {\n        \"id\": 5,\n        \"name\": \"John Smith\"\n      },\n      \"fulfillment_lines\": [\n        {\n          \"id\": 9000,\n          \"sales_order_line_id\": 55347,\n          \"quantity\": 2\n        }\n      ],\n      \"sales_channel_fulfillment_link\": null,\n      \"parcels\": [\n        {\n          \"tracking_number\": \"9400100000000000000000\",\n          \"delivery_status\": \"in_transit\",\n          \"carrier\": \"USPS\"\n        },\n        {\n          \"tracking_number\": \"9400100000000000000017\",\n          \"delivery_status\": \"delivered\",\n          \"carrier\": \"USPS\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Sales Order Backorder Coverage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/backorders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","backorders"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Gets backorder coverage data for a sales order — whether any of its lines are backordered, and the expected-arrival window of the incoming purchase orders that cover those backorders.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse fields:\n- earliest_covered_ship_by_date (date|null): The earliest resolved arrival date (ETA) among the purchase order lines allocated to the order's backordered lines. Null when no backordered line is covered by a purchase order.\n- latest_covered_ship_by_date (date|null): The latest such ETA — the date by which all covered backordered lines are expected to be shippable.\n- has_backorder_lines (boolean): True when the order has at least one backordered line.\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/backorders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","backorders"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"earliest_covered_ship_by_date\": \"2026-07-18\",\n    \"latest_covered_ship_by_date\": \"2026-08-02\",\n    \"has_backorder_lines\": true\n  }\n}"}]},{"name":"Get Sales Order Channel Document","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/document","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","document"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]},"description":"Gets the original sales-channel order document for a sales order — the raw order snapshot imported from the connected marketplace or cart (Shopify, Amazon, etc.).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBehavior:\n- The document's shape varies by sales channel: it is the channel-specific order record as stored at import time (order identifiers, financial/fulfillment statuses, totals, addresses, and channel metadata). The example below shows a Shopify-shaped document; other channels return their own field sets.\n- For documents from channels that expose a connected shop, the `integration_instance` relation is included so the document can be tied back to the specific store connection.\n- Returns `data: null` for manually created orders (orders with no sales-channel origin).\n\nPath parameters:\n- salesOrder (required): Sales order ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/document","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","document"],"variable":[{"key":"salesOrder","value":"500","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8123,\n    \"integration_instance_id\": 3,\n    \"shopify_customer_id\": 4471,\n    \"legacy_resource_id\": 5723198862,\n    \"name\": \"#1042\",\n    \"email\": \"buyer@example.com\",\n    \"currency\": \"USD\",\n    \"financial_status\": \"paid\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"risk_level\": \"low\",\n    \"test\": false,\n    \"subtotal_price\": 225,\n    \"total_discounts\": 0,\n    \"total_price\": 258.9,\n    \"total_tax\": 18.9,\n    \"total_shipping_price\": 15,\n    \"taxes_included\": false,\n    \"tags\": \"wholesale\",\n    \"note\": null,\n    \"source_name\": \"web\",\n    \"source_identifier\": null,\n    \"shopify_created_at\": \"2026-07-05T18:12:44.000000Z\",\n    \"shopify_updated_at\": \"2026-07-05T18:14:02.000000Z\",\n    \"shopify_processed_at\": \"2026-07-05T18:12:45.000000Z\",\n    \"shopify_cancelled_at\": null,\n    \"cancel_reason\": null,\n    \"shopify_closed_at\": null,\n    \"billing_address_json\": {\n      \"name\": \"Riley Chen\",\n      \"address1\": \"310 Harbor Way\",\n      \"city\": \"Oakland\",\n      \"province_code\": \"CA\",\n      \"zip\": \"94607\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_address_json\": {\n      \"name\": \"Riley Chen\",\n      \"address1\": \"310 Harbor Way\",\n      \"city\": \"Oakland\",\n      \"province_code\": \"CA\",\n      \"zip\": \"94607\",\n      \"country_code\": \"US\"\n    },\n    \"custom_attributes\": [],\n    \"metafields\": null,\n    \"archived_at\": null,\n    \"created_at\": \"2026-07-05T18:15:10.000000Z\",\n    \"updated_at\": \"2026-07-05T18:15:10.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"Acme Shopify Store\",\n      \"shop_url\": \"acme-store.myshopify.com\"\n    }\n  }\n}"}]},{"name":"Download Sales Orders Export","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/list/export/download?file=sales-orders-2026-07-10-13-00-00.xlsx","host":["{{baseUrl}}"],"path":["api","sales-orders","list","export","download"],"query":[{"key":"file","value":"sales-orders-2026-07-10-13-00-00.xlsx","description":"Filename returned in the completed tracked job's results.file. The server basenames this value and serves the stored export; unknown filenames yield 404.","disabled":true}]},"description":"Downloads a completed background export produced by Export Sales Orders (queued path). The filename is the one reported in the tracked job log's results.file field.\n\nAuthentication: Requires Bearer token. Scope: orders (read).\n\nResponse is the binary file (CSV or XLSX) with an attachment Content-Disposition header. Returns 404 if the file param is empty or the file no longer exists.\n\n**Requires permission:** `sales_orders.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/list/export/download?file=sales-orders-2026-07-10-13-00-00.xlsx","host":["{{baseUrl}}"],"path":["api","sales-orders","list","export","download"],"query":[{"key":"file","value":"sales-orders-2026-07-10-13-00-00.xlsx","description":"Filename returned in the completed tracked job's results.file. The server basenames this value and serves the stored export; unknown filenames yield 404.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary file>"}]}]},{"name":"Sales Order Lines","item":[{"name":"Get Sales Order Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLineId}","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLineId"],"variable":[{"key":"salesOrderLineId","value":"1001","description":"Sales order line ID"}]},"description":"Get detailed information for a single sales order line. Includes inventory allocation details with purchase order coverage and release sources.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLineId}","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLineId"],"variable":[{"key":"salesOrderLineId","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"next_scheduled_po\": {\n      \"date\": \"2024-04-01\",\n      \"purchase_order_id\": 55\n    },\n    \"active_coverages\": [\n      {\n        \"purchase_order_id\": 55,\n        \"purchase_order_number\": \"PO-2024-001\",\n        \"quantity\": 10,\n        \"date\": \"2024-03-01\",\n        \"eta\": \"2024-04-15\"\n      }\n    ],\n    \"releases\": [\n      {\n        \"id\": 201,\n        \"link\": {\n          \"id\": 55,\n          \"type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n          \"parent_type\": \"App\\\\Models\\\\PurchaseOrder\"\n        },\n        \"reference\": \"PO-2024-001\",\n        \"quantity\": 10,\n        \"release_date\": \"2024-03-10T08:00:00Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Delete Sales Order Line","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines","host":["{{baseUrl}}"],"path":["api","sales-order-lines"]},"description":"**Deletes a SINGLE sales order line**, identified by `line_id` in the request BODY — despite the collection-level path (`DELETE /api/sales-order-lines`), this is not a bulk or delete-all operation. For multi-line deletes use `DELETE /api/sales-order-lines/bulk`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nDelete a single sales order line. Recalculates order discounts if any were applied.\n\nAuthentication: Requires Bearer token.\n\nRestrictions:\n- Cannot delete if the line has associated fulfillment lines\n- Cannot delete the last line on a sales order\n\nBody:\n- line_id (required): ID of the sales order line to delete"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-order-lines","host":["{{baseUrl}}"],"path":["api","sales-order-lines"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Sales Order Lines","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/bulk","host":["{{baseUrl}}"],"path":["api","sales-order-lines","bulk"]},"description":"Bulk delete multiple sales order lines. Handles partial success and returns details of each line's outcome.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of integer sales order line IDs (min 1)"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-order-lines/bulk","host":["{{baseUrl}}"],"path":["api","sales-order-lines","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"partial\",\n  \"deleted\": [\n    1001,\n    1002\n  ],\n  \"failed\": [\n    {\n      \"id\": 1003,\n      \"message\": \"Line is fully/partially fulfilled.\"\n    }\n  ],\n  \"deleted_count\": 2\n}"}]},{"name":"Update Line Nominal Code","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/nominal-code","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","nominal-code"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"}]},"description":"Set or clear the nominal code override for a single sales order line. Used by the line-level nominal code editor on the V2 sales order detail page (only visible when the `accounting.use_sales_order_line_nominal_codes` config flag is true).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWhen `nominal_code_id` is null, the explicit override is cleared. The line's `getNominalCodeId` resolution chain (line → product → sales channel → global) still applies on save, so the field may auto-snapshot a resolved code afterwards.\n\nAuthentication: Requires Bearer token with `orders:write` scope.\n\nBody:\n- nominal_code_id (nullable, integer): existing nominal code ID, or null to clear the override.","body":{"mode":"raw","raw":"{\n  \"nominal_code_id\": 42\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/nominal-code","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","nominal-code"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Nominal code updated successfully\",\n  \"data\": {\n    \"sales_order_line_id\": 1001,\n    \"item_nominal_code_id\": 42,\n    \"item_nominal_code\": \"Sales\",\n    \"item_nominal_code_code\": \"4000\"\n  }\n}"}]},{"name":"Reorder Sales Order Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/reorder","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines","reorder"],"variable":[{"key":"salesOrder","value":"55","description":"The sales order ID."}]},"description":"Persist a new top-to-bottom ordering for a sales order's product lines.\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ordered_ids (required, integer array): sales order line ids in the desired order. A partial list is allowed — any line not listed keeps its relative order after the listed set. Every id must belong to this sales order (otherwise 422).\n\nReturns the resulting line ids in their new order under data.ids.\n\n**Requires permission:** `sales_orders.update`","body":{"mode":"raw","raw":"{\n  \"ordered_ids\": [\n    104,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/reorder","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines","reorder"],"variable":[{"key":"salesOrder","value":"55","description":"The sales order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ids\": [\n      104,\n      102,\n      103\n    ]\n  }\n}"}]},{"name":"Map Line to Product","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/map","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","map"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]},"description":"Map a sales order line to an existing product. Used to link unmapped channel order lines to SKU products.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- product_id (required): ID of the product to map to","body":{"mode":"raw","raw":"{\n  \"product_id\": 42\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/map","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","map"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order line has been mapped to the product\"\n}"}]},{"name":"Bulk Map Lines to Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/bulk-map","host":["{{baseUrl}}"],"path":["api","sales-order-lines","bulk-map"]},"description":"Map multiple unmapped sales order lines to the same product at once.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- product_id (required): ID of the product to map all lines to\n- line_ids (required): Array of sales order line IDs to map (min 1)\n\nOnly maps lines that are currently unmapped (product_id is null).","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"line_ids\": [\n    1001,\n    1002,\n    1003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/bulk-map","host":["{{baseUrl}}"],"path":["api","sales-order-lines","bulk-map"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapped 3 line(s) to product\",\n  \"data\": {\n    \"mapped_count\": 3\n  }\n}"}]},{"name":"Mark Line as Non-Product","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/make-as-non-product","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","make-as-non-product"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]},"description":"Mark an unmapped sales order line as a non-product line (e.g. shipping fee, gift wrapping). Only applicable to lines with no product_id.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/make-as-non-product","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","make-as-non-product"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order line has been marked as a non-product line\"\n}"}]},{"name":"Get Matching Unmapped Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/matching-unmapped","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","matching-unmapped"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"}]},"description":"Find other unmapped sales order lines across all orders that have the same product description as the given line. Useful for bulk mapping suggestions.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/matching-unmapped","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","matching-unmapped"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1005,\n      \"sales_order_id\": 305,\n      \"sales_order_number\": \"SO-2024-305\",\n      \"order_status\": \"open\",\n      \"order_date\": \"2024-03-10\",\n      \"quantity\": 2,\n      \"amount\": 29.99\n    }\n  ]\n}"}]},{"name":"Replace Line Product(s)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/replace","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","replace"],"variable":[{"key":"salesOrderLine","value":"33421","description":"Sales order line id to replace"}]},"description":"Replace a single sales order line with one or more SKUs, preserving the line's total amount and the order ↔ sales-channel tie.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- `salesOrderLine` (required): id of the sales order line to replace.\n\nBody:\n- `replacements` (required, array, min 1): the target SKUs. Each item:\n    - `product_id` (required, int, must exist in products)\n    - `quantity` (required, number > 0)\n    - `amount` (optional, number >= 0): per-unit price. When omitted on ALL items, the original line total is prorated across the replacements by catalog price; when provided, the explicit amounts must reconcile to the original total (else 422).\n- `mapping_mode` (optional, `one_time` | `permanent`, default `one_time`): only meaningful for a SINGLE-SKU replacement at the original quantity that resolves to a channel listing. `permanent` remaps the channel listing so every FUTURE order maps to the new SKU (sets product_mapping_overridden so the line survives a channel resync); `one_time` changes only this order. Multi-SKU replacements are always one-time.\n\nReturns the refreshed sales order.\n\nErrors:\n- 409: the line is committed to fulfillment (has a fulfillment line or an in-flight/submitted fulfillment order) — void/cancel the fulfillment first.\n- 422: explicit replacement amounts don't reconcile to the line total, or validation failed (unknown product, quantity <= 0, missing replacements).","body":{"mode":"raw","raw":"{\n  \"replacements\": [\n    {\n      \"product_id\": 4567,\n      \"quantity\": 2,\n      \"amount\": 19.99\n    },\n    {\n      \"product_id\": 8901,\n      \"quantity\": 1\n    }\n  ],\n  \"mapping_mode\": \"one_time\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/replace","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","replace"],"variable":[{"key":"salesOrderLine","value":"33421","description":"Sales order line id to replace"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 33188,\n    \"sales_order_number\": \"#63676\",\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"item_info\": [\n      {\n        \"id\": 99001,\n        \"product_id\": 4567,\n        \"sku\": \"REPL-A\",\n        \"quantity\": 2,\n        \"amount\": 19.99,\n        \"product_mapping_overridden\": false\n      },\n      {\n        \"id\": 99002,\n        \"product_id\": 8901,\n        \"sku\": \"REPL-B\",\n        \"quantity\": 1,\n        \"amount\": 9.62,\n        \"product_mapping_overridden\": false\n      }\n    ]\n  }\n}"}]},{"name":"Manage Reservations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/reservations","host":["{{baseUrl}}"],"path":["api","sales-order-lines","reservations"]},"description":"Reserve or reverse-reserve inventory for specific sales order lines. Returns the updated sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- sales_order_id (required): ID of the parent sales order\n- sales_order_lines (required): Array of line reservation actions\n- sales_order_lines[].id (required): Sales order line ID\n- sales_order_lines[].quantity (required): Quantity to reserve/reverse (> 0, < 100,000)\n- sales_order_lines[].action (required): One of `reserve` or `reverse_reservation`\n\nValidation:\n- Returns 422 when a `reserve` action targets a line where `sales_channel_fulfillment_out_of_sync = true`. These lines are auto-allocated by the inventory pipeline once stock arrives, so manual reservation is rejected by design. The error key is `sales_order_lines.{index}.id`.","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 300,\n  \"sales_order_lines\": [\n    {\n      \"id\": 1001,\n      \"quantity\": 5,\n      \"action\": \"reserve\"\n    },\n    {\n      \"id\": 1002,\n      \"quantity\": 3,\n      \"action\": \"unreserve\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/reservations","host":["{{baseUrl}}"],"path":["api","sales-order-lines","reservations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales order has been successfully created\",\n  \"data\": {\n    \"id\": 300,\n    \"sales_order_number\": \"SO-2024-300\",\n    \"order_status\": \"open\",\n    \"sales_order_lines\": [\n      {\n        \"id\": 1001,\n        \"quantity\": 5,\n        \"reserved_quantity\": 5,\n        \"product_id\": 42\n      }\n    ]\n  }\n}"}]},{"name":"Convert to Financial Line","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/{financialLineType}/convert-to-financial-line","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine",":financialLineType","convert-to-financial-line"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"},{"key":"financialLineType","value":"revenue","description":"Financial line type slug"}]},"description":"Convert a sales order line to a specific financial line type (e.g., revenue, adjustment).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/{financialLineType}/convert-to-financial-line","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine",":financialLineType","convert-to-financial-line"],"variable":[{"key":"salesOrderLine","value":"1001","description":"Sales order line ID"},{"key":"financialLineType","value":"revenue","description":"Financial line type slug"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sales order line successfully converted to revenue line\"\n}"}]},{"name":"Suggest Fulfillment Warehouse","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/suggest-warehouse","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","suggest-warehouse"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]},"description":"Read-only fulfillment-routing suggestion for an UNALLOCATED line. Runs the same warehouse priority + on-hand check the real routing uses to pick a default warehouse, and returns the ordered candidates with per-warehouse availability so the Allocate dialog can explain WHY a warehouse won and offer an override. Allocation itself is then performed via the split-across-warehouses endpoint with a single slice. Authenticate with a Personal Access Token (PAT).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/suggest-warehouse","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","suggest-warehouse"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sales_order_line_id\": 55347,\n    \"quantity_needed\": 4,\n    \"chosen_warehouse_id\": 9,\n    \"chosen_warehouse_name\": \"Main Warehouse\",\n    \"strategy\": \"priority\",\n    \"strategy_label\": \"Configured warehouse priority order\",\n    \"candidates\": [\n      {\n        \"warehouse_id\": 1,\n        \"warehouse_name\": \"Default Warehouse\",\n        \"warehouse_type\": \"direct\",\n        \"priority_rank\": 1,\n        \"available\": 0,\n        \"has_stock\": false,\n        \"fully_covers\": false,\n        \"chosen\": false\n      },\n      {\n        \"warehouse_id\": 9,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"warehouse_type\": \"direct\",\n        \"priority_rank\": 2,\n        \"available\": 50,\n        \"has_stock\": true,\n        \"fully_covers\": true,\n        \"chosen\": true\n      }\n    ]\n  }\n}"}]},{"name":"Split Line Across Warehouses","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/split-across-warehouses","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","split-across-warehouses"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]},"description":"Redistribute a sales order line's **pre-dispatch** fulfillment across multiple warehouses WITHOUT duplicating the line (Pattern C). The channel line stays 1:1 with upstream; the split materialises as **one InventoryAllocation + one FulfillmentOrder per warehouse** (`1 SOL → N allocations → N FOs`). Each slice allocates on-hand up to availability at that warehouse, with the remainder planned (backorder).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Pre-dispatch only.** Allowed while every fulfillment order for the line is still `open + unsubmitted`. Once any FO has been submitted to a carrier the line can no longer be redistributed — returns **409**.\n\n**Body fields:**\n- `slices` (required, array, min 1) — the target distribution.\n- `slices[].warehouse_id` (required, integer, must exist) — destination warehouse for this slice.\n- `slices[].quantity` (required, integer, min 1) — units to fulfil from that warehouse.\n\nThe slice total must not exceed the line's unfulfilled quantity (**422** otherwise). Duplicate warehouses are merged. Returns the refreshed sales order.","body":{"mode":"raw","raw":"{\n  \"slices\": [\n    {\n      \"warehouse_id\": 9,\n      \"quantity\": 3\n    },\n    {\n      \"warehouse_id\": 11,\n      \"quantity\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/split-across-warehouses","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","split-across-warehouses"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"sales_order_number\": \"SO-0123\",\n    \"order_status\": \"open\",\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 55347,\n        \"item_quantity\": 5,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"allocated_quantity\": 5,\n        \"on_hand_allocated_quantity\": 3,\n        \"planned_quantity\": 1,\n        \"awaiting_receipt_quantity\": 1,\n        \"backorder_warehouses\": [\n          {\n            \"warehouse_id\": 9,\n            \"quantity\": 1,\n            \"status\": \"planned\"\n          },\n          {\n            \"warehouse_id\": 12,\n            \"quantity\": 1,\n            \"status\": \"awaiting_receipt\"\n          }\n        ],\n        \"warehouse\": {\n          \"id\": 9,\n          \"name\": \"Default Warehouse\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Cancel Line Quantity","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/cancel-quantity","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","cancel-quantity"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]},"description":"Cancel part (or all) of a sales order line's remaining quantity **without changing the ordered quantity** — the line keeps its original `quantity` as a permanent record and `canceled_quantity` rises, so the net quantity to fulfill drops. Cancelling everything nets the line to zero: allocations are released, backorder demand clears, and any open (not yet submitted) fulfillment orders shrink to match.\n\nUnits already shipped, externally fulfilled, committed to a live fulfillment (submitted / picked / packed, a staged pickup, or an order already handed to a shipping provider), or already cancelled cannot be cancelled — cancel or void that fulfillment first. Exceeding the cancellable quantity returns **409**.\n\n**Body fields:**\n- `quantity` (required, integer, min 1) — units to cancel.\n- `reason` (optional, string, max 1000) — recorded on the order's notes for the audit trail.\n\nReturns the refreshed sales order.","body":{"mode":"raw","raw":"{\n  \"quantity\": 1,\n  \"reason\": \"Item out of stock — replacement line added\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{salesOrderLine}/cancel-quantity","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":salesOrderLine","cancel-quantity"],"variable":[{"key":"salesOrderLine","value":"55347","description":"SalesOrderLine ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"sales_order_number\": \"SO-0123\",\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"item_info\": [\n      {\n        \"sales_order_line_id\": 55347,\n        \"item_quantity\": 1,\n        \"item_canceled_quantity\": 1,\n        \"fulfilled_quantity\": 0,\n        \"submitted_quantity\": 0,\n        \"allocated_quantity\": 0,\n        \"warehouse\": {\n          \"id\": 9,\n          \"name\": \"Default Warehouse\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Import Lines from CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/import","host":["{{baseUrl}}"],"path":["api","sales-order-lines","import"]},"description":"Import sales order lines from a CSV file or raw CSV string. Required CSV columns: sku. Optional columns: description, quantity, price, pricing_tier, warehouse_id, warehouse_name.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIf sales_order_id is provided, lines are added to that order. Otherwise, returns a preview of parsed lines (useful for the import UI).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"csvString","type":"text","value":""},{"key":"sales_order_id","type":"text","value":""},{"key":"replace","type":"text","value":""},{"key":"separator","type":"text","value":""},{"key":"escape","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/import","host":["{{baseUrl}}"],"path":["api","sales-order-lines","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales order lines have been successfully imported\",\n  \"data\": [\n    {\n      \"product_id\": 42,\n      \"description\": \"Blue Widget 500ml\",\n      \"quantity\": 5,\n      \"amount\": 29.99,\n      \"is_product\": true,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      }\n    }\n  ]\n}"}]},{"name":"Override Edition","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/override-edition","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","override-edition"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]},"description":"Override the subscription edition for a sales order line. Assigns a specific edition instead of the automatically resolved one.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- subscription_edition_id (required): ID of the subscription edition to apply\n- reason (optional): Reason for the override, max 500 characters","body":{"mode":"raw","raw":"{\n  \"subscription_edition_id\": 7,\n  \"reason\": \"Customer requested upgrade to premium edition\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/override-edition","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","override-edition"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Edition override applied successfully\",\n  \"data\": {\n    \"sales_order_line_id\": 1001,\n    \"subscription_edition_id\": 7,\n    \"product_id\": 42,\n    \"edition_name\": \"Premium Annual\"\n  }\n}"}]},{"name":"Clear Edition Override","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/clear-edition-override","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","clear-edition-override"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]},"description":"Clear the edition override on a sales order line, reverting to automatic edition resolution.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-lines/{sales_order_line}/clear-edition-override","host":["{{baseUrl}}"],"path":["api","sales-order-lines",":sales_order_line","clear-edition-override"],"variable":[{"key":"sales_order_line","value":"1001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Edition override cleared\"\n}"}]}]},{"name":"Fulfillments","item":[{"name":"List Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments?page=1&per_page=10&sort=-id","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix - for descending. Allowed: id, status, fulfillment_type, tracking_number, cost, fulfilled_at, packing_slip_printed_at, created_at, updated_at","disabled":true}]},"description":"Returns paginated sales order fulfillments for the V2 fulfillments list page. Supports GroupedFilterSupport filter_groups tree for advanced filtering.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nDefault behavior: excludes archived fulfillments unless filter[archived] is provided.\n\nFilter columns (all support operator suffix, e.g. filter[column.contains]):\n• Basic: id (numeric), fulfillment_number, fulfillment_sequence (numeric), tracking_number, status, fulfillment_type, requested_shipping_method, fulfilled_shipping_method, backordered, warehouse\n• Sales Order: customer_reference, store, sales_channel_type_name, sales_order_shipping_method, sales_order_tags\n• Customer: customer_name, customer_email, customer_phone, customer_company, customer_address, customer_city, customer_province, customer_province_code, customer_zip, customer_country, customer_country_code\n• Items: item_name, item_sku, item_quantity (numeric), item_price (numeric), item_nominal_code\n• Financial: cost (numeric)\n• Dates: fulfilled_at, packing_slip_printed_at, created_at, updated_at, archived_at\n\nText operators: is, is_not, contains, does_not_contain, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty (negative ops use whereDoesntHave for relationships).\nNumeric operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\nDatetime operators: same as numeric plus relative ranges.\n\nAvailable sorts: id, status, fulfillment_type, tracking_number, cost, fulfilled_at, packing_slip_printed_at, created_at, updated_at (default: -id)\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals.\n\nEach row's sales_order includes customer_id (links the customer column to its detail page), and sales_channel returns name (integration TYPE, e.g. Shopify) plus integration_name (the connection/instance, e.g. \"Curvy AU\")."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments?page=1&per_page=10&sort=-id","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix - for descending. Allowed: id, status, fulfillment_type, tracking_number, cost, fulfilled_at, packing_slip_printed_at, created_at, updated_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"fulfillment_number\": \"FF-1001\",\n      \"fulfillment_sequence\": 1,\n      \"status\": \"submitted\",\n      \"fulfillment_type\": \"shipstation\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_link\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"cost\": \"12.50\",\n      \"fulfilled_at\": \"2024-01-18T14:00:00.000000Z\",\n      \"packing_slip_printed_at\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-18T14:00:00.000000Z\",\n      \"archived_at\": null,\n      \"is_parent\": false,\n      \"parent_id\": null,\n      \"sales_order\": {\n        \"id\": 500,\n        \"sales_order_number\": \"SO-20240115-500\",\n        \"order_date\": \"2024-01-15\",\n        \"order_status\": \"fulfilled\",\n        \"customer_name\": \"Acme Corp\",\n        \"customer_reference\": \"PO-2024-001\",\n        \"customer_id\": 281384\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"is_pickup\": false,\n      \"requested_shipping_method_text\": null,\n      \"fulfilled_shipping_method\": \"UPS Ground\",\n      \"fulfilled_shipping_method_text\": null,\n      \"sales_channel\": {\n        \"name\": \"shopify\",\n        \"integration_name\": \"Curvy AU\"\n      },\n      \"store\": \"My Shopify Store\",\n      \"item_count\": 2,\n      \"total_quantity\": 5\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 10,\n  \"per_page\": 10,\n  \"total\": 95,\n  \"unfiltered_total\": 1247,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Export Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"Export mode: summary (one row per fulfillment, default) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default, uses active filters), all (ignore filters), current_page, or selected","disabled":true}]},"description":"Exports sales order fulfillments as XLSX or CSV.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSummary mode columns: ID, Fulfillment #, Status, Type, Order #, Customer, Warehouse, Tracking #, Req. Method, Req. Method (Manual), Ful. Method, Ful. Method (Manual), Items, Qty, Cost, Fulfilled At, Packing Slip Printed At, Created At, Updated At.\n\nLine items mode also includes per-line: Item SKU, Item Name, Item Description, Item Qty, Unit Price, Line Total.\n\nAuthentication: Requires Bearer token.\n\nResponse: File download (binary), not JSON."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"Export mode: summary (one row per fulfillment, default) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default, uses active filters), all (ignore filters), current_page, or selected","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[Binary XLSX file download — fulfillments-2024-01-20-10-30-00.xlsx]"}]},{"name":"Get Fulfillment Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/detail","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","detail"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Returns full fulfillment detail including all related data: lines with products, sales order with addresses, warehouse, shipping methods, shipping provider orders (Shipstation, Shipfusion, etc.).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/detail","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","detail"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1001,\n    \"fulfillment_order_id\": 42,\n    \"fulfillment_number\": \"FF-1001\",\n    \"status\": \"submitted\",\n    \"fulfillment_type\": \"shipstation\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"cost\": \"12.50\",\n    \"fulfilled_at\": \"2024-01-18T14:00:00.000000Z\",\n    \"sales_order\": {\n      \"id\": 500,\n      \"sales_order_number\": \"SO-20240115-500\",\n      \"billing_address\": {\n        \"name\": \"Acme Corp\",\n        \"address1\": \"123 Main St\"\n      },\n      \"shipping_address\": {\n        \"name\": \"Acme Corp\",\n        \"address1\": \"456 Ship Lane\"\n      }\n    },\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"sales_order_fulfillment_lines\": [\n      {\n        \"id\": 2001,\n        \"quantity\": 3,\n        \"sales_order_line\": {\n          \"id\": 3001,\n          \"product\": {\n            \"id\": 42,\n            \"sku\": \"WIDGET-001\",\n            \"name\": \"Premium Widget\"\n          }\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Get Fulfillment Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/line-items","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","line-items"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Returns lightweight line items for a fulfillment's expandable row. Each item includes id, quantity, unit_cost, sku, product_name, and product_id. `unit_cost` is the per-unit cost of goods sold (FIFO-derived, prorated to the fulfilled quantity) — NOT the sale price; it is 0 when the line has no financial cost record.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/line-items","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","line-items"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2001,\n      \"quantity\": 3,\n      \"unit_cost\": 12.5,\n      \"sku\": \"WIDGET-001\",\n      \"product_name\": \"Premium Widget\",\n      \"product_id\": 42\n    }\n  ]\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Returns paginated activity log for a fulfillment, including activities on the fulfillment itself and all its child records (lines, etc.).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8001,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"SalesOrderFulfillment\",\n      \"subject_id\": 1001,\n      \"properties\": {\n        \"old\": {\n          \"status\": \"pending\"\n        },\n        \"attributes\": {\n          \"status\": \"submitted\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2024-01-18T14:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Returns paginated inventory movements linked to the fulfillment or any of its fulfillment lines.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"type\": \"sale\",\n      \"inventory_status\": \"available\",\n      \"quantity\": -3,\n      \"reference\": \"SO-20240115-500.1\",\n      \"inventory_movement_date\": \"2024-01-18\",\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Premium Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": \"15.00\",\n      \"unit_cost_provisional\": false,\n      \"link_type\": \"App\\\\Models\\\\SalesOrderFulfillmentLine\",\n      \"link_id\": 2001,\n      \"parent_link_id\": 1001,\n      \"detail_link_id\": null,\n      \"layer\": {\n        \"fifo_layer_id\": 55,\n        \"name\": \"fifo\"\n      },\n      \"created_at\": \"2024-01-18T14:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Clear Channel Submission","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/clear-channel-submission","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","clear-channel-submission"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Clears the submitted_to_sales_channel_at timestamp so the fulfillment will be resubmitted on the next sync. Works regardless of sales order status.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/clear-channel-submission","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","clear-channel-submission"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Channel submission cleared — will be resubmitted\"\n}"}]},{"name":"Submit to Sales Channel","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/submit-to-channel","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","submit-to-channel"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Submits (or resubmits) fulfillment tracking info to the sales channel (e.g. Shopify) synchronously. Only sends tracking to the sales channel — NOT to the shipping provider.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/submit-to-channel","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","submit-to-channel"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment submitted to sales channel\"\n}"}]},{"name":"Resync to Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/resync-to-provider","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","resync-to-provider"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Re-syncs the fulfillment to the shipping provider by sending the current line state. Only available for update-capable providers (Shipfusion, ShipHero, etc.) with submitted fulfillments.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/resync-to-provider","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","resync-to-provider"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment re-synced to provider successfully\"\n}"}]},{"name":"Resync from Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/resync-from-provider","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","resync-from-provider"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Fetches the latest data FROM the shipping provider (tracking, status, etc.) and updates the local fulfillment record. Supported providers: Shipstation, Starshipit, Shipfusion, ShipHero, Trackstar, Veracore.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/resync-from-provider","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","resync-from-provider"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetched and updated from provider\",\n  \"shipment_status\": \"delivered\",\n  \"tracking_pipeline_ran\": true\n}"}]},{"name":"Cancel Provider Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/cancel-provider-order","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","cancel-provider-order"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Cancels the provider-side fulfillment order. Supported providers: Amazon MCF (FBA), Shipfusion, ShipHero, Trackstar, Veracore.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/cancel-provider-order","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","cancel-provider-order"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Provider order cancelled successfully\"\n}"}]},{"name":"Edit Shipping Details","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/shipping-details","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","shipping-details"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]},"description":"Edit an existing fulfillment's shipping details — tracking number and shipping cost. A narrow, guard-free update: unlike the fulfill flow it does NOT require an open sales order or fulfillment lines, so a tracking number can be corrected after the order has shipped/closed. Never changes the warehouse (Stage 0 lock untouched).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional — send only what changes):\n- tracking_number (string, nullable, max 255)\n- cost (numeric, nullable, >= 0, < 100000)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"cost\": 12.5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/v2/sales-order-fulfillments/{salesOrderFulfillment}/shipping-details","host":["{{baseUrl}}"],"path":["api","v2","sales-order-fulfillments",":salesOrderFulfillment","shipping-details"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipping details updated\"\n}"}]},{"name":"Get Fulfillment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"4821","description":"Fulfillment (shipment) ID"}]},"description":"Get a single fulfillment (shipment) with its lines, parent sales order summary, warehouse, tracking, and void audit fields.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach fulfillment line includes the linked sales order line and product (with lot-tracking configuration) plus a live `item_inventory` breakdown per warehouse (stock, allocated, available, inbound, in transit).\n\nKey fields:\n- `status` / `fulfillment_status` — `submitted`, `acknowledged`, `picked`, `packed`, `fulfilled`, `canceled`, or `awaiting_pickup`\n- `fulfillment_type` — `manual`, `shipstation`, `starshipit`, `shipmyorders`, `fba`, `walmart_wfs`, `veracore`, `shiphero`, `shipfusion`, `d3`, `trackstar`, `pickup`, or `sales_channel`\n- `fulfillment_number` — `{sales_order_number}.{sequence}`, e.g. `SO-10412.1`\n- `voided_at` / `void_reason` / `voided_by` — set when the shipment has been voided\n\nArchived fulfillments are still returned. Requires the `orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"4821","description":"Fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 4821,\n    \"fulfillment_number\": \"SO-10412.1\",\n    \"sales_order_id\": 10412,\n    \"fulfillment_order_id\": 3377,\n    \"fulfillment_type\": \"shipstation\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"shipping_method_id\": 12,\n    \"requested_shipping_method_id\": 12,\n    \"fulfilled_shipping_method_id\": 14,\n    \"fulfilled_date\": \"2026-06-28T14:03:22.000000Z\",\n    \"tracking_number\": \"9400111899223197428490\",\n    \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899223197428490\",\n    \"tracking_link\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899223197428490\",\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"supplier_id\": null,\n      \"is_dropship\": false\n    },\n    \"warehouse_id\": 3,\n    \"fulfilled_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Operator\"\n    },\n    \"fulfilled_quantity\": 3,\n    \"fulfillment_lines\": [\n      {\n        \"id\": 9932,\n        \"sales_order_line_id\": 55340,\n        \"sales_order_fulfillment_id\": 4821,\n        \"quantity\": 3,\n        \"unit_cost\": 4.25,\n        \"metadata\": null,\n        \"item_inventory\": {\n          \"total\": {\n            \"inbound\": 120,\n            \"stock\": 458,\n            \"allocated\": 36,\n            \"on_hold\": 0,\n            \"available\": 422,\n            \"in_transit\": 0\n          },\n          \"warehouses\": {\n            \"Main Warehouse\": {\n              \"inbound\": 120,\n              \"stock\": 458,\n              \"allocated\": 36,\n              \"on_hold\": 0,\n              \"available\": 422,\n              \"supplier_in_stock\": null,\n              \"in_transit\": 0,\n              \"warehouse_id\": 3,\n              \"warehouse_name\": \"Main Warehouse\",\n              \"warehouse_type\": \"standard\",\n              \"supplier\": null,\n              \"country_code\": \"US\"\n            }\n          }\n        },\n        \"sales_order_line\": {\n          \"id\": 55340,\n          \"product_id\": 2210,\n          \"quantity\": 3,\n          \"amount\": 19.99,\n          \"description\": \"Stainless Steel Water Bottle 750ml\",\n          \"warehouse_id\": 3,\n          \"product\": {\n            \"id\": 2210,\n            \"sku\": \"WB-750-SS\",\n            \"name\": \"Stainless Steel Water Bottle 750ml\",\n            \"weight\": 0.42,\n            \"weight_unit\": \"kg\",\n            \"height\": 27,\n            \"width\": 7.5,\n            \"length\": 7.5,\n            \"dimension_unit\": \"cm\",\n            \"is_lot_tracked\": false,\n            \"lot_tracking_method\": null,\n            \"shelf_life_days\": null,\n            \"near_expiry_threshold_days\": null,\n            \"min_remaining_shelf_life_days\": null\n          }\n        }\n      }\n    ],\n    \"cost\": 8.45,\n    \"status\": \"fulfilled\",\n    \"voided_at\": null,\n    \"void_reason\": null,\n    \"voided_by\": null,\n    \"fulfilled_at\": \"2026-06-28T14:03:22.000000Z\",\n    \"marked_for_pickup_at\": null,\n    \"marked_for_pickup_by\": null,\n    \"expected_pickup_at\": null,\n    \"packing_slip_printed_at\": \"2026-06-27T18:20:11.000000Z\",\n    \"submitted_to_sales_channel_at\": \"2026-06-28T14:05:01.000000Z\",\n    \"last_synced_to_provider_at\": \"2026-06-28T14:03:25.000000Z\",\n    \"last_synced_from_provider_at\": \"2026-06-28T16:00:02.000000Z\",\n    \"metadata\": {\n      \"shipping_speed\": \"standard\"\n    },\n    \"fulfillment_sequence\": 1,\n    \"is_parent\": false,\n    \"parent_id\": null,\n    \"created_at\": \"2026-06-27T16:40:09.000000Z\",\n    \"provider_order_id\": null,\n    \"sales_channel_fulfillment_link\": null,\n    \"sales_order\": {\n      \"id\": 10412,\n      \"sales_order_number\": \"SO-10412\",\n      \"order_date\": \"2026-06-27\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"customer_reference\": \"AMZ-114-2298711\",\n      \"requested_shipping_method\": \"Standard Shipping\",\n      \"billing_address\": {\n        \"id\": 8811,\n        \"first_name\": \"Dana\",\n        \"last_name\": \"Whitfield\",\n        \"address1\": \"88 Elm St\",\n        \"address2\": null,\n        \"city\": \"Austin\",\n        \"province_code\": \"TX\",\n        \"zip\": \"78701\",\n        \"country_code\": \"US\",\n        \"phone\": \"+1 512 555 0138\"\n      },\n      \"shipping_address\": {\n        \"id\": 8812,\n        \"first_name\": \"Dana\",\n        \"last_name\": \"Whitfield\",\n        \"address1\": \"88 Elm St\",\n        \"address2\": null,\n        \"city\": \"Austin\",\n        \"province_code\": \"TX\",\n        \"zip\": \"78701\",\n        \"country_code\": \"US\",\n        \"phone\": \"+1 512 555 0138\"\n      }\n    }\n  }\n}"}]},{"name":"Fulfill or Update Shipment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"7781","description":"Sales order fulfillment (shipment) id"}]},"description":"Create or update a shipment (fulfillment) for a sales order. Uses FulfillSalesOrderRequest. Authenticate with a Personal Access Token, passed in the `Authorization` header as a bearer token.\n\nPUT updates the bound fulfillment; the same body shape is used when creating via POST /api/sales-orders/{salesOrder}/fulfillments.\n\nBody fields:\n- fulfillment_type (required): one of the SalesOrderFulfillment::TYPES (e.g. manual, fba, pickup).\n- warehouse_id (nullable on PUT; required on POST when the order spans multiple warehouses — auto-selected when single).\n- requested_shipping_method_id / requested_shipping_method (nullable).\n- fulfilled_shipping_method_id / manual_fulfilled_shipping_method (nullable — for manual fulfillment).\n- fulfilled_at (required when fulfillment_type=manual; date).\n- cost (nullable, numeric < 100000).\n- tracking_number (nullable, max 255).\n- fulfillment_sequence (nullable, integer, unique per sales order).\n- fulfillment_lines (array, min 1): each line has\n - sales_order_line_id (required, exists)\n - quantity (required, numeric, 0..<100000)\n - id (PUT only — required_without sales_order_line_id; the SOFL id)\n - metadata.fba_seller_sku (optional string)\n - lot_allocation (optional, array): user-chosen lot allocation (FEFO override) for a lot-tracked product. Each entry { fifo_layer_id (exists), quantity (>0) }. The entries MUST sum to the line's quantity, reference active FIFO layers of the line's product + warehouse with enough available quantity, and respect the tenant lot override policy (under 'enforce', consuming expired stock or a later-expiry lot for FEFO products is rejected). Omit it to consume by automatic FEFO/FIFO.\n- metadata.* (optional shipment-level flags: signature_required, saturday_delivery, shipping_speed, comments, veracore_*).\n- submit_to_shipping_provider / submit_to_sales_channel (optional bool).\n\nPer-line 422 lot validation errors are keyed fulfillment_lines.{index}.lot_allocation and fulfillment_lines.{index}.lot_allocation.{i}.{field}.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fulfillment_type\": \"manual\",\n  \"warehouse_id\": 7,\n  \"requested_shipping_method_id\": 12,\n  \"fulfilled_shipping_method_id\": 12,\n  \"manual_fulfilled_shipping_method\": \"UPS Ground\",\n  \"fulfilled_at\": \"2026-06-20 14:30:00\",\n  \"cost\": 8.5,\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"fulfillment_sequence\": 1,\n  \"fulfillment_lines\": [\n    {\n      \"sales_order_line_id\": 55347,\n      \"quantity\": 3,\n      \"metadata\": {\n        \"fba_seller_sku\": \"WIDGET-LOT-001\"\n      },\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 90211,\n          \"quantity\": 2\n        },\n        {\n          \"fifo_layer_id\": 90217,\n          \"quantity\": 1\n        }\n      ]\n    },\n    {\n      \"sales_order_line_id\": 55348,\n      \"quantity\": 1\n    }\n  ],\n  \"metadata\": {\n    \"signature_required\": true,\n    \"saturday_delivery\": false,\n    \"shipping_speed\": \"standard\",\n    \"comments\": \"Leave at front door\"\n  },\n  \"submit_to_shipping_provider\": true,\n  \"submit_to_sales_channel\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"7781","description":"Sales order fulfillment (shipment) id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7781,\n    \"fulfillment_number\": \"SO-1042.1\",\n    \"sales_order_id\": 1042,\n    \"fulfillment_order_id\": 451,\n    \"fulfillment_type\": \"manual\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"shipping_method_id\": 12,\n    \"requested_shipping_method\": null,\n    \"requested_shipping_method_id\": 12,\n    \"fulfilled_shipping_method\": \"UPS Ground\",\n    \"fulfilled_shipping_method_id\": 12,\n    \"fulfilled_date\": \"2026-06-20T14:30:00+00:00\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": null,\n    \"tracking_link\": null,\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"supplier_id\": null,\n      \"is_dropship\": false\n    },\n    \"warehouse_id\": 7,\n    \"fulfilled_by\": {\n      \"id\": 3,\n      \"name\": \"Warehouse Operator\"\n    },\n    \"fulfilled_quantity\": 4,\n    \"fulfillment_lines\": [\n      {\n        \"id\": 99001,\n        \"sales_order_line_id\": 55347,\n        \"sales_order_fulfillment_id\": 7781,\n        \"quantity\": 3,\n        \"unit_cost\": 5,\n        \"metadata\": {\n          \"lot_allocation\": [\n            {\n              \"fifo_layer_id\": 90211,\n              \"quantity\": 2\n            },\n            {\n              \"fifo_layer_id\": 90217,\n              \"quantity\": 1\n            }\n          ]\n        },\n        \"item_inventory\": {},\n        \"sales_order_line\": {\n          \"id\": 55347,\n          \"product_id\": 8842,\n          \"quantity\": 3,\n          \"amount\": 19.99,\n          \"description\": \"Lot-Tracked Widget\",\n          \"warehouse_id\": 7,\n          \"product\": {\n            \"id\": 8842,\n            \"sku\": \"WIDGET-LOT-001\",\n            \"name\": \"Lot-Tracked Widget\",\n            \"weight\": 0.5,\n            \"weight_unit\": \"kg\",\n            \"height\": null,\n            \"width\": null,\n            \"length\": null,\n            \"dimension_unit\": null,\n            \"is_lot_tracked\": true,\n            \"lot_tracking_method\": \"fefo\",\n            \"shelf_life_days\": 365,\n            \"near_expiry_threshold_days\": 30,\n            \"min_remaining_shelf_life_days\": 60\n          }\n        }\n      },\n      {\n        \"id\": 99002,\n        \"sales_order_line_id\": 55348,\n        \"sales_order_fulfillment_id\": 7781,\n        \"quantity\": 1,\n        \"unit_cost\": 3,\n        \"metadata\": null,\n        \"item_inventory\": {},\n        \"sales_order_line\": {\n          \"id\": 55348,\n          \"product_id\": 8843,\n          \"quantity\": 1,\n          \"amount\": 9.99,\n          \"description\": \"Standard Gadget\",\n          \"warehouse_id\": 7,\n          \"product\": {\n            \"id\": 8843,\n            \"sku\": \"GADGET-200\",\n            \"name\": \"Standard Gadget\",\n            \"weight\": 0.2,\n            \"weight_unit\": \"kg\",\n            \"height\": null,\n            \"width\": null,\n            \"length\": null,\n            \"dimension_unit\": null,\n            \"is_lot_tracked\": false,\n            \"lot_tracking_method\": null,\n            \"shelf_life_days\": null,\n            \"near_expiry_threshold_days\": null,\n            \"min_remaining_shelf_life_days\": null\n          }\n        }\n      }\n    ],\n    \"cost\": 8.5,\n    \"status\": \"fulfilled\",\n    \"voided_at\": null,\n    \"void_reason\": null,\n    \"voided_by\": null,\n    \"fulfilled_at\": \"2026-06-20T14:30:00+00:00\",\n    \"fulfillment_sequence\": 1,\n    \"is_parent\": false,\n    \"parent_id\": null,\n    \"created_at\": \"2026-06-20T14:30:00+00:00\",\n    \"provider_order_id\": null,\n    \"metadata\": {\n      \"signature_required\": true\n    }\n  }\n}"}]},{"name":"Void Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment (shipment) ID"}]},"description":"Voids a shipment (SalesOrderFulfillment) — a SOFT, reversible cancel that does NOT hard-delete the record ('A1'). Voiding: reverses the shipment's inventory movements, reverts Fulfilled→Allocated allocations, restores the parent FulfillmentOrder budget and reopens the SAME FO to Open/Unsubmitted so it can be re-fulfilled, cancels the carrier order, and flips the SOF to status=canceled with voided_at/voided_by_user_id/void_reason set. The SOF + its lines are RETAINED for history; voided shipments are excluded from the active fulfillment tab (voided_at IS NULL filter).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nNot voidable (returns 400): an already-shipped shipment (status fulfilled / fulfilled_awaiting_info — use a return/RMA), an already-voided shipment, or a multi-channel (MCF / merge-group) submission (void individual standalone shipments only).\n\nRequest body (optional):\n- void_reason (string, optional): reason recorded on the void + FO activity entry. Falls back to `reason` if absent.\n\nQuery params:\n- check-deletable (0|1, default 1): when 1, runs the carrier-side 'already shipped at provider' guard before voiding.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillment}","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillment"],"variable":[{"key":"salesOrderFulfillment","value":"1001","description":"Sales order fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The sales order fulfillment SO-0123.2 voided successfully\",\n  \"data\": []\n}"}]},{"name":"Bulk Void Shipments","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments"]},"description":"Bulk-voids shipments. The DELETE verb is retained for backwards compatibility, but it now performs a soft VOID (not a hard delete): each shipment's inventory is reversed, its parent FulfillmentOrder is reopened, the carrier order is cancelled, and the SOF row is kept for history (status=canceled + void audit columns).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequest body:\n• ids (`array<int>`, required without apply_to_all): fulfillment IDs to void.\n• apply_to_all (bool, optional): when true, voids every shipment matching `filters` instead of `ids`.\n• filters (object, optional): the V2 list filter set used to resolve IDs when apply_to_all=true.\n• force (bool, optional, default false): when false, shipments already shipped at the provider are NOT voided — they land in the `needs_confirmation` bucket. Re-submit those with force=true to void the local copy anyway (inventory reversed, carrier order left as-is).\n• void_reason (string, optional, max 1000): reason recorded on each void + FO activity entry.\n\nSelection size routing:\n• ≤ 30 shipments: voided synchronously; the response `data` carries per-shipment result buckets.\n• > 30 shipments: dispatched to a background tracked job; the response `data` carries `tracked_job_log_id` for the tracked job log endpoints.\n\nResult buckets (synchronous):\n• voided[]: { id, fulfillment_number } — successfully voided.\n• needs_confirmation[]: { id, fulfillment_number, reason } — shipped at the provider; re-submit with force=true.\n• skipped[]: { id, fulfillment_number, reason } — already voided or otherwise not voidable.\n• errors[]: { id, fulfillment_number, error } — unexpected failures.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Voided 2 shipment(s). 1 shipped shipment(s) need confirmation to void the local copy.\",\n  \"data\": {\n    \"voided\": [\n      {\n        \"id\": 1001,\n        \"fulfillment_number\": \"SO-0123.1\"\n      },\n      {\n        \"id\": 1002,\n        \"fulfillment_number\": \"SO-0123.2\"\n      }\n    ],\n    \"needs_confirmation\": [\n      {\n        \"id\": 1003,\n        \"fulfillment_number\": \"SO-0124.1\",\n        \"reason\": \"shipped\"\n      }\n    ],\n    \"skipped\": [],\n    \"errors\": []\n  }\n}"}]},{"name":"Get Shipment Packing Slip Cache Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-order-fulfillments/{salesOrderFulfillment}/packing-slip/cache-status","host":["{{baseUrl}}"],"path":["api","export","sales-order-fulfillments",":salesOrderFulfillment","packing-slip","cache-status"],"variable":[{"key":"salesOrderFulfillment","value":"123","description":"Sales order fulfillment (shipment) ID"}]},"description":"Reports whether a rendered packing-slip PDF is currently cached for this shipment (SalesOrderFulfillment), and when it was generated. The packing-slip export serves the stored `{id}.pdf` as-is whenever it exists, so a cached slip can lag the FO's current lines or sequence. The UI uses this to show a \"cached\" indicator and offer a one-click clear.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/sales-order-fulfillments/{salesOrderFulfillment}/packing-slip/cache-status","host":["{{baseUrl}}"],"path":["api","export","sales-order-fulfillments",":salesOrderFulfillment","packing-slip","cache-status"],"variable":[{"key":"salesOrderFulfillment","value":"123","description":"Sales order fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"cached\": true,\n    \"generated_at\": \"2026-06-23T22:24:20+00:00\"\n  }\n}"}]},{"name":"Clear Shipment Packing Slip Cache","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/export/sales-order-fulfillments/{salesOrderFulfillment}/packing-slip/cache","host":["{{baseUrl}}"],"path":["api","export","sales-order-fulfillments",":salesOrderFulfillment","packing-slip","cache"],"variable":[{"key":"salesOrderFulfillment","value":"123","description":"Sales order fulfillment (shipment) ID"}]},"description":"Clears (deletes) the cached packing-slip PDF for this shipment (SalesOrderFulfillment) so the next print regenerates from current data. Idempotent — clearing a slip that was never cached is a no-op.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/export/sales-order-fulfillments/{salesOrderFulfillment}/packing-slip/cache","host":["{{baseUrl}}"],"path":["api","export","sales-order-fulfillments",":salesOrderFulfillment","packing-slip","cache"],"variable":[{"key":"salesOrderFulfillment","value":"123","description":"Sales order fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cached packing slip cleared — the next print will regenerate from current data.\"\n}"}]},{"name":"Get Provider Fulfillment Snapshots","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]},"description":"Read-only provider order/shipment visibility & reconciliation for the Sales Order Fulfillments tab.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns each connected shipping provider's cached order/shipment (Starshipit + ShipStation pilots), matched to this sales order by the `{sales_order_number}.{fulfillment_sequence}` reference, and classified into a reconciliation state:\n- `matched` — attached to an FO/SOF on this order and items agree\n- `item_mismatch` — attached, but provider items differ from our lines\n- `orphan_linkable` — unattached, but a matching FO/SOF exists (repair target)\n- `orphan_importable` — unattached and no matching FO/SOF (import candidate)\n- `orphan_duplicate` — unattached, but its products are already fulfilled by an FO that has an active provider order (a duplicate at the carrier; resolve by voiding it there and recording a voided FO)\n\n`snapshots[]` are attached to an FO/SOF (see `attached_to`); `orphans[]` are unattached provider records; `summary` carries per-state counts.\n\nAuthentication: requires a Bearer token (Personal Access Token).\nRead-only — no query parameters. Cache-only (no live provider call); `last_synced_at` reflects staleness.\nGated by the `fulfillment.provider_snapshots_enabled` flag — returns 404 when disabled so the UI degrades gracefully.\n\nEach orphan carries a `suggested_action`: `link`, `import_fo`, `import_fo_and_sof`, `void_and_import` (live duplicate), or `import_voided_fo` (already-cancelled duplicate). `summary` includes per-state counts, including `orphan_duplicate`.\n\nEach snapshot/orphan entry includes `marked_shipped_without_label` (boolean): true when the provider order reports shipped but no label was ever purchased and no tracking exists anywhere (the ShipStation \"Mark as Shipped\" fingerprint). Such orphans get `suggested_action: import_voided_fo` — importing records a terminal voided mirror fulfillment order instead of a live FO/SOF.\n\n`marked_shipped_without_label` also covers hand-typed trackings: a \"Mark as Shipped\" order (ShipStation payload externallyFulfilled=true) with a typed tracking is flagged only when that tracking matches a shipment already recorded on the order. Shipped orphans sharing a tracking with a recorded shipment classify as orphan_linkable (free shipment) or orphan_duplicate with import_voided_fo (shipment already provider-backed).\n\nEach attached snapshot may carry a `discrepancy` object when a shipping provider shipped a fulfillment order whose line SKU cannot fulfill from on-hand stock: `{ fulfillment_order_id, can_accept, accepted, discrepant_lines[], fulfillable_lines[] }`. When `can_accept` is true, POST the fulfillment order's accept-discrepancy endpoint to ship the fulfillable lines and park the rest. Null when there is no discrepancy to surface."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"snapshots\": [\n      {\n        \"provider\": \"starshipit\",\n        \"provider_label\": \"Starshipit\",\n        \"integration_instance_id\": 12,\n        \"integration_instance_name\": \"AU Warehouse\",\n        \"external_order_id\": \"987654\",\n        \"order_reference\": \"C604018.1\",\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"deep_link_url\": \"/integrations/starshipit/12/orders/987654\",\n        \"external_url\": \"https://app2.starshipit.com/orders/new/987654\",\n        \"last_synced_at\": \"2026-06-24T03:11:00+00:00\",\n        \"shipped\": true,\n        \"marked_shipped_without_label\": false,\n        \"attached_to\": {\n          \"type\": \"fulfillment_order\",\n          \"id\": 4471\n        },\n        \"link_state\": \"matched\",\n        \"link_state_label\": \"Matched\",\n        \"link_state_color\": \"success\",\n        \"suggested_action\": null,\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"name\": \"Red Widget\",\n            \"quantity\": 2,\n            \"product_id\": 55\n          }\n        ],\n        \"shipments\": [\n          {\n            \"external_shipment_id\": \"PKG-1\",\n            \"tracking_number\": \"ABX123\",\n            \"tracking_url\": \"https://track.aus/ABX123\",\n            \"carrier\": \"Australia Post\",\n            \"service\": \"Express\",\n            \"shipped_at\": \"2026-06-24T02:55:00+00:00\",\n            \"delivery_status\": \"In Transit\",\n            \"voided\": false\n          }\n        ],\n        \"item_match\": {\n          \"matches\": true,\n          \"lines\": [\n            {\n              \"sku\": \"WIDGET-RED\",\n              \"name\": \"Red Widget\",\n              \"our_qty\": 2,\n              \"provider_qty\": 2,\n              \"state\": \"ok\"\n            }\n          ]\n        },\n        \"discrepancy\": {\n          \"fulfillment_order_id\": 4471,\n          \"can_accept\": true,\n          \"accepted\": false,\n          \"discrepant_lines\": [\n            {\n              \"sku\": \"195093200861\",\n              \"name\": \"Mis-tagged item\",\n              \"quantity\": 1\n            }\n          ],\n          \"fulfillable_lines\": [\n            {\n              \"sku\": \"ABC-1\",\n              \"name\": \"In-stock item\",\n              \"quantity\": 1\n            }\n          ]\n        }\n      },\n      {\n        \"provider\": \"shipstation\",\n        \"provider_label\": \"ShipStation\",\n        \"integration_instance_id\": 7,\n        \"integration_instance_name\": \"US Warehouse\",\n        \"external_order_id\": 3320,\n        \"order_reference\": \"C604018.2\",\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"deep_link_url\": \"/integrations/shipstation/7/orders/3310\",\n        \"external_url\": \"https://ship.shipstation.com/orders/all-orders-search-result?quickSearch=C604018.2\",\n        \"last_synced_at\": \"2026-06-24T02:40:00+00:00\",\n        \"shipped\": true,\n        \"marked_shipped_without_label\": false,\n        \"attached_to\": {\n          \"type\": \"sales_order_fulfillment\",\n          \"id\": 9912\n        },\n        \"link_state\": \"item_mismatch\",\n        \"link_state_label\": \"Items differ\",\n        \"link_state_color\": \"error\",\n        \"suggested_action\": null,\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"name\": \"Red Widget\",\n            \"quantity\": 2,\n            \"product_id\": 55\n          },\n          {\n            \"sku\": \"GIZMO-9\",\n            \"name\": \"Gizmo 9\",\n            \"quantity\": 1,\n            \"product_id\": 61\n          }\n        ],\n        \"shipments\": [\n          {\n            \"external_shipment_id\": 88810,\n            \"tracking_number\": \"1Z111\",\n            \"tracking_url\": \"https://ups.com/track?1Z111\",\n            \"carrier\": \"ups\",\n            \"service\": \"ups_ground\",\n            \"shipped_at\": \"2026-06-24T02:30:00+00:00\",\n            \"delivery_status\": null,\n            \"voided\": false\n          }\n        ],\n        \"item_match\": {\n          \"matches\": false,\n          \"lines\": [\n            {\n              \"sku\": \"WIDGET-RED\",\n              \"name\": \"Red Widget\",\n              \"our_qty\": 2,\n              \"provider_qty\": 2,\n              \"state\": \"ok\"\n            },\n            {\n              \"sku\": \"GIZMO-9\",\n              \"name\": \"Gizmo 9\",\n              \"our_qty\": 3,\n              \"provider_qty\": 1,\n              \"state\": \"qty_diff\"\n            }\n          ]\n        },\n        \"discrepancy\": null\n      }\n    ],\n    \"orphans\": [\n      {\n        \"provider\": \"shipstation\",\n        \"provider_label\": \"ShipStation\",\n        \"integration_instance_id\": 7,\n        \"integration_instance_name\": \"US Warehouse\",\n        \"external_order_id\": 3321,\n        \"order_reference\": \"C604018.3\",\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"deep_link_url\": \"/integrations/shipstation/7/orders/3321\",\n        \"external_url\": \"https://ship.shipstation.com/orders/all-orders-search-result?quickSearch=C604018.3\",\n        \"last_synced_at\": \"2026-06-24T01:00:00+00:00\",\n        \"shipped\": true,\n        \"marked_shipped_without_label\": false,\n        \"attached_to\": null,\n        \"link_state\": \"orphan_importable\",\n        \"link_state_label\": \"Importable\",\n        \"link_state_color\": \"purple\",\n        \"suggested_action\": \"import_fo_and_sof\",\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"name\": \"Red Widget\",\n            \"quantity\": 1,\n            \"product_id\": 55\n          }\n        ],\n        \"shipments\": [\n          {\n            \"external_shipment_id\": 88812,\n            \"tracking_number\": \"1Z999\",\n            \"tracking_url\": \"https://ups.com/track?1Z999\",\n            \"carrier\": \"ups\",\n            \"service\": \"ups_ground\",\n            \"shipped_at\": \"2026-06-23T20:00:00+00:00\",\n            \"delivery_status\": null,\n            \"voided\": false\n          }\n        ],\n        \"item_match\": {\n          \"matches\": null,\n          \"lines\": []\n        },\n        \"discrepancy\": null\n      }\n    ],\n    \"summary\": {\n      \"matched\": 1,\n      \"item_mismatch\": 1,\n      \"orphan_linkable\": 0,\n      \"orphan_importable\": 1\n    }\n  }\n}"}]},{"name":"Repair Provider Fulfillment Orphan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots/repair","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots","repair"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]},"description":"Link an orphan shipping-provider order (link_state `orphan_linkable`, suggested_action `link`) to an existing FulfillmentOrder / SalesOrderFulfillment already on this sales order whose lines cover the same products (Phase 2). Only links to an FO/SOF that does NOT already have an active (non-cancelled) provider order — two active provider orders on one FO is invalid. An orphan whose only match is already taken is classified `orphan_duplicate` (use Import) instead of `orphan_linkable`, and a repair attempt against it is rejected with 422. Use the `provider`, `integration_instance_id`, and `external_order_id` from the orphan returned by GET provider-fulfillment-snapshots.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the refreshed reconciliation bundle (`snapshots`, `orphans`, `summary`) plus a `message` describing the link. The previously-orphaned record now appears under `snapshots[]` attached to its FO/SOF.\n\nRequest body:\n- `provider` (string, required) — the carrier that owns the order (e.g. `starshipit`).\n- `integration_instance_id` (integer, optional) — the provider integration instance the order belongs to.\n- `external_order_id` (string, required) — the carrier-side order id.\n\nAuthentication: Bearer token. Requires the `sales_orders.fulfill` permission.\nGated by the `fulfillment.provider_snapshots_enabled` flag — 404 when disabled.\nReturns 422 when no matching FO/SOF exists to link to, the order is already linked, the order belongs to a different sales order, or the orphan can no longer be found.\n\nA tracking-based fallback supplements the SKU-set shipment matcher: when the orphan's label/tracking matches a recorded fulfilled shipment that has no active provider order, the orphan links to that shipment even if their item sets differ (e.g. post-repair consolidated shipments).","body":{"mode":"raw","raw":"{\n  \"provider\": \"starshipit\",\n  \"integration_instance_id\": 12,\n  \"external_order_id\": \"987654\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots/repair","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots","repair"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"snapshots\": [\n      {\n        \"provider\": \"starshipit\",\n        \"provider_label\": \"Starshipit\",\n        \"integration_instance_id\": 12,\n        \"integration_instance_name\": \"AU Warehouse\",\n        \"external_order_id\": \"987654\",\n        \"order_reference\": \"C604018.1\",\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"deep_link_url\": \"/integrations/starshipit/12/orders/987654\",\n        \"external_url\": \"https://app2.starshipit.com/orders/new/987654\",\n        \"last_synced_at\": \"2026-06-24T03:11:00+00:00\",\n        \"shipped\": true,\n        \"attached_to\": {\n          \"type\": \"sales_order_fulfillment\",\n          \"id\": 9920\n        },\n        \"link_state\": \"matched\",\n        \"link_state_label\": \"Matched\",\n        \"link_state_color\": \"success\",\n        \"suggested_action\": null,\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"name\": \"Red Widget\",\n            \"quantity\": 1,\n            \"product_id\": 55\n          }\n        ],\n        \"shipments\": [\n          {\n            \"external_shipment_id\": \"PKG-9\",\n            \"tracking_number\": \"ABX900\",\n            \"tracking_url\": \"https://track.aus/ABX900\",\n            \"carrier\": \"Australia Post\",\n            \"service\": \"Express\",\n            \"shipped_at\": \"2026-06-24T02:55:00+00:00\",\n            \"delivery_status\": \"In Transit\",\n            \"voided\": false\n          }\n        ],\n        \"item_match\": {\n          \"matches\": true,\n          \"lines\": [\n            {\n              \"sku\": \"WIDGET-RED\",\n              \"name\": \"Red Widget\",\n              \"our_qty\": 1,\n              \"provider_qty\": 1,\n              \"state\": \"ok\"\n            }\n          ]\n        }\n      }\n    ],\n    \"orphans\": [],\n    \"summary\": {\n      \"matched\": 1,\n      \"item_mismatch\": 0,\n      \"orphan_linkable\": 0,\n      \"orphan_importable\": 0\n    }\n  },\n  \"message\": \"Linked Starshipit order C604018.1 to fulfillment #9920.\"\n}"}]},{"name":"Import Provider Fulfillment Orphan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots/import","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots","import"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]},"description":"Create the SKU fulfillment entities for an orphan shipping-provider order with no counterpart (link_state `orphan_importable`) (Phase 3). When the provider order is not yet shipped (suggested_action `import_fo`) a FulfillmentOrder is created; when it is already shipped (suggested_action `import_fo_and_sof`) a FulfillmentOrder plus a SalesOrderFulfillment ship event with tracking is created. Provider item SKUs are matched against the sales order's unfulfilled lines.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nImport also resolves an `orphan_duplicate` (its products already fulfilled by an FO that has an active provider order). If the duplicate is still live at the carrier (suggested_action `void_and_import`) it is first voided there; then — or if it was already cancelled (suggested_action `import_voided_fo`) — it is recorded as a terminal voided \"mirror\" FulfillmentOrder linked to it, reserving no stock, so SKU mirrors the carrier 1:1.\n\nReturns the refreshed reconciliation bundle (`snapshots`, `orphans`, `summary`) plus a `message`; the imported record now appears under `snapshots[]` attached to the new FO/SOF.\n\nRequest body:\n- `provider` (string, required) — the carrier that owns the order (e.g. `starshipit`).\n- `integration_instance_id` (integer, optional) — the provider integration instance the order belongs to.\n- `external_order_id` (string, required) — the carrier-side order id.\n\nAuthentication: Bearer token. Requires the `sales_orders.fulfill` permission.\nGated by the `fulfillment.provider_snapshots_enabled` flag — 404 when disabled.\nReturns 422 when the provider items cannot be matched to unfulfilled sales order lines, the order is already linked, the order belongs to a different sales order, or the orphan can no longer be found.\n\nOrphans flagged `marked_shipped_without_label` (shipped at the provider with no label purchased and no tracking) are imported as a terminal voided mirror fulfillment order (`external_type: provider_reconciliation_void_mirror`) with no carrier call, no shipment, and no inventory impact — message: \"Recorded the {Provider} order (marked shipped, no label purchased) as voided fulfillment order #N on {order}.\"\n\nTracking-match handling: a shipped orphan sharing a tracking number with a shipment already recorded on the order is never live-imported. If that shipment has no active provider order, the orphan is linked to it (response message: \"Linked ... (same tracking)\"); if the shipment is already provider-backed, the orphan is recorded as a voided mirror FO. A hand-typed \"Mark as Shipped\" tracking (payload externallyFulfilled=true) only counts as covered when it matches a recorded shipment — a unique typed tracking stays a live import.","body":{"mode":"raw","raw":"{\n  \"provider\": \"starshipit\",\n  \"integration_instance_id\": 12,\n  \"external_order_id\": \"987654\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/provider-fulfillment-snapshots/import","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","provider-fulfillment-snapshots","import"],"variable":[{"key":"salesOrder","value":"1","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"snapshots\": [\n      {\n        \"provider\": \"starshipit\",\n        \"provider_label\": \"Starshipit\",\n        \"integration_instance_id\": 12,\n        \"integration_instance_name\": \"AU Warehouse\",\n        \"external_order_id\": \"987654\",\n        \"order_reference\": \"C604018.1\",\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"deep_link_url\": \"/integrations/starshipit/12/orders/987654\",\n        \"external_url\": \"https://app2.starshipit.com/orders/new/987654\",\n        \"last_synced_at\": \"2026-06-24T03:11:00+00:00\",\n        \"shipped\": true,\n        \"attached_to\": {\n          \"type\": \"sales_order_fulfillment\",\n          \"id\": 9920\n        },\n        \"link_state\": \"matched\",\n        \"link_state_label\": \"Matched\",\n        \"link_state_color\": \"success\",\n        \"suggested_action\": null,\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"name\": \"Red Widget\",\n            \"quantity\": 1,\n            \"product_id\": 55\n          }\n        ],\n        \"shipments\": [\n          {\n            \"external_shipment_id\": \"PKG-9\",\n            \"tracking_number\": \"ABX900\",\n            \"tracking_url\": \"https://track.aus/ABX900\",\n            \"carrier\": \"Australia Post\",\n            \"service\": \"Express\",\n            \"shipped_at\": \"2026-06-24T02:55:00+00:00\",\n            \"delivery_status\": \"In Transit\",\n            \"voided\": false\n          }\n        ],\n        \"item_match\": {\n          \"matches\": true,\n          \"lines\": [\n            {\n              \"sku\": \"WIDGET-RED\",\n              \"name\": \"Red Widget\",\n              \"our_qty\": 1,\n              \"provider_qty\": 1,\n              \"state\": \"ok\"\n            }\n          ]\n        }\n      }\n    ],\n    \"orphans\": [],\n    \"summary\": {\n      \"matched\": 1,\n      \"item_mismatch\": 0,\n      \"orphan_linkable\": 0,\n      \"orphan_importable\": 0\n    }\n  },\n  \"message\": \"Imported Starshipit order C604018.1 as fulfillment #9920.\"\n}"}]},{"name":"Check Fulfillments Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/deletable","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","deletable"]},"description":"Check whether fulfillments can be voided (deleted). A fulfillment is not deletable when its linked shipping-provider order is already marked as shipped at the provider.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody:\n- `ids` (array of integers, required, min 1) — fulfillment IDs to check. Unknown IDs fail validation with 422.\n\nReturns one entry per fulfillment with `deletable` and, when not deletable, a human-readable `reason`. Use before calling the void (DELETE) endpoint.\n\nRead-only — no external calls and no changes. Requires the `orders:write` token scope.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4821,\n    4977\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/deletable","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"fulfillment_number\": \"SO-10412.1\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 4977,\n      \"fulfillment_number\": \"SO-10501.2\",\n      \"deletable\": false,\n      \"reason\": \"The shipstation order marked as shipped, you can not delete shipped fulfillment order\"\n    }\n  ]\n}"}]},{"name":"Restore Voided Shipment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/restore","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","restore"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]},"description":"Restore (un-void) a previously voided shipment. No request body.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe shipment returns to its pre-void status (typically `submitted`), and the void audit fields (`voided_at`, `voided_by`, `void_reason`) are cleared.\n\nSide effects:\n- Restoring back to a shipped status re-creates the inventory movements and cost-layer consumption that the void reversed, and re-marks allocations as fulfilled.\n- If the shipment's sales-channel fulfillment (e.g. Shopify) was cancelled during the void, the channel submission is reset so a fresh fulfillment is pushed to the channel on the next sync.\n- Product inventory and average-cost figures are recalculated in the background.\n\nErrors (422):\n- the shipment is not voided (nothing to restore)\n- the shipment is part of a multi-shipment merge group and cannot be restored individually\n- insufficient allocation to restore a shipped fulfillment (the error names the SKU and quantities)\n\nRequires the `orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/restore","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","restore"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"The sales order fulfillment SO-10412.1 restored successfully\"\n}"}]},{"name":"Bulk Archive Fulfillments","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/archive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","archive"]},"description":"Archive multiple fulfillments at once. Archived fulfillments are hidden from default list results but remain retrievable.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody — either:\n- `ids` (array of integers) — explicit fulfillment IDs; or\n- `apply_to_all: true` with an optional `filters` object — archives every fulfillment matching the filters. The `filters` object accepts the same keys as the fulfillment list filters, e.g. `{\"fulfillment_type\": \"manual\", \"voided\": \"exclude\", \"packing_slip_printed\": \"no\", \"integration_instance_ids\": \"1,2\", \"search\": \"SO-10412\"}`.\n\nThe response is always HTTP 200; check the JSON `status` field. Already-archived records are reported per ID under `warnings` and the overall `status` becomes `warning`.\n\nRequires the `orders:write` token scope.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4821,\n    4977,\n    5010\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/archive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"3/3 sales order fulfillments had been archived successfully\"\n}"}]},{"name":"Bulk Unarchive Fulfillments","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/unarchive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","unarchive"]},"description":"Unarchive multiple fulfillments at once, restoring them to default list results.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody — either `ids` (array of integers) or `apply_to_all: true` with an optional `filters` object (same filter keys as Bulk Archive Fulfillments; include `\"archived\": \"only\"` to target archived records).\n\nThe response is always HTTP 200; check the JSON `status` field. Records that are not archived are reported per ID under `warnings` and the overall `status` becomes `warning`.\n\nRequires the `orders:write` token scope.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4821,\n    4977\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/unarchive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"2/2 sales order fulfillments had been un archived successfully\"\n}"}]},{"name":"Bulk Request Fulfillment Tracking Updates","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/tracking-updates","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","tracking-updates"]},"description":"Request fresh tracking information from shipping providers for the selected fulfillments.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody:\n- `ids` (optional) — array of fulfillment IDs or a comma-separated string (`\"4821,4977\"`). Unknown IDs are ignored.\n\nOnly fulfillments of type `starshipit`, `shipstation`, or `fba` that are not yet in `fulfilled` status are processed; all others are skipped silently.\n\n**May run asynchronously** — when more than 10 fulfillments match for a provider, the sync is queued as a background job and the response says so; smaller selections are polled inline against the provider before responding.\n\nSide effects: tracking numbers and URLs are written back, and a shipment found shipped/delivered at the provider transitions to `fulfilled` — which records inventory movements, consumes cost layers, and submits the fulfillment to the sales channel.\n\nErrors: 400 when the required shipping-provider integration is not connected, or when the provider API returns an error.\n\nRequires the `orders:write` token scope.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4821,\n    4977\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/tracking-updates","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments","tracking-updates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"The tracking data of the selected fulfillments has been updated\"\n}"}]},{"name":"Archive Fulfillment","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/archive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","archive"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]},"description":"Archive a single fulfillment. No request body. Archived fulfillments are hidden from default list results but remain retrievable.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response is always HTTP 200; if the fulfillment is already archived, the JSON `status` is `warning` with a per-field entry under `warnings`.\n\nReturns 404 for an unknown ID. Requires the `orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/archive","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","archive"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"The sales order fulfillment 'SO-10412.1' archived successfully\"\n}"}]},{"name":"Unarchive Fulfillment","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","unarchived"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]},"description":"Unarchive a single fulfillment, restoring it to default list results. No request body.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nNote the path segment is `unarchived` (the bulk endpoint uses `unarchive`).\n\nThe response is always HTTP 200; if the fulfillment is not archived, the JSON `status` is `warning` with a per-field entry under `warnings`.\n\nReturns 404 for an unknown ID. Requires the `orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/unarchived","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","unarchived"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"The sales order fulfillment 'SO-10412.1' unarchived successfully\"\n}"}]},{"name":"Mark Fulfillment as Printed","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/mark-as-printed","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","mark-as-printed"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]},"description":"Mark a fulfillment's packing slip as printed by stamping `packing_slip_printed_at` with the current time. No request body.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nExporting a packing slip sets this stamp automatically; use this endpoint to set it manually (e.g. after printing through your own system).\n\nNote: the endpoint responds with success even if the ID does not exist (no 404 is returned; zero rows are updated).\n\nRequires the `orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-order-fulfillments/{salesOrderFulfillmentId}/mark-as-printed","host":["{{baseUrl}}"],"path":["api","sales-order-fulfillments",":salesOrderFulfillmentId","mark-as-printed"],"variable":[{"key":"salesOrderFulfillmentId","value":"4821","description":"Fulfillment (shipment) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"The selected sales order fulfillment marked as printed successfully.\"\n}"}]}]},{"name":"Merged Shipments","item":[{"name":"Update Sales Order Payment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments",":payment"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"},{"key":"payment","value":"88","description":"Payment ID"}]},"description":"Updates a payment on a sales order and recalculates the order's payment status (unpaid / partially paid / paid) afterward.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields (all optional on update):\n- payment_type_id (integer): Must exist in payment types. Ignored when the payment is a system-created store-credit (`Credit`) payment — its type cannot be changed.\n- amount (number, < 100,000,000): A positive amount must not exceed the order's remaining balance (the payment's current amount is credited back before this check, so re-sending the same amount always passes). A negative amount is a refund and must not exceed the total already paid on the order.\n- payment_date (date): Payment date.\n- external_reference (string, max 255): External reference such as a cheque or transaction number.\n- currency_id (integer): Must exist in currencies.\n\nBehavior:\n- The payment must belong to the sales order in the path; otherwise a 422 is returned.\n- The response `data` is the stored payment record (including its payment type), which is a fuller shape than the entries returned by the list endpoint.\n\nPath parameters:\n- salesOrderId (required): Sales Order ID.\n- payment (required): Payment ID.\n\n**Requires permission:** `sales_orders.manage_payments`","body":{"mode":"raw","raw":"{\n  \"amount\": 120,\n  \"payment_date\": \"2026-07-01\",\n  \"payment_type_id\": 3,\n  \"external_reference\": \"CHECK # 039281\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments",":payment"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"},{"key":"payment","value":"88","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"link_id\": 500,\n    \"payment_date\": \"2026-07-01T00:00:00.000000Z\",\n    \"payment_type_id\": 3,\n    \"external_reference\": \"CHECK # 039281\",\n    \"type\": \"direct\",\n    \"amount\": 120,\n    \"cost\": null,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"currency_id_tenant_snapshot\": 1,\n    \"accounting_integration_id\": null,\n    \"accounting_integration_type\": null,\n    \"last_sync_error\": null,\n    \"created_at\": \"2026-06-28T16:40:12.000000Z\",\n    \"updated_at\": \"2026-07-06T09:15:33.000000Z\",\n    \"payment_type\": {\n      \"id\": 3,\n      \"name\": \"Check\",\n      \"user_id\": null,\n      \"accounting_integration_id\": null,\n      \"accounting_integration_type\": null,\n      \"archived_at\": null,\n      \"created_at\": \"2025-11-02T10:00:00.000000Z\",\n      \"updated_at\": \"2025-11-02T10:00:00.000000Z\"\n    }\n  },\n  \"message\": \"The sales order payment '88' updated successfully\"\n}"}]},{"name":"Delete Sales Order Payment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments",":payment"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"},{"key":"payment","value":"88","description":"Payment ID"}]},"description":"Delete a payment from a sales order. Recalculates the order's payment_status afterward.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nGuard: When the payment was created by applying a store credit (Credit-type payment) and a matching SalesCreditAllocation row exists (same sales_order_id and amount), this endpoint returns 422. Use the Unallocate Sales Credit endpoint under Customers instead — it reverses both the allocation and the corresponding payment atomically.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `sales_orders.manage_payments`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments",":payment"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"},{"key":"payment","value":"88","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"payments\": []\n  },\n  \"message\": \"payment deleted successfully\"\n}"}]},{"name":"List Sales Order Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"}]},"description":"Lists all payments recorded against a sales order.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse fields (per payment):\n- id (integer): Payment ID.\n- amount (number): Payment amount in the payment currency.\n- cost (number|null): Processing cost associated with the payment, when tracked.\n- payment_date (string): Payment date as a UTC datetime.\n- payment_type (object): `{id, name}` of the payment type (e.g. Check, Credit Card).\n- external_reference (string|null): External reference such as a cheque or transaction number.\n- type (string|null): `direct`, `overpayment`, `prepayment`, or null.\n- currency_code (string): ISO currency code of the payment.\n- sales_credit_allocation (object|null): `{id, sales_credit_id, sales_credit_number}` — set only on payments that were created by applying a store credit to the order. Such payments cannot be deleted directly; reverse them by unallocating the linked sales credit.\n\nPath parameters:\n- salesOrderId (required): Sales Order ID.\n\nReturns 404 when the sales order does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"amount\": 149.99,\n      \"cost\": null,\n      \"payment_date\": \"2026-06-28T00:00:00.000000Z\",\n      \"payment_type\": {\n        \"id\": 3,\n        \"name\": \"Check\"\n      },\n      \"external_reference\": \"CHECK # 039281\",\n      \"type\": \"direct\",\n      \"currency_code\": \"USD\",\n      \"sales_credit_allocation\": null\n    },\n    {\n      \"id\": 91,\n      \"amount\": 25,\n      \"cost\": null,\n      \"payment_date\": \"2026-07-02T00:00:00.000000Z\",\n      \"payment_type\": {\n        \"id\": 7,\n        \"name\": \"Credit\"\n      },\n      \"external_reference\": null,\n      \"type\": null,\n      \"currency_code\": \"USD\",\n      \"sales_credit_allocation\": {\n        \"id\": 41,\n        \"sales_credit_id\": 205,\n        \"sales_credit_number\": \"SC-0205\"\n      }\n    }\n  ]\n}"}]},{"name":"Record Sales Order Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"}]},"description":"Record a manual payment against a sales order and recalculate the order's payment_status.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n- `payment_type_id` (integer, required) — must exist in payment_types.\n- `amount` (numeric, required, < 100,000,000) — positive records a payment; **negative** records a refund (creates a Refund sales credit and a matching positive payment against it); an amount exceeding the order balance creates an Overpayment sales credit for the excess.\n- `payment_date` (date, optional) — defaults to today (Y-m-d) when omitted.\n- `external_reference` (string, optional, max 255) — e.g. a cheque or transaction number.\n- `currency_id` (integer, optional) — defaults to the sales order's currency when omitted.\n\n**Duplicate handling:** payments are unique on (payment_type_id, external_reference). Re-submitting an identical payment for the **same** order is idempotent (the existing payment is returned, no duplicate created). Reusing the same type+reference for a **different** payment (different owner/amount/date) returns **422** with an `external_reference` error — it no longer 500s.\n\n**Validation:** returns 422 if the order is already fully paid (positive amount), or if a refund exceeds the amount already paid.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `sales_orders.manage_payments`","body":{"mode":"raw","raw":"{\n  \"payment_type_id\": 3,\n  \"amount\": 149.99,\n  \"payment_date\": \"2026-07-06\",\n  \"external_reference\": \"CHECK # 039281\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrderId}/payments","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrderId","payments"],"variable":[{"key":"salesOrderId","value":"500","description":"Sales Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"link_id\": 500,\n    \"payment_type_id\": 3,\n    \"amount\": 149.99,\n    \"currency_id\": 1,\n    \"payment_date\": \"2026-07-06\",\n    \"external_reference\": \"CHECK # 039281\"\n  },\n  \"message\": \"sales order payment created successfully\"\n}"}]},{"name":"List Merged Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/merged-shipments?page=1&per_page=10&sort=-id","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix - for descending. Allowed: id, merged_shipment_number, status, created_at, shipped_at. Default: -id","disabled":true}]},"description":"Returns a paginated list of merged shipments (sales-order merge groups).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery Parameters:\n- page (integer): Page number (default 1)\n- per_page (integer): Items per page (default 10)\n- sort (string): One of id, merged_shipment_number, status, created_at, shipped_at. Prefix with - for descending. Default -id.\n- filter[id]: Exact match\n- filter[status]: Exact match on status enum (awaiting_pack, awaiting_label, awaiting_ship, shipped, cancelled, unmerged)\n- filter[warehouse_id]: Exact match\n- filter[merged_shipment_number]: Partial match\n- filter[open_only]: Boolean — restricts to in-progress merge groups (excludes cancelled/unmerged/shipped)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/merged-shipments?page=1&per_page=10&sort=-id","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix - for descending. Allowed: id, merged_shipment_number, status, created_at, shipped_at. Default: -id","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"merged_shipment_number\": \"MS-000012\",\n      \"status\": \"awaiting_pack\",\n      \"status_label\": \"Awaiting Pack\",\n      \"integration_instance_id\": 3,\n      \"primary_sales_order_id\": 5501,\n      \"warehouse_id\": 1,\n      \"tracking_number\": null,\n      \"tracking_url\": null,\n      \"fulfilled_shipping_method_id\": null,\n      \"package_weight\": null,\n      \"package_length\": null,\n      \"package_width\": null,\n      \"package_height\": null,\n      \"notes\": \"Merged at customer's request\",\n      \"metadata\": null,\n      \"label_purchased_at\": null,\n      \"shipped_at\": null,\n      \"cancelled_at\": null,\n      \"unmerged_at\": null,\n      \"created_at\": \"2026-05-04T15:23:11.000000Z\",\n      \"updated_at\": \"2026-05-04T15:23:11.000000Z\",\n      \"is_label_purchased\": false,\n      \"is_shipped\": false,\n      \"primary_sales_order\": {\n        \"id\": 5501,\n        \"sales_order_number\": \"SO-2026-5501\",\n        \"order_date\": \"2026-05-04\",\n        \"customer_name\": \"Jane Doe\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"creator\": {\n        \"id\": 7,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"fulfilled_shipping_method\": null,\n      \"fulfillments\": [\n        {\n          \"id\": 9001,\n          \"fulfillment_number\": \"F-9001\",\n          \"status\": \"submitted\",\n          \"sales_order_id\": 5501,\n          \"sales_order\": {\n            \"id\": 5501,\n            \"sales_order_number\": \"SO-2026-5501\",\n            \"order_status\": \"open\",\n            \"fulfillment_status\": \"pending\"\n          }\n        },\n        {\n          \"id\": 9002,\n          \"fulfillment_number\": \"F-9002\",\n          \"status\": \"submitted\",\n          \"sales_order_id\": 5502,\n          \"sales_order\": {\n            \"id\": 5502,\n            \"sales_order_number\": \"SO-2026-5502\",\n            \"order_status\": \"open\",\n            \"fulfillment_status\": \"pending\"\n          }\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/v2/merged-shipments?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/v2/merged-shipments?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/v2/merged-shipments\",\n  \"links\": []\n}"}]},{"name":"Create Merged Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/merged-shipments","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments"]},"description":"Merges two or more sales orders into a single physical shipment (merge group). Each underlying sales order remains intact; one fulfillment per SO is created and linked to the new merge group. The lowest-ID order is the primary.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- sales_order_ids (required, integer[]): Two or more sales order IDs to merge\n- notes (optional, string, max 2000): Free-form notes attached to the merge group\n- acknowledge_warnings (optional, boolean): If true, allows merging despite warnings (e.g. ship-by date variance). Blockers always prevent merging.","body":{"mode":"raw","raw":"{\n  \"sales_order_ids\": [\n    5501,\n    5502\n  ],\n  \"notes\": \"Merged at customer's request\",\n  \"acknowledge_warnings\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/merged-shipments","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"merged_shipment_number\": \"MS-000012\",\n    \"status\": \"awaiting_pack\",\n    \"status_label\": \"Awaiting Pack\",\n    \"integration_instance_id\": 3,\n    \"primary_sales_order_id\": 5501,\n    \"warehouse_id\": 1,\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"fulfilled_shipping_method_id\": null,\n    \"package_weight\": null,\n    \"package_length\": null,\n    \"package_width\": null,\n    \"package_height\": null,\n    \"notes\": \"Merged at customer's request\",\n    \"metadata\": null,\n    \"label_purchased_at\": null,\n    \"shipped_at\": null,\n    \"cancelled_at\": null,\n    \"unmerged_at\": null,\n    \"created_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"updated_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"is_label_purchased\": false,\n    \"is_shipped\": false,\n    \"primary_sales_order\": {\n      \"id\": 5501,\n      \"sales_order_number\": \"SO-2026-5501\",\n      \"order_date\": \"2026-05-04\",\n      \"customer_name\": \"Jane Doe\"\n    },\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"creator\": {\n      \"id\": 7,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"fulfilled_shipping_method\": null,\n    \"fulfillments\": [\n      {\n        \"id\": 9001,\n        \"fulfillment_number\": \"F-9001\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5501,\n        \"sales_order\": {\n          \"id\": 5501,\n          \"sales_order_number\": \"SO-2026-5501\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      },\n      {\n        \"id\": 9002,\n        \"fulfillment_number\": \"F-9002\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5502,\n        \"sales_order\": {\n          \"id\": 5502,\n          \"sales_order_number\": \"SO-2026-5502\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Check Merge Eligibility","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/eligibility","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments","eligibility"]},"description":"Evaluates whether a set of sales orders can be merged into a single physical shipment. Returns blockers (hard failures) and warnings (acknowledgeable issues). Does not perform the merge.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- sales_order_ids (required, integer[]): Two or more sales order IDs to evaluate\n- proposed_warehouse_id (optional, integer): Override the inferred fulfilling warehouse","body":{"mode":"raw","raw":"{\n  \"sales_order_ids\": [\n    5501,\n    5502\n  ],\n  \"proposed_warehouse_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/eligibility","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments","eligibility"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"is_eligible\": true,\n    \"primary_sales_order_id\": 5501,\n    \"warehouse_id\": 1,\n    \"integration_instance_id\": 3,\n    \"shipping_address_signature\": \"a3f9c1d8b2e7...\",\n    \"member_sales_order_ids\": [\n      5501,\n      5502\n    ],\n    \"has_blockers\": false,\n    \"has_warnings\": false,\n    \"blockers\": [],\n    \"warnings\": []\n  }\n}"}]},{"name":"Get Merged Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/{mergedShipment}","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments",":mergedShipment"],"variable":[{"key":"mergedShipment","value":"","description":"The merged shipment ID."}]},"description":"Returns a single merged shipment with primary sales order, warehouse, creator, shipping method, and per-SO fulfillments eager-loaded.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nPath Parameters:\n- mergedShipment (integer): ID of the merge group"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/{mergedShipment}","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments",":mergedShipment"],"variable":[{"key":"mergedShipment","value":"","description":"The merged shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"merged_shipment_number\": \"MS-000012\",\n    \"status\": \"awaiting_pack\",\n    \"status_label\": \"Awaiting Pack\",\n    \"integration_instance_id\": 3,\n    \"primary_sales_order_id\": 5501,\n    \"warehouse_id\": 1,\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"fulfilled_shipping_method_id\": null,\n    \"package_weight\": null,\n    \"package_length\": null,\n    \"package_width\": null,\n    \"package_height\": null,\n    \"notes\": \"Merged at customer's request\",\n    \"metadata\": null,\n    \"label_purchased_at\": null,\n    \"shipped_at\": null,\n    \"cancelled_at\": null,\n    \"unmerged_at\": null,\n    \"created_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"updated_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"is_label_purchased\": false,\n    \"is_shipped\": false,\n    \"primary_sales_order\": {\n      \"id\": 5501,\n      \"sales_order_number\": \"SO-2026-5501\",\n      \"order_date\": \"2026-05-04\",\n      \"customer_name\": \"Jane Doe\"\n    },\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"creator\": {\n      \"id\": 7,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"fulfilled_shipping_method\": null,\n    \"fulfillments\": [\n      {\n        \"id\": 9001,\n        \"fulfillment_number\": \"F-9001\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5501,\n        \"sales_order\": {\n          \"id\": 5501,\n          \"sales_order_number\": \"SO-2026-5501\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      },\n      {\n        \"id\": 9002,\n        \"fulfillment_number\": \"F-9002\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5502,\n        \"sales_order\": {\n          \"id\": 5502,\n          \"sales_order_number\": \"SO-2026-5502\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Unmerge Merged Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/{mergedShipment}/unmerge","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments",":mergedShipment","unmerge"],"variable":[{"key":"mergedShipment","value":"","description":"The merged shipment ID."}]},"description":"Reverses a merge group, restoring each sales order to its pre-merge state. Only allowed before a label is purchased / the shipment is shipped.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nPath Parameters:\n- mergedShipment (integer): ID of the merge group\n\nRequest Body:\n- reason (optional, string, max 1000): Audit-trail reason for the unmerge","body":{"mode":"raw","raw":"{\n  \"reason\": \"Customer requested separate shipments\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/merged-shipments/{mergedShipment}/unmerge","host":["{{baseUrl}}"],"path":["api","v2","merged-shipments",":mergedShipment","unmerge"],"variable":[{"key":"mergedShipment","value":"","description":"The merged shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"merged_shipment_number\": \"MS-000012\",\n    \"status\": \"unmerged\",\n    \"status_label\": \"Unmerged\",\n    \"integration_instance_id\": 3,\n    \"primary_sales_order_id\": 5501,\n    \"warehouse_id\": 1,\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"fulfilled_shipping_method_id\": null,\n    \"package_weight\": null,\n    \"package_length\": null,\n    \"package_width\": null,\n    \"package_height\": null,\n    \"notes\": \"Merged at customer's request\",\n    \"metadata\": null,\n    \"label_purchased_at\": null,\n    \"shipped_at\": null,\n    \"cancelled_at\": null,\n    \"unmerged_at\": \"2026-05-04T17:11:02.000000Z\",\n    \"created_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"updated_at\": \"2026-05-04T15:23:11.000000Z\",\n    \"is_label_purchased\": false,\n    \"is_shipped\": false,\n    \"primary_sales_order\": {\n      \"id\": 5501,\n      \"sales_order_number\": \"SO-2026-5501\",\n      \"order_date\": \"2026-05-04\",\n      \"customer_name\": \"Jane Doe\"\n    },\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"creator\": {\n      \"id\": 7,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"fulfilled_shipping_method\": null,\n    \"fulfillments\": [\n      {\n        \"id\": 9001,\n        \"fulfillment_number\": \"F-9001\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5501,\n        \"sales_order\": {\n          \"id\": 5501,\n          \"sales_order_number\": \"SO-2026-5501\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      },\n      {\n        \"id\": 9002,\n        \"fulfillment_number\": \"F-9002\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5502,\n        \"sales_order\": {\n          \"id\": 5502,\n          \"sales_order_number\": \"SO-2026-5502\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"pending\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"List Merge Candidates for Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/merge-candidates?limit=25","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","merge-candidates"],"query":[{"key":"limit","value":"25","description":"Max candidates to return. Clamped to range 1-50. Default: 25.","disabled":true}],"variable":[{"key":"salesOrder","value":"5501","description":"ID of the anchor sales order. Returns other open sales orders that share its warehouse and shipping address signature."}]},"description":"Returns a list of open sales orders eligible to be merged into a single shipment with the anchor sales order.\n\n**Eligibility rules** — a candidate is included only if it:\n- Is not the anchor itself.\n- Has order_status of `open` or `reserved`.\n- Ships from the same single warehouse as the anchor (across all of its lines).\n- Has the same shipping address signature (name + company + address1 + address2 + city + province + zip + country_code) as the anchor.\n- Is not already a member of any open SalesOrderMergeGroup.\n- Has no in-progress SalesOrderFulfillment (submitted, processing, or shipped).\n\nIf the anchor itself has no shipping address, an empty list is returned.\n\n**Response shape** — `data[]` is an array of `MergeCandidateData`:\n- `sales_order_id` (int)\n- `sales_order_number` (string)\n- `order_status` (string — typically `open` or `reserved`)\n- `customer_name` (string | null)\n- `integration_instance_name` (string | null) — name of the sales channel's integration instance, when applicable\n- `integration_instance_id` (int | null)\n- `line_count` (int)\n- `total_quantity` (int)\n- `integration_matches_anchor` (bool) — `false` when the candidate is from a different sales channel/integration than the anchor; the UI should warn before merging.\n\n**Auth:** Bearer token (scope `rw:orders`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/merge-candidates?limit=25","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","merge-candidates"],"query":[{"key":"limit","value":"25","description":"Max candidates to return. Clamped to range 1-50. Default: 25.","disabled":true}],"variable":[{"key":"salesOrder","value":"5501","description":"ID of the anchor sales order. Returns other open sales orders that share its warehouse and shipping address signature."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sales_order_id\": 5502,\n      \"sales_order_number\": \"SO-2026-5502\",\n      \"order_status\": \"open\",\n      \"customer_name\": \"Jane Doe\",\n      \"integration_instance_name\": \"Acme Shopify\",\n      \"integration_instance_id\": 3,\n      \"line_count\": 2,\n      \"total_quantity\": 5,\n      \"integration_matches_anchor\": true\n    },\n    {\n      \"sales_order_id\": 5503,\n      \"sales_order_number\": \"SO-2026-5503\",\n      \"order_status\": \"open\",\n      \"customer_name\": \"Jane Doe\",\n      \"integration_instance_name\": \"Acme Amazon US\",\n      \"integration_instance_id\": 7,\n      \"line_count\": 1,\n      \"total_quantity\": 1,\n      \"integration_matches_anchor\": false\n    }\n  ]\n}"}]},{"name":"Get Active Merge Group for Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/active-merge-group","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","active-merge-group"],"variable":[{"key":"salesOrder","value":"5501","description":"Sales order ID"}]},"description":"Returns the open merged shipment (not yet shipped, cancelled, or unmerged) that the sales order currently belongs to, with primary sales order, warehouse, creator, shipping method, and per-order fulfillments (including lines) eager-loaded. Returns `null` data when the order is not part of an active merge group.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath Parameters:\n- salesOrder (integer): ID of the sales order"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/sales-orders/{salesOrder}/active-merge-group","host":["{{baseUrl}}"],"path":["api","v2","sales-orders",":salesOrder","active-merge-group"],"variable":[{"key":"salesOrder","value":"5501","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"merged_shipment_number\": \"MS-000012\",\n    \"derived_status\": \"submitted\",\n    \"derived_status_label\": \"Submitted\",\n    \"integration_instance_id\": 3,\n    \"primary_sales_order_id\": 5501,\n    \"warehouse_id\": 1,\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"fulfilled_shipping_method_id\": null,\n    \"package_weight\": null,\n    \"package_length\": null,\n    \"package_width\": null,\n    \"package_height\": null,\n    \"notes\": \"Merged at customer's request\",\n    \"metadata\": null,\n    \"label_purchased_at\": null,\n    \"shipped_at\": null,\n    \"cancelled_at\": null,\n    \"unmerged_at\": null,\n    \"created_at\": \"2026-07-04T15:23:11.000000Z\",\n    \"updated_at\": \"2026-07-04T15:23:11.000000Z\",\n    \"is_label_purchased\": false,\n    \"is_shipped\": false,\n    \"is_cancelled\": false,\n    \"is_unmerged\": false,\n    \"primary_sales_order\": {\n      \"id\": 5501,\n      \"sales_order_number\": \"SO-2026-5501\",\n      \"order_date\": \"2026-07-04\",\n      \"customer_name\": \"Jane Doe\"\n    },\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"creator\": {\n      \"id\": 7,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"fulfilled_shipping_method\": null,\n    \"fulfillments\": [\n      {\n        \"id\": 9001,\n        \"fulfillment_number\": \"F-9001\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5501,\n        \"sales_order\": {\n          \"id\": 5501,\n          \"sales_order_number\": \"SO-2026-5501\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"unfulfilled\"\n        },\n        \"lines\": [\n          {\n            \"id\": 15601,\n            \"sales_order_line_id\": 8912,\n            \"quantity\": 2,\n            \"sku\": \"WIDGET-BLUE\",\n            \"product_name\": \"Blue Widget\",\n            \"product_id\": 341\n          }\n        ]\n      },\n      {\n        \"id\": 9002,\n        \"fulfillment_number\": \"F-9002\",\n        \"status\": \"submitted\",\n        \"sales_order_id\": 5502,\n        \"sales_order\": {\n          \"id\": 5502,\n          \"sales_order_number\": \"SO-2026-5502\",\n          \"order_status\": \"open\",\n          \"fulfillment_status\": \"unfulfilled\"\n        },\n        \"lines\": [\n          {\n            \"id\": 15602,\n            \"sales_order_line_id\": 8955,\n            \"quantity\": 1,\n            \"sku\": \"WIDGET-RED\",\n            \"product_name\": \"Red Widget\",\n            \"product_id\": 355\n          }\n        ]\n      }\n    ]\n  }\n}"}]}]},{"name":"Channel Refunds","item":[{"name":"Get Channel Refund Context","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refund/context","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refund","context"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]},"description":"Returns the refund capabilities and current refundable state for a sales order's channel: per-line refundable quantities and amounts (net of refunds already recorded on the channel), refundable shipping, supported restock options and locations, required reason codes, and whether the channel processes refunds asynchronously.\n\nWhen the channel does not support API refunds, `supported` is false and `deep_link` (when available) points to the channel's own refund page.\n\nRequires a Bearer token.\n- `capabilities.notice` (string|null) — channel-specific caveat rendered as an info alert in the refund dialog (e.g. Magento 1 credit memos are offline — no money moves on the channel)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refund/context","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refund","context"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"supported\": true,\n    \"channel\": \"shopify\",\n    \"instance_id\": 3,\n    \"currency_code\": \"USD\",\n    \"async\": false,\n    \"capabilities\": {\n      \"supported\": true,\n      \"async\": false,\n      \"line_items\": true,\n      \"shipping\": true,\n      \"custom_amount\": false,\n      \"restock_options\": [\n        \"return\",\n        \"cancel\",\n        \"no_restock\"\n      ],\n      \"restock_locations\": [\n        {\n          \"id\": \"gid://shopify/Location/1\",\n          \"name\": \"Main Warehouse\"\n        }\n      ],\n      \"reasons\": [],\n      \"notify_customer\": true,\n      \"reason_required\": false,\n      \"deep_link\": null,\n      \"unsupported_reason\": null,\n      \"notice\": null\n    },\n    \"previously_refunded_total\": 0,\n    \"pending_request_total\": 0,\n    \"shipping\": {\n      \"charged\": 4.9,\n      \"refunded\": 0,\n      \"refundable\": 4.9\n    },\n    \"lines\": [\n      {\n        \"sales_order_line_id\": 991,\n        \"channel_line_id\": \"gid://shopify/LineItem/222\",\n        \"sku\": \"BLU-W\",\n        \"description\": \"Blue Widget\",\n        \"unit_price\": 25,\n        \"quantity_ordered\": 2,\n        \"quantity_refunded\": 0,\n        \"quantity_refundable\": 2,\n        \"tax_per_unit\": 2.06,\n        \"product_id\": 42\n      }\n    ],\n    \"deep_link\": null,\n    \"unsupported_reason\": null\n  }\n}"}]},{"name":"List Channel Refund Requests","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refunds","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refunds"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]},"description":"Lists every channel refund request recorded for the sales order, newest first, including status, amounts, the channel-side refund ID, and the linked sales credit once the refund has been confirmed and imported.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refunds","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refunds"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 17,\n      \"sales_order_id\": 500,\n      \"channel\": \"shopify\",\n      \"status\": \"completed\",\n      \"total_amount\": 31.9,\n      \"currency_code\": \"USD\",\n      \"channel_refund_id\": \"987654321\",\n      \"sales_credit_id\": 4521,\n      \"sales_credit_number\": \"SC-00231\",\n      \"requested_by\": {\n        \"id\": 8,\n        \"name\": \"Jane Operator\"\n      },\n      \"request_payload\": {\n        \"lines\": [\n          {\n            \"sales_order_line_id\": 991,\n            \"quantity\": 1,\n            \"amount\": 25,\n            \"restock\": \"return\",\n            \"restock_location_id\": \"gid://shopify/Location/1\"\n          }\n        ],\n        \"shipping_amount\": 4.9,\n        \"custom_amount\": 0,\n        \"reason\": null,\n        \"note\": \"Customer emailed photos of damage\",\n        \"notify_customer\": true\n      },\n      \"error\": null,\n      \"submitted_at\": \"2026-07-10T18:22:04+00:00\",\n      \"completed_at\": \"2026-07-10T18:22:09+00:00\",\n      \"created_at\": \"2026-07-10T18:22:03+00:00\"\n    }\n  ]\n}"}]},{"name":"Issue Channel Refund","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refunds","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refunds"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]},"description":"Creates and submits a refund to the order's sales channel. Amounts are validated server-side against the channel's refundable state: line quantities may not exceed the refundable quantity, line amounts may not exceed quantity times unit price, and the shipping amount may not exceed the refundable shipping. Line tax is added automatically to the total sent to the channel.\n\nFields:\n- `lines` (array, required, may be empty when only shipping or a custom amount is refunded)\n- `lines[].sales_order_line_id` (integer, required) — must belong to the order\n- `lines[].quantity` (number, required, min 0)\n- `lines[].amount` (number, required, min 0) — product amount excluding tax\n- `lines[].restock` (string, optional: return | cancel | no_restock) — channels with restock support only\n- `lines[].restock_location_id` (string, optional) — channel location for restocking\n- `shipping_amount` (number, optional, min 0)\n- `custom_amount` (number, optional, min 0) — only on channels whose capabilities report `custom_amount: true`\n- `reason` (string, optional; required when capabilities report `reason_required: true` — use a value from `capabilities.reasons`)\n- `note` (string, optional, max 1000)\n- `notify_customer` (boolean, optional)\n\nOnly one refund request may be in flight per order at a time; a second submission returns 409 until the first reaches a terminal state.\n\nAsynchronous channels (eBay) return `status: awaiting_channel`; the status updates automatically once the channel finishes processing.\n\nRequires a Bearer token and refund permission.\n- Each `lines[].sales_order_line_id` must be unique within the request (`distinct` validation) — duplicate entries are rejected with a 422 because their summed quantity could exceed the line's refundable quantity.","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"sales_order_line_id\": 991,\n      \"quantity\": 1,\n      \"amount\": 25,\n      \"restock\": \"return\",\n      \"restock_location_id\": \"gid://shopify/Location/1\"\n    }\n  ],\n  \"shipping_amount\": 4.9,\n  \"custom_amount\": 0,\n  \"reason\": \"damaged\",\n  \"note\": \"Customer emailed photos of damage\",\n  \"notify_customer\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/channel-refunds","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","channel-refunds"],"variable":[{"key":"salesOrder","value":"500","description":"The sales order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"sales_order_id\": 500,\n    \"channel\": \"shopify\",\n    \"status\": \"completed\",\n    \"total_amount\": 31.9,\n    \"currency_code\": \"USD\",\n    \"channel_refund_id\": \"987654321\",\n    \"sales_credit_id\": 4521,\n    \"sales_credit_number\": \"SC-00231\",\n    \"requested_by\": {\n      \"id\": 8,\n      \"name\": \"Jane Operator\"\n    },\n    \"request_payload\": {\n      \"lines\": [\n        {\n          \"sales_order_line_id\": 991,\n          \"quantity\": 1,\n          \"amount\": 25,\n          \"restock\": \"return\",\n          \"restock_location_id\": \"gid://shopify/Location/1\"\n        }\n      ],\n      \"shipping_amount\": 4.9,\n      \"custom_amount\": 0,\n      \"reason\": null,\n      \"note\": \"Customer emailed photos of damage\",\n      \"notify_customer\": true\n    },\n    \"error\": null,\n    \"submitted_at\": \"2026-07-10T18:22:04+00:00\",\n    \"completed_at\": \"2026-07-10T18:22:09+00:00\",\n    \"created_at\": \"2026-07-10T18:22:03+00:00\"\n  }\n}"}]},{"name":"Retry Channel Refund Request","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/channel-refund-requests/{channelRefundRequest}/retry","host":["{{baseUrl}}"],"path":["api","channel-refund-requests",":channelRefundRequest","retry"],"variable":[{"key":"channelRefundRequest","value":"17","description":"The channel refund request ID"}]},"description":"Re-submits a failed refund request to the channel after re-validating it against the current refundable state. Only requests with status `failed` can be retried.\n\nRequires a Bearer token and refund permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-refund-requests/{channelRefundRequest}/retry","host":["{{baseUrl}}"],"path":["api","channel-refund-requests",":channelRefundRequest","retry"],"variable":[{"key":"channelRefundRequest","value":"17","description":"The channel refund request ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"sales_order_id\": 500,\n    \"channel\": \"shopify\",\n    \"status\": \"completed\",\n    \"total_amount\": 31.9,\n    \"currency_code\": \"USD\",\n    \"channel_refund_id\": \"987654321\",\n    \"sales_credit_id\": 4521,\n    \"sales_credit_number\": \"SC-00231\",\n    \"requested_by\": {\n      \"id\": 8,\n      \"name\": \"Jane Operator\"\n    },\n    \"request_payload\": {\n      \"lines\": [\n        {\n          \"sales_order_line_id\": 991,\n          \"quantity\": 1,\n          \"amount\": 25,\n          \"restock\": \"return\",\n          \"restock_location_id\": \"gid://shopify/Location/1\"\n        }\n      ],\n      \"shipping_amount\": 4.9,\n      \"custom_amount\": 0,\n      \"reason\": null,\n      \"note\": \"Customer emailed photos of damage\",\n      \"notify_customer\": true\n    },\n    \"error\": null,\n    \"submitted_at\": \"2026-07-10T18:22:04+00:00\",\n    \"completed_at\": \"2026-07-10T18:22:09+00:00\",\n    \"created_at\": \"2026-07-10T18:22:03+00:00\"\n  }\n}"}]},{"name":"Check Channel Refund Status","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/channel-refund-requests/{channelRefundRequest}/check-status","host":["{{baseUrl}}"],"path":["api","channel-refund-requests",":channelRefundRequest","check-status"],"variable":[{"key":"channelRefundRequest","value":"17","description":"The channel refund request ID"}]},"description":"Polls the sales channel for the outcome of an asynchronous refund request (for example an eBay refund still in `awaiting_channel`), updates the stored status, and links the resulting sales credit when the refund has been imported. Terminal requests are returned unchanged.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-refund-requests/{channelRefundRequest}/check-status","host":["{{baseUrl}}"],"path":["api","channel-refund-requests",":channelRefundRequest","check-status"],"variable":[{"key":"channelRefundRequest","value":"17","description":"The channel refund request ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"sales_order_id\": 500,\n    \"channel\": \"shopify\",\n    \"status\": \"awaiting_channel\",\n    \"total_amount\": 31.9,\n    \"currency_code\": \"USD\",\n    \"channel_refund_id\": \"987654321\",\n    \"sales_credit_id\": null,\n    \"sales_credit_number\": null,\n    \"requested_by\": {\n      \"id\": 8,\n      \"name\": \"Jane Operator\"\n    },\n    \"request_payload\": {\n      \"lines\": [\n        {\n          \"sales_order_line_id\": 991,\n          \"quantity\": 1,\n          \"amount\": 25,\n          \"restock\": \"return\",\n          \"restock_location_id\": \"gid://shopify/Location/1\"\n        }\n      ],\n      \"shipping_amount\": 4.9,\n      \"custom_amount\": 0,\n      \"reason\": null,\n      \"note\": \"Customer emailed photos of damage\",\n      \"notify_customer\": true\n    },\n    \"error\": null,\n    \"submitted_at\": \"2026-07-10T18:22:04+00:00\",\n    \"completed_at\": null,\n    \"created_at\": \"2026-07-10T18:22:03+00:00\"\n  }\n}"}]}]},{"name":"Purchase Orders","item":[{"name":"List Purchase Orders (list view)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders?page=1&limit=15&sort=created_at&search=&filter[order_status]=open&filter[arriving_this_week]=1&filter[overdue]=1&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","purchase-orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Items per page","disabled":true},{"key":"sort","value":"created_at","description":"Sort field. Prefix with - for descending (e.g. -created_at). Allowed: id, purchase_order_number, purchase_order_date, estimated_delivery_date, order_status, submission_status, receipt_status, shipment_status, invoice_status, total, total_quantity, supplier_id, created_at, updated_at","disabled":true},{"key":"search","value":"","description":"Full-text search across PO number, supplier name, item SKU, invoice number, tracking number","disabled":true},{"key":"filter[order_status]","value":"open","description":"Filter by order status: draft, open, closed","disabled":true},{"key":"filter[arriving_this_week]","value":"1","description":"Filter POs arriving this week (1=true)","disabled":true},{"key":"filter[overdue]","value":"1","description":"Filter overdue POs (1=true)","disabled":true},{"key":"archived","value":"0","description":"Include archived: 0=exclude (default), 1=include, only=archived only","disabled":true},{"key":"included[]","value":"","description":"Relationships to include","disabled":true},{"key":"excluded[]","value":"","description":"Fields to exclude from response","disabled":true}]},"description":"Paginated purchase orders list using the list view trait. Supports full-text search, filters, sorting, and archival state.\n\nAuthentication: Requires Bearer token.\n\nFilter scopes available:\n- filter[order_status]: draft, open, closed\n- filter[arriving_this_week]: 1\n- filter[overdue]: 1\n- filter[submission_status]: pending, sent\n- filter[receipt_status]: unreceived, partial, received, dropship\n- filter[shipment_status]: pending, shipped\n- filter[invoice_status]: uninvoiced, partial, invoiced\n\nAllowed sorts: id, purchase_order_number, purchase_order_date, estimated_delivery_date, order_status, submission_status, receipt_status, shipment_status, invoice_status, total, total_quantity, supplier_id, created_at, updated_at\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders?page=1&limit=15&sort=created_at&search=&filter[order_status]=open&filter[arriving_this_week]=1&filter[overdue]=1&archived=0&included[]=&excluded[]=","host":["{{baseUrl}}"],"path":["api","purchase-orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Items per page","disabled":true},{"key":"sort","value":"created_at","description":"Sort field. Prefix with - for descending (e.g. -created_at). Allowed: id, purchase_order_number, purchase_order_date, estimated_delivery_date, order_status, submission_status, receipt_status, shipment_status, invoice_status, total, total_quantity, supplier_id, created_at, updated_at","disabled":true},{"key":"search","value":"","description":"Full-text search across PO number, supplier name, item SKU, invoice number, tracking number","disabled":true},{"key":"filter[order_status]","value":"open","description":"Filter by order status: draft, open, closed","disabled":true},{"key":"filter[arriving_this_week]","value":"1","description":"Filter POs arriving this week (1=true)","disabled":true},{"key":"filter[overdue]","value":"1","description":"Filter overdue POs (1=true)","disabled":true},{"key":"archived","value":"0","description":"Include archived: 0=exclude (default), 1=include, only=archived only","disabled":true},{"key":"included[]","value":"","description":"Relationships to include","disabled":true},{"key":"excluded[]","value":"","description":"Fields to exclude from response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"po_number\": \"PO-00101\",\n      \"purchase_order_date\": \"2024-01-15\",\n      \"supplier_id\": 5,\n      \"supplier_name\": {\n        \"id\": 5,\n        \"name\": \"Acme Supplies\"\n      },\n      \"destination_warehouse_id\": 2,\n      \"order_status\": \"open\",\n      \"submission_status\": \"sent\",\n      \"submission_blocked_no_email\": false,\n      \"receipt_status\": \"unreceived\",\n      \"shipment_status\": \"pending\",\n      \"invoice_status\": \"uninvoiced\",\n      \"total\": 1500,\n      \"total_quantity\": 100,\n      \"estimated_delivery_date\": \"2024-02-01\",\n      \"created_at\": \"2024-01-15T10:00:00Z\",\n      \"updated_at\": \"2024-01-15T10:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 15,\n  \"total\": 72,\n  \"unfiltered_total\": 1843,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Create Purchase Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders","host":["{{baseUrl}}"],"path":["api","purchase-orders"]},"description":"Create a new purchase order with optional line items.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired fields:\n- purchase_order_date (date)\n- supplier_id OR supplier_name\n- currency_id OR currency_code\n- destination_warehouse_id: warehouse the stock will be received into (required for standard purchase orders; omit for dropship purchase orders, which ship directly to the customer)\n\nOptional fields:\n- purchase_order_number: custom PO number (auto-generated if omitted)\n- approval_status: pending (default) or approved\n- order_status: draft (only allowed value; omit for open)\n- shipment_id: required when destination_warehouse is Amazon FBA\n\nLine item fields:\n- product_id OR sku (required if not a cost line)\n- quantity (required, min:0)\n- amount (required, min:0) — unit cost\n- description, discount, tax_rate_id, estimated_delivery_date, nominal_code_id, is_free_of_charge, free_of_charge_reason, linked_backorders all optional\n\n**Requires permission:** `purchase_orders.create`","body":{"mode":"raw","raw":"{\n  \"purchase_order_date\": \"2024-01-15\",\n  \"supplier_id\": 5,\n  \"currency_id\": 1,\n  \"destination_warehouse_id\": 2,\n  \"purchase_order_number\": \"PO-CUSTOM-001\",\n  \"submission_format\": \"email\",\n  \"payment_term_id\": 1,\n  \"incoterm_id\": null,\n  \"store_id\": 1,\n  \"estimated_delivery_date\": \"2024-02-01\",\n  \"other_date\": null,\n  \"supplier_notes\": \"Please ship ASAP\",\n  \"tracking_number\": null,\n  \"is_tax_included\": false,\n  \"tax_rate_id\": null,\n  \"currency_rate\": 1,\n  \"approval_status\": \"pending\",\n  \"tags\": [\n    \"urgent\"\n  ],\n  \"shipment_id\": null,\n  \"purchase_order_lines\": [\n    {\n      \"product_id\": 10,\n      \"description\": \"Widget A\",\n      \"quantity\": 100,\n      \"amount\": 15,\n      \"discount\": 0,\n      \"tax_rate_id\": null,\n      \"estimated_delivery_date\": null,\n      \"nominal_code_id\": null,\n      \"is_free_of_charge\": false,\n      \"linked_backorders\": []\n    }\n  ],\n  \"financial_lines\": [\n    {\n      \"description\": \"Freight\",\n      \"quantity\": 1,\n      \"amount\": 50,\n      \"financial_line_type_id\": 1,\n      \"allocate_to_products\": true,\n      \"proration_strategy\": \"quantity\"\n    }\n  ],\n  \"incoterm_place\": \"Port of Los Angeles, CA\",\n  \"incoterm_version\": 2020\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders","host":["{{baseUrl}}"],"path":["api","purchase-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 102,\n    \"po_number\": \"PO-CUSTOM-001\",\n    \"order_status\": \"open\",\n    \"total\": 1550\n  },\n  \"message\": \"Purchase order created successfully\"\n}"}]},{"name":"Bulk Delete Purchase Orders","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders","host":["{{baseUrl}}"],"path":["api","purchase-orders"]},"description":"Bulk delete purchase orders by IDs or by filter criteria.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPass either ids[] or filters{} (Spatie filter params — same as list endpoint). Filters are resolved to IDs before deletion.\n\n**Requires permission:** `purchase_orders.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-orders","host":["{{baseUrl}}"],"path":["api","purchase-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase orders deleted successfully\"\n}"}]},{"name":"List Purchase Orders (List)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/list?page=1&per_page=15&sort=-created_at&filter[search]=PO-001&filter[archived]=&filter[asn_sent]=&filter[is_tax_included]=&filter[arriving_this_week]=&filter[overdue]=&filter[order_status][is]=open&filter[supplier_id][equals]=&filter[destination_warehouse_id][equals]=&filter[purchase_order_date][on_or_after]=&filter[total][greater_than]=&filter[logistics_<slug>_estimate][on_or_after]=&filter[logistics_<slug>_actual][on_or_before]=&filter_groups[conjunction]=and&filter_groups[children][0][type]=condition","host":["{{baseUrl}}"],"path":["api","purchase-orders","list"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix - for descending. Allowed: id, purchase_order_number, purchase_order_date, other_date, order_status, submission_status, receipt_status, shipment_status, invoice_status, estimated_delivery_date, tracking_number, total, total_quantity, tax_total, supplier_notes, supplier_name, destination_warehouse_name, currency_code, product_total, additional_cost, discount, line_item_count, payment_term_name, incoterm_description, created_at, updated_at, fully_received_at, asn_last_sent_at, submission_format, requested_shipping_method, currency_rate","disabled":true},{"key":"filter[search]","value":"PO-001","description":"Full-text search across PO number (exact ID), tracking number, order status, submission format, supplier name, item SKU, invoice number","disabled":true},{"key":"filter[archived]","value":"","description":"Archival filter: omit=non-archived only, 'only'=archived only. Also supports advanced: filter[archived.is]=true","disabled":true},{"key":"filter[asn_sent]","value":"","description":"ASN sent filter: true/false","disabled":true},{"key":"filter[is_tax_included]","value":"","description":"Tax included filter: true/false","disabled":true},{"key":"filter[arriving_this_week]","value":"","description":"Arriving this week scope filter","disabled":true},{"key":"filter[overdue]","value":"","description":"Overdue scope filter","disabled":true},{"key":"filter[order_status][is]","value":"open","description":"Advanced text filter operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of","disabled":true},{"key":"filter[supplier_id][equals]","value":"","description":"Numeric filter by supplier_id. Operators: equals, not_equals, greater_than, less_than, between","disabled":true},{"key":"filter[destination_warehouse_id][equals]","value":"","description":"Numeric filter by destination_warehouse_id","disabled":true},{"key":"filter[purchase_order_date][on_or_after]","value":"","description":"Date filter. Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty","disabled":true},{"key":"filter[total][greater_than]","value":"","description":"Numeric filter on total cost","disabled":true},{"key":"filter[logistics_<slug>_estimate][on_or_after]","value":"","description":"Date filter on a logistics tracking field estimate date. Replace &lt;slug> with the logistics field slug (e.g. logistics_port-arrived_estimate). Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, is.","disabled":true},{"key":"filter[logistics_<slug>_actual][on_or_before]","value":"","description":"Date filter on a logistics tracking field actual date (e.g. logistics_customs-cleared_actual). Same operators as the estimate filter.","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"GroupedFilterSupport tree root conjunction: and/or","disabled":true},{"key":"filter_groups[children][0][type]","value":"condition","description":"Filter tree node: condition or group","disabled":true}]},"description":"Paginated purchase order list for the list view. Uses Spatie QueryBuilder with advanced grouped filter support.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSupports both simple filters (filter[field]=value) and advanced grouped filter trees (filter_groups). The advanced system supports AND/OR conjunctions with nested groups.\n\nAvailable text filter columns: purchase_order_number, order_status, submission_status, confirmation_status (derived supplier-confirmation state; values: awaiting, confirmed, changes_requested, rejected), receipt_status, shipment_status, invoice_status, tracking_number, supplier_notes, submission_format, requested_shipping_method, po_type (standard/dropship/fba_inbound/awd_inbound), supplier_name, destination_warehouse_name, currency_code, payment_term, incoterm, shipping_method, supplier_email, supplier_po_email, supplier_company, supplier_contact, supplier_phone, supplier_address, supplier_city, supplier_province, supplier_zip, supplier_country, destination_email, destination_company, destination_phone, destination_address, destination_city, destination_province, destination_zip, destination_country, item_sku, item_name, item_nominal_code, item_supplier_sku, shipment_tracking, shipment_shipping_method, tag, invoice_number\n\nAvailable numeric filter columns: supplier_id, destination_warehouse_id, id, total_quantity, total, tax_cost, product_total, additional_cost, discount, line_item_count, item_quantity, item_price, item_received, item_tax_rate, shipment_quantity, shipment_received, irr, sell_through\n\nAvailable date filter columns: purchase_order_date, other_date, estimated_delivery_date, created_at, updated_at, fully_received_at, asn_last_sent_at, item_eta, shipment_date\n\nLogistics tracking date filter columns: `logistics_<slug>`_estimate, `logistics_<slug>`_actual — where &lt;slug> is the slug of any active LogisticsTrackingField (e.g. logistics_port-arrived_estimate, logistics_customs-cleared_actual). Each PO row in the response includes a logistics_tracking_field_values array with { slug, name, estimate_date, actual_date } entries for every active logistics tracking field configured for the tenant.\n\nThe irr and sell_through numeric filters match against the purchase order's annualized internal rate of return and sell-through, entered as whole percentages (e.g. irr greater_than 50 = an IRR above 50%, sell_through less_than 25 = under 25% sold through). They filter on the persisted product-variant return metrics; purchase orders without computed return metrics are excluded when either filter is used.\n\nReturn metrics (per PO, whole percentages; null until computed / not meaningful): `sell_through` = product-variant sell-through (units sold ÷ received × 100), `irr` = annualized internal rate of return (× 100). Filter on them with the `irr` / `sell_through` numeric filters above."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/list?page=1&per_page=15&sort=-created_at&filter[search]=PO-001&filter[archived]=&filter[asn_sent]=&filter[is_tax_included]=&filter[arriving_this_week]=&filter[overdue]=&filter[order_status][is]=open&filter[supplier_id][equals]=&filter[destination_warehouse_id][equals]=&filter[purchase_order_date][on_or_after]=&filter[total][greater_than]=&filter[logistics_<slug>_estimate][on_or_after]=&filter[logistics_<slug>_actual][on_or_before]=&filter_groups[conjunction]=and&filter_groups[children][0][type]=condition","host":["{{baseUrl}}"],"path":["api","purchase-orders","list"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field. Prefix - for descending. Allowed: id, purchase_order_number, purchase_order_date, other_date, order_status, submission_status, receipt_status, shipment_status, invoice_status, estimated_delivery_date, tracking_number, total, total_quantity, tax_total, supplier_notes, supplier_name, destination_warehouse_name, currency_code, product_total, additional_cost, discount, line_item_count, payment_term_name, incoterm_description, created_at, updated_at, fully_received_at, asn_last_sent_at, submission_format, requested_shipping_method, currency_rate","disabled":true},{"key":"filter[search]","value":"PO-001","description":"Full-text search across PO number (exact ID), tracking number, order status, submission format, supplier name, item SKU, invoice number","disabled":true},{"key":"filter[archived]","value":"","description":"Archival filter: omit=non-archived only, 'only'=archived only. Also supports advanced: filter[archived.is]=true","disabled":true},{"key":"filter[asn_sent]","value":"","description":"ASN sent filter: true/false","disabled":true},{"key":"filter[is_tax_included]","value":"","description":"Tax included filter: true/false","disabled":true},{"key":"filter[arriving_this_week]","value":"","description":"Arriving this week scope filter","disabled":true},{"key":"filter[overdue]","value":"","description":"Overdue scope filter","disabled":true},{"key":"filter[order_status][is]","value":"open","description":"Advanced text filter operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of","disabled":true},{"key":"filter[supplier_id][equals]","value":"","description":"Numeric filter by supplier_id. Operators: equals, not_equals, greater_than, less_than, between","disabled":true},{"key":"filter[destination_warehouse_id][equals]","value":"","description":"Numeric filter by destination_warehouse_id","disabled":true},{"key":"filter[purchase_order_date][on_or_after]","value":"","description":"Date filter. Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty","disabled":true},{"key":"filter[total][greater_than]","value":"","description":"Numeric filter on total cost","disabled":true},{"key":"filter[logistics_<slug>_estimate][on_or_after]","value":"","description":"Date filter on a logistics tracking field estimate date. Replace &lt;slug> with the logistics field slug (e.g. logistics_port-arrived_estimate). Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, is.","disabled":true},{"key":"filter[logistics_<slug>_actual][on_or_before]","value":"","description":"Date filter on a logistics tracking field actual date (e.g. logistics_customs-cleared_actual). Same operators as the estimate filter.","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"GroupedFilterSupport tree root conjunction: and/or","disabled":true},{"key":"filter_groups[children][0][type]","value":"condition","description":"Filter tree node: condition or group","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\",\n      \"purchase_order_date\": \"2024-01-15T00:00:00.000000Z\",\n      \"other_date\": null,\n      \"order_status\": \"open\",\n      \"submission_status\": \"sent\",\n      \"submission_blocked_no_email\": false,\n      \"receipt_status\": \"unreceived\",\n      \"shipment_status\": \"pending\",\n      \"invoice_status\": \"uninvoiced\",\n      \"submission_format\": \"email\",\n      \"is_tax_included\": false,\n      \"currency_rate\": 1,\n      \"supplier_name\": \"Acme Supplies\",\n      \"supplier_id\": 5,\n      \"destination_warehouse_name\": \"Main Warehouse\",\n      \"destination_warehouse_id\": 2,\n      \"estimated_delivery_date\": \"2024-02-01T00:00:00.000000Z\",\n      \"tracking_number\": null,\n      \"requested_shipping_method\": null,\n      \"total\": 1500,\n      \"total_quantity\": 100,\n      \"product_total\": 1500,\n      \"additional_cost\": 0,\n      \"tax_total\": 0,\n      \"discount\": 0,\n      \"sell_through\": 53.3,\n      \"irr\": 13.4,\n      \"currency_code\": \"USD\",\n      \"payment_term_name\": \"Net 30\",\n      \"incoterm_description\": null,\n      \"tags\": [],\n      \"supplier_notes\": null,\n      \"fully_received_at\": null,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"archived_at\": null,\n      \"is_dropship\": false,\n      \"po_type\": \"standard\",\n      \"line_item_count\": 3,\n      \"first_line_sku\": \"SKU-001\",\n      \"asn_last_sent_at\": null,\n      \"invoices\": [],\n      \"logistics_tracking_field_values\": [\n        {\n          \"slug\": \"port-arrived\",\n          \"name\": \"Port Arrived\",\n          \"estimate_date\": \"2026-06-01\",\n          \"actual_date\": \"2026-06-03\"\n        },\n        {\n          \"slug\": \"customs-cleared\",\n          \"name\": \"Customs Cleared\",\n          \"estimate_date\": \"2026-06-10\",\n          \"actual_date\": null\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 56,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Export Purchase Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/list/export?format=xlsx&content_mode=summary&scope=filtered&ids=&columns=id,purchase_order_number,supplier_name,order_status&sort=-created_at&filter[order_status][is]=","host":["{{baseUrl}}"],"path":["api","purchase-orders","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"Content mode: summary (one row per PO, default) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default), all, current_page, selected","disabled":true},{"key":"ids","value":"","description":"Comma-separated PO IDs (required when scope=selected)","disabled":true},{"key":"columns","value":"id,purchase_order_number,supplier_name,order_status","description":"Comma-separated column keys to export. Available: id, purchase_order_number, purchase_order_date, supplier_name, destination_warehouse_name, order_status, submission_status, receipt_status, shipment_status, invoice_status, estimated_delivery_date, tracking_number, total_quantity, product_total, additional_cost, tax_total, discount, total, currency_code, payment_term_name, incoterm_description, supplier_notes, tags, invoices, is_dropship, po_type, other_date, fully_received_at, asn_last_sent_at, created_at, updated_at, submission_format, is_tax_included, currency_rate, requested_shipping_method_name, supplier_email, supplier_po_email, supplier_company, supplier_contact, supplier_phone, supplier_address, supplier_city, supplier_province, supplier_country, destination_email, destination_company, destination_address, destination_city, destination_province, destination_country. Also accepts logistics tracking columns: `logistics_<slug>`_estimate and `logistics_<slug>`_actual for any active LogisticsTrackingField (e.g. logistics_port-arrived_estimate, logistics_customs-cleared_actual).","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field (same as list endpoint)","disabled":true},{"key":"filter[order_status][is]","value":"","description":"Filters carry over from list endpoint","disabled":true}]},"description":"Export purchase orders as XLSX or CSV. Supports summary (one row per PO) and line_items (one row per line item with PO fields repeated) modes.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download (XLSX or CSV).\n\nScope options:\n- filtered: Apply active filters (default)\n- all: Export all POs ignoring filters\n- current_page: Export current page only\n- selected: Export specific IDs (pass ids=1,2,3)\n\nLine item columns (always included in line_items mode): item_sku, item_barcode, item_name, item_description, item_quantity, item_received_qty, item_price, item_discount_rate, item_tax_rate, item_line_total, item_eta.\n\n**Requires permission:** `purchase_orders.export`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/list/export?format=xlsx&content_mode=summary&scope=filtered&ids=&columns=id,purchase_order_number,supplier_name,order_status&sort=-created_at&filter[order_status][is]=","host":["{{baseUrl}}"],"path":["api","purchase-orders","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx (default) or csv","disabled":true},{"key":"content_mode","value":"summary","description":"Content mode: summary (one row per PO, default) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Export scope: filtered (default), all, current_page, selected","disabled":true},{"key":"ids","value":"","description":"Comma-separated PO IDs (required when scope=selected)","disabled":true},{"key":"columns","value":"id,purchase_order_number,supplier_name,order_status","description":"Comma-separated column keys to export. Available: id, purchase_order_number, purchase_order_date, supplier_name, destination_warehouse_name, order_status, submission_status, receipt_status, shipment_status, invoice_status, estimated_delivery_date, tracking_number, total_quantity, product_total, additional_cost, tax_total, discount, total, currency_code, payment_term_name, incoterm_description, supplier_notes, tags, invoices, is_dropship, po_type, other_date, fully_received_at, asn_last_sent_at, created_at, updated_at, submission_format, is_tax_included, currency_rate, requested_shipping_method_name, supplier_email, supplier_po_email, supplier_company, supplier_contact, supplier_phone, supplier_address, supplier_city, supplier_province, supplier_country, destination_email, destination_company, destination_address, destination_city, destination_province, destination_country. Also accepts logistics tracking columns: `logistics_<slug>`_estimate and `logistics_<slug>`_actual for any active LogisticsTrackingField (e.g. logistics_port-arrived_estimate, logistics_customs-cleared_actual).","disabled":true},{"key":"sort","value":"-created_at","description":"Sort field (same as list endpoint)","disabled":true},{"key":"filter[order_status][is]","value":"","description":"Filters carry over from list endpoint","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(Binary XLSX file)"}]},{"name":"List Export Columns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/csv-columns","host":["{{baseUrl}}"],"path":["api","purchase-orders","csv-columns"]},"description":"Returns the master registry of supported PO email CSV columns and the tenant-wide default selection. Used by the per-supplier CSV column picker, the supplier preferences panel, and the PO settings page.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe registry is **append-only and position-stable** — column ordering and keys are part of a public contract that supplier intake pipelines rely on. Removing or renaming a key is a breaking change.\n\nResponse fields:\n- `data.columns[]` — array of `{ key, label }` in canonical order\n- `data.tenant_default` — array of column keys representing the tenant-wide default, or `null` if no override is set (means: use system default = every column)\n\nAuthentication: Requires Bearer token. Scope: `purchase-orders:rw`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/csv-columns","host":["{{baseUrl}}"],"path":["api","purchase-orders","csv-columns"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"columns\": [\n      {\n        \"key\": \"purchase_order\",\n        \"label\": \"Purchase Order\"\n      },\n      {\n        \"key\": \"sku\",\n        \"label\": \"SKU\"\n      },\n      {\n        \"key\": \"barcode\",\n        \"label\": \"Barcode\"\n      },\n      {\n        \"key\": \"supplier_sku\",\n        \"label\": \"Supplier SKU\"\n      },\n      {\n        \"key\": \"name\",\n        \"label\": \"Name\"\n      },\n      {\n        \"key\": \"qty_ordered\",\n        \"label\": \"Qty Ordered\"\n      },\n      {\n        \"key\": \"unit_cost\",\n        \"label\": \"Unit Cost\"\n      },\n      {\n        \"key\": \"extended_cost\",\n        \"label\": \"Extended Cost\"\n      }\n    ],\n    \"tenant_default\": null\n  }\n}"}]},{"name":"Get Purchase Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]},"description":"Get a single purchase order with all relations loaded: lines, products, inventory, shipments, receipts, invoices, bills, notes, financial lines, Amazon inbound data, and more.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"po_number\": \"PO-00101\",\n    \"purchase_order_date\": \"2024-01-15\",\n    \"other_date\": null,\n    \"payment_term_id\": 1,\n    \"payment_term\": \"Net 30\",\n    \"incoterm_id\": 4,\n    \"incoterm_place\": \"Shenzhen Port\",\n    \"incoterm_version\": 2020,\n    \"incoterm_code\": \"FOB\",\n    \"incoterm_display\": \"FOB Shenzhen Port, Incoterms 2020\",\n    \"importer_of_record\": \"Buyer\",\n    \"seller_must_insure\": false,\n    \"incoterm_description\": \"Sea and inland-waterway transport only. The seller clears the goods for export and loads them onto the vessel; risk passes once they are on board.\",\n    \"incoterm\": {\n      \"id\": 4,\n      \"code\": \"FOB\",\n      \"name\": \"Free On Board\",\n      \"transport_mode\": \"sea_inland\",\n      \"family\": \"F\",\n      \"seller_pays_main_carriage\": false,\n      \"export_cleared_by\": \"seller\",\n      \"import_cleared_by\": \"buyer\",\n      \"seller_insurance\": \"none\",\n      \"risk_transfer_point\": \"Goods on board the vessel at the named port of shipment.\",\n      \"is_standard\": true,\n      \"is_deprecated\": false,\n      \"sort_order\": 4\n    },\n    \"submission_format\": \"email\",\n    \"currency_id\": 1,\n    \"currency\": \"USD\",\n    \"currency_rate\": 1,\n    \"created_at\": \"2024-01-15T10:00:00Z\",\n    \"updated_at\": \"2024-01-15T10:00:00Z\",\n    \"created_by\": \"John Doe\",\n    \"last_updated_by\": \"Jane Smith\",\n    \"archived_at\": null,\n    \"is_dropship\": false,\n    \"is_supplier_pickup\": false,\n    \"expected_pickup_at\": null,\n    \"tracking_number\": null,\n    \"supplier_id\": 5,\n    \"supplier_name\": {\n      \"id\": 5,\n      \"name\": \"Acme Supplies\"\n    },\n    \"supplier_email\": \"orders@acme.com\",\n    \"destination_warehouse_id\": 2,\n    \"destination_warehouse_type\": \"standard\",\n    \"order_status\": \"open\",\n    \"submission_status\": \"sent\",\n    \"submission_blocked_no_email\": false,\n    \"receipt_status\": \"unreceived\",\n    \"resolution\": {\n      \"type\": \"inbound_shortage\",\n      \"label\": \"Inbound Shortage\",\n      \"quantity\": 16,\n      \"cost_impact\": 1002.94,\n      \"date\": \"2025-12-17\",\n      \"reference\": null\n    },\n    \"needs_shortfall_reconciliation\": false,\n    \"shipment_status\": \"pending\",\n    \"invoice_status\": \"uninvoiced\",\n    \"additional_cost\": 0,\n    \"discount\": 0,\n    \"product_total\": 1500,\n    \"total\": 1500,\n    \"subtotal\": 1500,\n    \"tax_cost\": 0,\n    \"is_tax_included\": false,\n    \"total_quantity\": 100,\n    \"supplier_notes\": null,\n    \"estimated_delivery_date\": \"2024-02-01\",\n    \"fully_received_at\": null,\n    \"tags\": [\n      \"urgent\"\n    ],\n    \"store_id\": 1,\n    \"items\": [\n      {\n        \"id\": 201,\n        \"product_id\": 10,\n        \"description\": \"Widget A\",\n        \"quantity\": 100,\n        \"amount\": 15,\n        \"received_quantity\": 0\n      }\n    ],\n    \"summary_info\": {\n      \"total_lines\": 1,\n      \"total_product_lines\": 1,\n      \"total_units\": 100,\n      \"total_quantity_pending_receipt\": 100\n    },\n    \"financial_lines\": [],\n    \"bills\": [],\n    \"invoices\": [],\n    \"amazon_pending_inbound\": null,\n    \"has_active_allocations\": false,\n    \"walmart_wfs_inbound_shipment\": null,\n    \"settlement_summary\": {\n      \"total_product_lines\": 3,\n      \"matched\": 1,\n      \"credited\": 1,\n      \"settled\": 1,\n      \"outstanding\": 0,\n      \"outstanding_quantity\": 0,\n      \"credited_quantity\": 5,\n      \"credit_sources\": [\n        {\n          \"vendor_credit_id\": 42,\n          \"vendor_credit_number\": \"VC-1001\",\n          \"quantity\": 5,\n          \"credit_status\": \"open\",\n          \"restock_inventory\": false\n        }\n      ]\n    },\n    \"is_outsourced_manufacturing\": false,\n    \"manufacturing_order_id\": null\n  }\n}"}]},{"name":"Update Purchase Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]},"description":"Update an existing purchase order. All fields are optional (sometimes).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNote: Updates acquire a Redis lock to serialize concurrent edits to the same PO. The request blocks for up to 10 seconds waiting for the lock; if the lock still cannot be acquired it returns 409 Conflict.\n\nUpdate-only fields:\n- po_number: alias for purchase_order_number\n- purchase_order_lines[].id: ID of existing line to update (omit line from array to delete it)\n- financial_lines[].id: ID of existing financial line to update\n\nCannot reduce line quantity below received or invoiced quantity.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"purchase_order_date\": \"2024-01-15\",\n  \"estimated_delivery_date\": \"2024-02-15\",\n  \"supplier_notes\": \"Updated notes\",\n  \"tracking_number\": \"TRACK123\",\n  \"approval_status\": \"approved\",\n  \"tags\": [\n    \"urgent\",\n    \"priority\"\n  ],\n  \"purchase_order_lines\": [\n    {\n      \"id\": 201,\n      \"product_id\": 10,\n      \"quantity\": 120,\n      \"amount\": 14.5\n    }\n  ],\n  \"incoterm_id\": 12,\n  \"incoterm_place\": \"Port of Los Angeles, CA\",\n  \"incoterm_version\": 2020\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"po_number\": \"PO-00101\",\n    \"order_status\": \"open\",\n    \"total\": 1740\n  },\n  \"message\": \"Purchase order PO-00101 updated successfully\"\n}"}]},{"name":"Delete Purchase Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]},"description":"Delete a single purchase order. Fails with 400 if the PO has invoices (delete the invoices first) or has received inventory that has been used in FIFO layers.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order"],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase order PO-00101 deleted successfully\"\n}"}]},{"name":"Bulk Approve Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/approve","host":["{{baseUrl}}"],"path":["api","purchase-orders","approve"]},"description":"Bulk approve purchase orders by IDs or filters.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns warnings if some POs fail to approve, error if all fail.\n\nBody:\n- ids[]: Array of purchase order IDs (required without filters)\n- filters: Spatie filter params to resolve IDs (required without ids)\n\n**Requires permission:** `purchase_orders.approve`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/approve","host":["{{baseUrl}}"],"path":["api","purchase-orders","approve"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    [\n      101,\n      102,\n      103\n    ]\n  ],\n  \"message\": \"Purchase orders approved successfully\"\n}"}]},{"name":"Bulk Submit Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/submit","host":["{{baseUrl}}"],"path":["api","purchase-orders","submit"]},"description":"Bulk submit (send to supplier) purchase orders.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids[]: Array of purchase order IDs (required without filters)\n- filters: Spatie filter params (required without ids)\n\n**Requires permission:** `purchase_orders.approve`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/submit","host":["{{baseUrl}}"],"path":["api","purchase-orders","submit"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase orders submitted successfully\"\n}"}]},{"name":"Bulk Archive Purchase Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/archive","host":["{{baseUrl}}"],"path":["api","purchase-orders","archive"]},"description":"Bulk archive purchase orders.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/archive","host":["{{baseUrl}}"],"path":["api","purchase-orders","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase orders archived successfully\"\n}"}]},{"name":"Bulk Unarchive Purchase Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/unarchive","host":["{{baseUrl}}"],"path":["api","purchase-orders","unarchive"]},"description":"Bulk unarchive purchase orders.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/unarchive","host":["{{baseUrl}}"],"path":["api","purchase-orders","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase orders unarchived successfully\"\n}"}]},{"name":"Check Purchase Orders Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/deletable","host":["{{baseUrl}}"],"path":["api","purchase-orders","deletable"]},"description":"Check whether each purchase order can be deleted. Returns a list with deletable flag and reason if not.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids[]: Required array of integer purchase order IDs (min:1, each must exist)\n\n**Requires permission:** `purchase_orders.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/deletable","host":["{{baseUrl}}"],"path":["api","purchase-orders","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\",\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 102,\n      \"purchase_order_number\": \"PO-00102\",\n      \"deletable\": false,\n      \"reason\": {\n        \"usedFifoLayers\": \"Purchase order PO-00102 has used FIFO layers in its lines and cannot be deleted.\"\n      }\n    }\n  ]\n}"}]},{"name":"Submit PO to Supplier","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/submit","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","submit"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Submit (send) a draft purchase order to the supplier. Triggers PO sent notification.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.approve` Optionally include supplier_message to set the vendor-facing note (saved before the PO is emailed); omit it to keep the saved message, or send an empty string to clear it.","body":{"mode":"raw","raw":"{\n  \"supplier_message\": \"Please ship in original cartons.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/submit","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","submit"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"submission_status\": \"sent\"\n  },\n  \"message\": \"Purchase order PO-00101 submitted to supplier\"\n}"}]},{"name":"Close Purchase Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/close","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","close"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Manually close an open purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- reason (optional, string, max:500): Reason for closing\n\n**Requires permission:** `purchase_orders.cancel`","body":{"mode":"raw","raw":"{\n  \"reason\": \"Fulfilled by alternate means\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/close","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","close"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"order_status\": \"closed\"\n  },\n  \"message\": \"Purchase order closed.\"\n}"}]},{"name":"Reopen Purchase Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/reopen","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","reopen"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Reopen a closed purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.cancel`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/reopen","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","reopen"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"order_status\": \"open\"\n  },\n  \"message\": \"Purchase order reopened.\"\n}"}]},{"name":"Duplicate Purchase Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/duplicate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","duplicate"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Duplicate a purchase order (creates a new draft with the same lines).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.create`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/duplicate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","duplicate"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 200,\n    \"po_number\": \"PO-00200\",\n    \"order_status\": \"draft\"\n  },\n  \"message\": \"Purchase order duplicated successfully\"\n}"}]},{"name":"Cover Backorders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/cover-backorders","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","cover-backorders"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Sync inventory allocation coverages for all lines in this purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/cover-backorders","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","cover-backorders"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated backorder coverage\"\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","generate-accounting-transaction"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Generate (or regenerate) the accounting transaction for a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","generate-accounting-transaction"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"status\": \"draft\",\n    \"total\": 1500,\n    \"reference\": \"PO-00101\",\n    \"transaction_date\": \"2024-01-15T00:00:00Z\",\n    \"type\": \"purchase_order\"\n  },\n  \"message\": \"Accounting transaction generated successfully.\"\n}"}]},{"name":"Create Receiving Discrepancy","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receiving-discrepancy","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receiving-discrepancy"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Create an accounting transaction for the receiving discrepancy on this purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFails if nominal code mapping is missing or a discrepancy already exists.\n\n**Requires permission:** `purchase_orders.receive`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receiving-discrepancy","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receiving-discrepancy"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully closed with receiving discrepancy\"\n}"}]},{"name":"Undo Receiving Discrepancy","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receiving-discrepancy/undo","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receiving-discrepancy","undo"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"}]},"description":"Reverse a previous \"close with receiving discrepancy\" on a purchase order. No request body.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWhat it does (all in one transaction, synchronous):\n- deletes the discrepancy accounting entry and its lines\n- reopens the purchase order (`order_status: open`) and recomputes its receipt status from actual received quantities (it may land on `partially_received`, `unreceived`, or auto-close again as `received` if everything was in fact received)\n\nErrors:\n- 404 — the purchase order has no receiving discrepancy to undo\n- 400 — the discrepancy has already been posted to your accounting provider; it cannot be undone and a reversing entry must be made manually\n\nRequires the `purchase-orders:write` token scope and receiving permission on purchase orders."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receiving-discrepancy/undo","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receiving-discrepancy","undo"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully undone close with receiving discrepancy\",\n  \"status\": \"success\"\n}"}]},{"name":"Mark as Opening-Balance Purchase Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/opening-balance","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","opening-balance"],"variable":[{"key":"purchase_order","value":"682","description":"Purchase order ID"}]},"description":"Mark a purchase order as an opening-balance (\"transition\") order. Use this for a purchase order whose stock was received before your inventory start date, so it was loaded as an opening balance rather than as tracked receipts. No request body.\n\nWhat it does (synchronous):\n- closes the purchase order as fully received with no receiving loss, regardless of how many units the tracked ledger shows\n- stops its receipt status from later recomputing back to partially/unreceived off the (empty) ledger\n- its pre-inventory-start invoices are treated as opening balances and are not posted to your accounting provider (posting them would double-count the balances loaded at go-live)\n\nRequires the `purchase-orders:write` token scope and receiving permission on purchase orders."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/opening-balance","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","opening-balance"],"variable":[{"key":"purchase_order","value":"682","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Marked as an opening-balance purchase order\",\n  \"status\": \"success\"\n}"}]},{"name":"Remove Opening-Balance Mark","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/opening-balance","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","opening-balance"],"variable":[{"key":"purchase_order","value":"682","description":"Purchase order ID"}]},"description":"Remove the opening-balance mark from a purchase order and reopen it so its receipt status recomputes normally from actual received quantities. No request body.\n\nRequires the `purchase-orders:write` token scope and receiving permission on purchase orders."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/opening-balance","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","opening-balance"],"variable":[{"key":"purchase_order","value":"682","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Removed the opening-balance mark\",\n  \"status\": \"success\"\n}"}]},{"name":"Get PO Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines?page=1&limit=10","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page (default 10). -1 returns ALL lines un-paginated (vendor-credit / lookup callers)","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]},"description":"Purchase order lines for the PO grid (POGridView), plus the vendor-credit / lookup callers that pass limit=-1 to fetch every line. Includes per-line COGS breakdown data.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nCanonical params (the legacy table_specifications flag has been removed):\n- query — search across line description, product SKU, product barcode\n- filter[receipt_status] — fully_received / partially_received / not_received / not_fully_received\n- filter[shipment_status] — fully_shipped / partially_shipped / not_shipped\n- page / limit / total — pagination (limit=-1 returns ALL rows, un-paginated; the response is then a plain resource collection without pagination meta)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines?page=1&limit=10","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"10","description":"Items per page (default 10). -1 returns ALL lines un-paginated (vendor-credit / lookup callers)","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"quantity\": 100,\n      \"sku\": {\n        \"id\": 10,\n        \"sku\": \"SKU-001\"\n      },\n      \"barcode\": 123456789012,\n      \"name\": \"Widget A\",\n      \"price\": 15,\n      \"received\": 25,\n      \"shipped_quantity\": 25,\n      \"invoiced_quantity\": 0,\n      \"unfulfilled_quantity\": 75\n    }\n  ],\n  \"links\": {\n    \"first\": \"https://example.sku.io/api/purchase-orders/101/lines?page=1\",\n    \"last\": null,\n    \"prev\": null,\n    \"next\": \"https://example.sku.io/api/purchase-orders/101/lines?page=2\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"path\": \"https://example.sku.io/api/purchase-orders/101/lines\",\n    \"per_page\": 10,\n    \"to\": 10\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Get PO Lines for Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines-for-invoice","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines-for-invoice"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get purchase order lines optimised for invoice creation. Returns only essential invoice-relevant fields with minimal N+1 overhead.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines-for-invoice","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines-for-invoice"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"product_id\": 10,\n      \"description\": \"Widget A\",\n      \"quantity\": 100,\n      \"received_quantity\": 0,\n      \"amount\": 15,\n      \"discount_rate\": 0\n    }\n  ]\n}"}]},{"name":"Get PO Lines for Receiving","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines-for-receiving","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines-for-receiving"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Lean endpoint for the Receive drawer. Returns only the 8 fields the UI consumes (id, sku, name, barcode, img_url, quantity, received) — no COGS, no allocations, no inventory snapshots, no resource transformation.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFor POs with ~1000 lines this is ~9× faster than `/lines` (~100ms vs ~900ms) and returns ~5× smaller payloads.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/lines-for-receiving","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","lines-for-receiving"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"sku\": {\n        \"id\": 10,\n        \"sku\": \"WIDGET-A\"\n      },\n      \"name\": \"Widget A\",\n      \"barcode\": 123456789012,\n      \"img_url\": \"https://cdn.sku.io/products/10/primary.jpg\",\n      \"quantity\": 100,\n      \"received\": 0\n    }\n  ]\n}"}]},{"name":"Get PO Shipment Line Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/shipment-line-options","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","shipment-line-options"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Lines for the Create Shipment / Add to Existing Shipment pickers on the PO Shipments tab.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns every unreceived line on the PO with server-computed `assigned_quantity` (units already claimed by live inbound shipments — InTransit, PartiallyReceived, Received) and `available_quantity` (what the user can still add). Draft, Cancelled, and Closed shipments do NOT count toward `assigned_quantity`.\n\nFully-received lines (effective_received >= quantity) are excluded. AWD / FBA receipts are honoured via `getEffectiveReceivedQuantity` so received quantity is correct even when the `received_quantity` column is not directly updated.\n\nThere is intentionally no pagination cap — a single PO can have hundreds of lines and silent truncation hid line items from users (Freshdesk #1892).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/shipment-line-options","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","shipment-line-options"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 201,\n      \"product_id\": 10,\n      \"sku\": \"WIDGET-A\",\n      \"product_name\": \"Widget A\",\n      \"img_url\": \"https://cdn.sku.io/products/10/primary.jpg\",\n      \"ordered_quantity\": 100,\n      \"received_quantity\": 0,\n      \"unreceived_quantity\": 100,\n      \"assigned_quantity\": 40,\n      \"available_quantity\": 60,\n      \"already_on_shipment\": true\n    },\n    {\n      \"purchase_order_line_id\": 202,\n      \"product_id\": 11,\n      \"sku\": \"WIDGET-B\",\n      \"product_name\": \"Widget B\",\n      \"img_url\": null,\n      \"ordered_quantity\": 50,\n      \"received_quantity\": 0,\n      \"unreceived_quantity\": 50,\n      \"assigned_quantity\": 0,\n      \"available_quantity\": 50,\n      \"already_on_shipment\": false\n    }\n  ]\n}"}]},{"name":"Get PO Line Items (Lightweight)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/line-items","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","line-items"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Lightweight line items for the expandable row in the list view. Returns id, product SKU, barcode, product_name, quantity, received_quantity, amount, discount_rate, and line_total.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/line-items","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","line-items"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"sku\": \"SKU-001\",\n      \"barcode\": 123456789012,\n      \"product_name\": \"Widget A\",\n      \"product_id\": 10,\n      \"quantity\": 100,\n      \"received_quantity\": 0,\n      \"amount\": 15,\n      \"discount_rate\": 0,\n      \"line_total\": 1500\n    }\n  ]\n}"}]},{"name":"Import Lines from CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import-lines","host":["{{baseUrl}}"],"path":["api","purchase-orders","import-lines"]},"description":"Import purchase order line items from a CSV file. CSV must have a 'sku' column. Optional columns: quantity, unit_cost, description, discount_rate, tax_rate_id, pricing_tier, barcode.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIf purchase_order_id is provided, lines are added/merged into that PO.\nIf only supplier_id is provided, returns parsed line resources without saving.\n\n**Requires permission:** `purchase_orders.import`","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"csvString","type":"text","value":""},{"key":"purchase_order_id","type":"text","value":""},{"key":"supplier_id","type":"text","value":""},{"key":"replace","type":"text","value":""},{"key":"separator","type":"text","value":""},{"key":"escape","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/import-lines","host":["{{baseUrl}}"],"path":["api","purchase-orders","import-lines"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase order lines imported successfully\"\n}"}]},{"name":"Download Lines Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import-lines/template","host":["{{baseUrl}}"],"path":["api","purchase-orders","import-lines","template"]},"description":"Download an XLSX import template for PO line items with headers (sku, quantity, unit_cost) and sample data.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary XLSX file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/import-lines/template","host":["{{baseUrl}}"],"path":["api","purchase-orders","import-lines","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(Binary XLSX file)"}]},{"name":"Apply Discount Rate to Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-discount-rate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-discount-rate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]},"description":"Apply a discount rate to all lines of a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- discount (required, numeric, min:0, max:100): Discount percentage (e.g. 10 = 10%)\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"discount\": 10\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-discount-rate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-discount-rate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"po_number\": \"PO-00101\"\n  },\n  \"message\": \"Discount rate successfully applied.\"\n}"}]},{"name":"Apply Pricing Tier to Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-pricing-tier/{supplierPricingTier}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-pricing-tier",":supplierPricingTier"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."},{"key":"supplierPricingTier","value":"3","description":"The supplier pricing tier ID."}]},"description":"Apply a supplier pricing tier to all (or specified) lines of a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody (optional):\n- line_ids[]: Array of specific line IDs to apply pricing to. If omitted, applies to all lines.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    201,\n    202\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-pricing-tier/{supplierPricingTier}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-pricing-tier",":supplierPricingTier"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."},{"key":"supplierPricingTier","value":"3","description":"The supplier pricing tier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101\n  },\n  \"message\": \"Pricing tier successfully applied.\"\n}"}]},{"name":"Apply Tax Rate to Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-tax-rate/{taxRate}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-tax-rate",":taxRate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."},{"key":"taxRate","value":"2","description":"The tax rate ID."}]},"description":"Apply a tax rate to all lines of a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- include_cost_lines (boolean, default false): Whether to also apply to non-product (cost) lines\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"include_cost_lines\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/apply-tax-rate/{taxRate}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","apply-tax-rate",":taxRate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."},{"key":"taxRate","value":"2","description":"The tax rate ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101\n  },\n  \"message\": \"Tax rate successfully applied to all lines.\"\n}"}]},{"name":"Clear Tax Rate from Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/clear-tax-rate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","clear-tax-rate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]},"description":"Clear tax rates from all lines of a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- include_cost_lines (boolean, default false): Whether to also clear from non-product (cost) lines\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"include_cost_lines\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/clear-tax-rate","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","clear-tax-rate"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101\n  },\n  \"message\": \"Tax rates cleared from all lines.\"\n}"}]},{"name":"Update PO Line","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to update"}]},"description":"Update a single purchase order line. Designed for the PO grid's inline-edit interactions (tax rate, quantity, unit cost, discount, description, FOC toggle, nominal code).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nConcurrency: Shares the per-PO Redis lock used by `PATCH /api/purchase-orders/:purchase_order` so concurrent edits on the same purchase order serialize rather than collide. The endpoint will wait up to 10 seconds for the lock; if it cannot acquire it, returns 409.\n\nRequest body (all fields optional — only sent fields are touched):\n- `quantity` (numeric, min 0, < 10000000): new ordered quantity. Validated against `received_quantity` and `invoice_total` — cannot drop below either.\n- `amount` (numeric, min 0, < 10000000): unit cost.\n- `description` (nullable string, max 255): free-text override for the product name on this line.\n- `tax_rate_id` (nullable integer, exists in `tax_rates`): set or clear the tax rate. When cleared, `tax_allocation` is reset to 0.\n- `discount` (nullable numeric, 0–100): percentage discount. Stored as `discount_rate` (e.g. 25 → 0.25).\n- `nominal_code_id` (nullable integer, exists in `nominal_codes`).\n- `is_free_of_charge` (boolean): toggle the FOC flag.\n- `free_of_charge_reason` (nullable enum, required when `is_free_of_charge=true`): one of the `FreeOfChargeReasonEnum` cases.\n\nSide effects:\n- Recomputes `tax_allocation` whenever the tax rate or any subtotal input (quantity/amount/discount) changes.\n- Recomputes the parent PO's `total_cost` and `total_quantity`.\n- Refreshes the PO's `receipt_status` when the quantity changes.\n- When the quantity is reduced, excess awaiting-receipt inventory allocations on this line are reverted so the next coverage sync can rebalance them.\n\nReturns the refreshed purchase order line object.","body":{"mode":"raw","raw":"{\n  \"quantity\": 12,\n  \"amount\": 9.95,\n  \"description\": \"Optional override of the line description\",\n  \"tax_rate_id\": 5,\n  \"discount\": 10,\n  \"nominal_code_id\": 42,\n  \"is_free_of_charge\": false,\n  \"free_of_charge_reason\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to update"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"quantity\": 12,\n    \"sku\": {\n      \"id\": 4421,\n      \"sku\": \"ACME-WIDGET-BLU\"\n    },\n    \"barcode\": \"5012345678900\",\n    \"sales_channel_unique_id\": null,\n    \"is_variation\": false,\n    \"img_url\": null,\n    \"supplier_sku\": \"SUP-WIDGET-001\",\n    \"supplier_product_id\": 882,\n    \"price\": 9.95,\n    \"is_free_of_charge\": false,\n    \"free_of_charge_reason\": null,\n    \"free_of_charge_reason_label\": null,\n    \"name\": \"Acme Widget, Blue\",\n    \"nominal_code_id\": 42,\n    \"nominal_code\": \"Cost of Goods Sold\",\n    \"nominal_code_code\": \"5000\",\n    \"received\": 0,\n    \"effective_ordered\": 12,\n    \"invoiced_quantity\": null,\n    \"uninvoiced_quantity\": null,\n    \"unfulfilled_quantity\": null,\n    \"shipped_quantity\": null,\n    \"weight\": 1.2,\n    \"weight_unit\": \"kg\",\n    \"length\": null,\n    \"width\": null,\n    \"height\": null,\n    \"dimension_unit\": null,\n    \"tax_rate\": 20,\n    \"tax_rate_id\": 5,\n    \"tax_rate_name\": \"Standard 20%\",\n    \"tax_allocation\": 21.49,\n    \"discount\": 10,\n    \"discount_rate\": 0.1,\n    \"discount_amount\": 0.995,\n    \"discount_amount_extended\": 11.94,\n    \"item_tax_value\": 21.49,\n    \"line_total\": 128.94,\n    \"created_at\": \"2026-05-10T14:22:01.000000Z\",\n    \"updated_at\": \"2026-05-21T09:31:44.000000Z\"\n  }\n}"}]},{"name":"Short-Close PO Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}/short-close","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line","short-close"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to short-close"}]},"description":"Short-close a PO line at a smaller `closed_quantity` than originally ordered. Records an audit event (PurchaseOrderLineShortCloseEvent) and mutates the line's `quantity` to the new effective ordered amount. The line's own `save` propagates the change into demand-planning coverages.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- `closed_quantity` (required, numeric, min 0): the new effective ordered quantity. Must be less than the original ordered quantity AND greater than or equal to the already-received quantity.\n- `reason` (optional, nullable, max 500): free-text reason for the short-close, recorded on the event.\n\nValidation rules (422):\n- A PO line can only have one active short-close at a time — undo the existing one first.\n- `closed_quantity` must be less than the original ordered quantity.\n- `closed_quantity` cannot be less than the already-received quantity.\n\nReturns the created PurchaseOrderLineShortCloseEvent (eager-loaded with `closedBy` and `followUpPurchaseOrder`).","body":{"mode":"raw","raw":"{\n  \"closed_quantity\": 89,\n  \"reason\": \"Supplier short-shipped; closing line at received qty and creating a follow-up PO.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}/short-close","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line","short-close"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to short-close"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"purchase_order_line_id\": 101,\n    \"original_quantity\": 91,\n    \"closed_quantity\": 89,\n    \"released_quantity\": 2,\n    \"reason\": \"Supplier short-shipped; closing line at received qty and creating a follow-up PO.\",\n    \"closed_at\": \"2026-05-14T10:30:00.000000Z\",\n    \"closed_by\": {\n      \"id\": 3,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"follow_up_purchase_order\": null,\n    \"undone_at\": null,\n    \"undone_by\": null,\n    \"is_active\": true\n  }\n}"}]},{"name":"Undo Short-Close","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-line-short-close-events/{short_close_event}","host":["{{baseUrl}}"],"path":["api","purchase-order-line-short-close-events",":short_close_event"],"variable":[{"key":"short_close_event","value":"55","description":"Short-close event ID to reverse"}]},"description":"Reverse a prior short-close event, restoring the PO line's original ordered quantity.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe event is marked as undone (with `undone_at` / `undone_by`) rather than deleted, preserving the audit trail. The associated PurchaseOrderLine's `quantity` is restored to its `original_quantity` from the event.\n\nValidation errors (422):\n- The event must currently be active. Re-reversing an already-undone event is rejected.\n\nReturns the updated PurchaseOrderLineShortCloseEvent (now with `is_active: false`, eager-loaded with `closedBy`, `undoneBy`, and `followUpPurchaseOrder`)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-order-line-short-close-events/{short_close_event}","host":["{{baseUrl}}"],"path":["api","purchase-order-line-short-close-events",":short_close_event"],"variable":[{"key":"short_close_event","value":"55","description":"Short-close event ID to reverse"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"purchase_order_line_id\": 101,\n    \"original_quantity\": 91,\n    \"closed_quantity\": 89,\n    \"released_quantity\": 2,\n    \"reason\": \"Supplier short-shipped; closing line at received qty and creating a follow-up PO.\",\n    \"closed_at\": \"2026-05-14T10:30:00.000000Z\",\n    \"closed_by\": {\n      \"id\": 3,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"follow_up_purchase_order\": null,\n    \"undone_at\": \"2026-05-14T11:45:00.000000Z\",\n    \"undone_by\": {\n      \"id\": 3,\n      \"name\": \"Kalvin Mizzi\"\n    },\n    \"is_active\": false\n  }\n}"}]},{"name":"Settle PO Line Billing (Final Invoice)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}/settle-billing","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line","settle-billing"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to mark billing-settled"}]},"description":"Mark a PO line as billing-settled — the SAP EREKZ \"final invoice\" axis. A billing-settled line counts as fully invoiced for reconciliation regardless of any residual short-billed quantity; use it when the supplier confirms this is the final bill for the line even though it was under-billed.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires the `purchase_orders.update` permission.\n\nRequest body fields:\n- `reason` (optional, nullable, string, max 500): free-text note recorded on the settlement and shown in the audit trail.\n\nStamps `billing_settled_at`, `billing_settled_reason`, and `billing_settled_by` (the acting user) on the line, then re-derives the parent purchase order's `invoice_status`.\n\nValidation errors (422, DomainException): returned when the line cannot be settled — e.g. it is already billing-settled, or it is already fully invoiced through quantity/credit so settlement is unnecessary.\n\nReturns the updated PurchaseOrderLine billing-settlement view (eager-loaded with `billingSettledBy` and `purchaseOrder`).","body":{"mode":"raw","raw":"{\n  \"reason\": \"SAP EREKZ final-invoice indicator received; treat line as fully billed despite short-billed residual.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-order-lines/{purchase_order_line}/settle-billing","host":["{{baseUrl}}"],"path":["api","purchase-order-lines",":purchase_order_line","settle-billing"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID to mark billing-settled"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 101,\n  \"billing_settled_at\": \"2026-07-07T14:20:00.000000Z\",\n  \"billing_settled_reason\": \"SAP EREKZ final-invoice indicator received; treat line as fully billed despite short-billed residual.\",\n  \"billing_settled_by\": {\n    \"id\": 3,\n    \"name\": \"Kalvin Mizzi\"\n  },\n  \"fully_invoiced\": true,\n  \"purchase_order\": {\n    \"id\": 715,\n    \"invoice_status\": \"invoiced\",\n    \"fully_invoiced\": true\n  }\n}"}]},{"name":"Unsettle PO Line Billing","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-line-billing-settlements/{purchase_order_line}","host":["{{baseUrl}}"],"path":["api","purchase-order-line-billing-settlements",":purchase_order_line"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID whose billing settlement to clear"}]},"description":"Reverse a prior billing settlement on a PO line, clearing the SAP EREKZ \"final invoice\" flag. The line reverts to normal quantity/credit reconciliation, so it may flip back to partially-invoiced if it was short-billed.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires the `purchase_orders.update` permission.\n\nClears `billing_settled_at`, `billing_settled_reason`, and `billing_settled_by` on the line, then re-derives the parent purchase order's `invoice_status`.\n\nValidation errors (422, DomainException): returned when the line is not currently billing-settled.\n\nReturns the updated PurchaseOrderLine billing-settlement view (eager-loaded with `billingSettledBy` and `purchaseOrder`)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-order-line-billing-settlements/{purchase_order_line}","host":["{{baseUrl}}"],"path":["api","purchase-order-line-billing-settlements",":purchase_order_line"],"variable":[{"key":"purchase_order_line","value":"101","description":"Purchase order line ID whose billing settlement to clear"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 101,\n  \"billing_settled_at\": null,\n  \"billing_settled_reason\": null,\n  \"billing_settled_by\": null,\n  \"fully_invoiced\": false,\n  \"purchase_order\": {\n    \"id\": 715,\n    \"invoice_status\": \"partially_invoiced\",\n    \"fully_invoiced\": false\n  }\n}"}]},{"name":"Settle Whole PO Billing (Final Invoice)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/settle-billing","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","settle-billing"],"variable":[{"key":"purchase_order","value":"715","description":"Purchase order ID whose eligible lines to bulk billing-settle"}]},"description":"Bulk-settle the billing axis for every eligible line on a purchase order in one call — the whole-PO equivalent of the per-line settle endpoint. Each still-open, short-billed line is stamped billing-settled; lines already fully invoiced or already settled are left untouched.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Requires the `purchase_orders.update` permission.\n\nRequest body fields:\n- `reason` (optional, nullable, string, max 500): free-text note recorded on every line settled by this call.\n\nAfter settling, the purchase order's `invoice_status` is re-derived and returned.\n\nResponse fields:\n- `settled_count`: number of lines newly billing-settled by this call.\n- `purchase_order`: `{ id, invoice_status, fully_invoiced }` after re-derivation.\n- `lines[]`: the billing-settlement view of each line that was settled (each eager-loaded with `billingSettledBy` and `purchaseOrder`).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Final invoice received for the whole PO; settle all short-billed lines.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/settle-billing","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","settle-billing"],"variable":[{"key":"purchase_order","value":"715","description":"Purchase order ID whose eligible lines to bulk billing-settle"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"settled_count\": 2,\n  \"purchase_order\": {\n    \"id\": 715,\n    \"invoice_status\": \"invoiced\",\n    \"fully_invoiced\": true\n  },\n  \"lines\": [\n    {\n      \"id\": 101,\n      \"billing_settled_at\": \"2026-07-07T14:20:00.000000Z\",\n      \"billing_settled_reason\": \"Final invoice received for the whole PO; settle all short-billed lines.\",\n      \"billing_settled_by\": {\n        \"id\": 3,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"fully_invoiced\": true,\n      \"purchase_order\": {\n        \"id\": 715,\n        \"invoice_status\": \"invoiced\",\n        \"fully_invoiced\": true\n      }\n    },\n    {\n      \"id\": 102,\n      \"billing_settled_at\": \"2026-07-07T14:20:00.000000Z\",\n      \"billing_settled_reason\": \"Final invoice received for the whole PO; settle all short-billed lines.\",\n      \"billing_settled_by\": {\n        \"id\": 3,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"fully_invoiced\": true,\n      \"purchase_order\": {\n        \"id\": 715,\n        \"invoice_status\": \"invoiced\",\n        \"fully_invoiced\": true\n      }\n    }\n  ]\n}"}]},{"name":"Reorder Purchase Order Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/lines/reorder","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","lines","reorder"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]},"description":"Persist a new top-to-bottom ordering for a purchase order's lines.\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ordered_ids (required, integer array): purchase order line ids in the desired order. A partial list is allowed — any line not listed keeps its relative order after the listed set. Every id must belong to this purchase order (otherwise 422).\n\nReturns the resulting line ids in their new order under data.ids.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"ordered_ids\": [\n    305,\n    304,\n    306\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/lines/reorder","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","lines","reorder"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ids\": [\n      305,\n      304,\n      306\n    ]\n  }\n}"}]},{"name":"Get PO Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receipts","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receipts"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get all shipment receipts for a purchase order.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receipts","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receipts"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 301,\n      \"inbound_shipment_id\": 401,\n      \"warehouse_id\": 3,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"East Coast Fulfillment\"\n      },\n      \"received_at\": \"2024-02-05T14:00:00Z\",\n      \"notes\": \"Pallet 2 of 3 received\",\n      \"received_by\": {\n        \"id\": 12,\n        \"name\": \"Dana Receiving\"\n      },\n      \"inbound_shipment_receipt_lines\": [\n        {\n          \"id\": 501,\n          \"purchase_order_line_id\": 601,\n          \"quantity\": 100\n        }\n      ],\n      \"purchase_orders\": [\n        {\n          \"id\": 88,\n          \"purchase_order_number\": \"PO-000088\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Single PO Receipt","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receipts",":receipt"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]},"description":"Get a single receipt for a purchase order.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- purchase_order: Purchase order ID\n- receipt: InboundShipmentReceipt (ISR) ID — this is the canonical wire id since Phase 4.4g.6a (the same id returned by `/api/purchase-orders/{po}/receipts`).\n\nReturns the canonical InboundShipmentReceipt with `inbound_shipment_receipt_lines`; line `id`s within that array are InboundShipmentReceiptLine (ISRL) ids."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","receipts",":receipt"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9001,\n    \"received_at\": \"2024-02-05T14:00:00Z\",\n    \"fulfilled_by\": {\n      \"id\": 1,\n      \"name\": \"Jane Smith\"\n    },\n    \"inbound_shipment_receipt_lines\": [\n      {\n        \"id\": 8101,\n        \"quantity\": 10,\n        \"purchase_order_line\": {\n          \"id\": 501,\n          \"product\": {\n            \"id\": 42,\n            \"sku\": \"WIDGET-001\",\n            \"supplier_sku\": \"SUP-WIDG-001\"\n          },\n          \"description\": \"Widget\",\n          \"received_quantity\": 10,\n          \"quantity\": 25\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Get Dropship Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/dropship-shipments","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","dropship-shipments"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get dropship fulfillment shipments for a dropship purchase order. Returns empty array for non-dropship POs.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/dropship-shipments","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","dropship-shipments"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 700,\n      \"warehouse_id\": 3,\n      \"tracking_number\": \"TRACK456\",\n      \"sales_order_fulfillment_lines\": []\n    }\n  ]\n}"}]},{"name":"Mark as Shipped (FBA/AWD)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","mark-as-shipped"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Mark an FBA or AWD purchase order as shipped. Processes through Amazon inbound management (creates pending inbound record).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly works for Amazon FBA or AWD destination warehouses.\n\nBody:\n- shipment_date (optional, date Y-m-d, must be on or before today)\n- tracking_number (optional, string, max:255)\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2024-01-20\",\n  \"tracking_number\": \"AMZN-TRACK-123\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","mark-as-shipped"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"shipment_status\": \"shipped\"\n  },\n  \"message\": \"Purchase order marked as shipped successfully.\"\n}"}]},{"name":"Update Shipment Details (FBA)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/update-shipment","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","update-shipment"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Update shipment details (shipped date and tracking number) for an already-shipped FBA purchase order.\n\nAuthentication: Requires Bearer token.\n\nBody:\n- shipment_date (optional, date Y-m-d, on or before today)\n- tracking_number (optional, string, max:255)","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2024-01-22\",\n  \"tracking_number\": \"AMZN-TRACK-456\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/update-shipment","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","update-shipment"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101\n  },\n  \"message\": \"Purchase order shipment details updated successfully.\"\n}"}]},{"name":"Get Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get paginated notes for a purchase order (most recent first).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"note\": \"Called supplier to confirm ETA.\",\n      \"is_pinned\": false,\n      \"created_at\": \"2024-01-16T09:00:00Z\",\n      \"user\": {\n        \"id\": 1,\n        \"name\": \"John Doe\"\n      }\n    }\n  ],\n  \"current_page\": 1\n}"}]},{"name":"Add Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Add a note to a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- note (required): Note text\n- is_pinned (optional, boolean): Pin note to top\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"note\": \"Supplier confirmed shipment for Feb 1.\",\n  \"is_pinned\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"note\": \"Supplier confirmed shipment for Feb 1.\",\n    \"is_pinned\": false,\n    \"created_at\": \"2024-01-17T10:00:00Z\",\n    \"user\": {\n      \"id\": 1,\n      \"name\": \"John Doe\"\n    }\n  },\n  \"message\": \"Note created successfully\"\n}"}]},{"name":"Toggle Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes",":noteId","toggle-pin"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"noteId","value":"2","description":"The note ID."}]},"description":"Toggle the pinned state of a note on a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes",":noteId","toggle-pin"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"noteId","value":"2","description":"The note ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"is_pinned\": true\n  },\n  \"message\": \"Note pinned\"\n}"}]},{"name":"Delete Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes",":noteId"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"noteId","value":"2","description":"The note ID."}]},"description":"Delete a note from a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","notes",":noteId"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"noteId","value":"2","description":"The note ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Note 2 deleted successfully\"\n}"}]},{"name":"List Purchase Order Communication Threads","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/threads","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","threads"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"List the topic threads on a purchase order (e.g. \"Ship date\", \"Invoice\"), most-recent first. Each thread includes its primary channel, unread count, and latest message for the sidebar preview.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/threads","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","threads"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"subject\": \"Ship date & delivery\",\n      \"channel\": \"whatsapp\",\n      \"channel_label\": \"WhatsApp\",\n      \"unread_count\": 2,\n      \"last_message_at\": \"2026-07-22T12:28:00+00:00\",\n      \"last_message\": {\n        \"id\": 842,\n        \"channel\": \"whatsapp\",\n        \"channel_label\": \"WhatsApp\",\n        \"direction\": \"inbound\",\n        \"direction_label\": \"Inbound\",\n        \"author_name\": \"Acme Supplies\",\n        \"author_type\": \"supplier\",\n        \"from_address\": \"+15551234567\",\n        \"to_addresses\": null,\n        \"subject\": null,\n        \"body_html\": null,\n        \"body_text\": \"Great, we'll lock the 480-unit ship date and send confirmation shortly.\",\n        \"attachments\": [],\n        \"is_read\": false,\n        \"external_message_id\": \"SMabc123\",\n        \"meta\": {\n          \"delivery\": \"sent\"\n        },\n        \"link_reference\": \"PO-2942\",\n        \"link_type_label\": \"Purchase Order\",\n        \"link_id\": 101,\n        \"link_route\": \"/orders/purchase-orders/101\",\n        \"created_at\": \"2026-07-22T12:28:00+00:00\"\n      },\n      \"created_at\": \"2026-07-18T09:00:00+00:00\"\n    },\n    {\n      \"id\": 11,\n      \"subject\": \"Invoice & payment\",\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"unread_count\": 0,\n      \"last_message_at\": \"2026-07-22T12:28:00+00:00\",\n      \"last_message\": null,\n      \"created_at\": \"2026-07-18T09:00:00+00:00\"\n    },\n    {\n      \"id\": 1,\n      \"subject\": \"General\",\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"unread_count\": 0,\n      \"last_message_at\": \"2026-07-22T12:28:00+00:00\",\n      \"last_message\": null,\n      \"created_at\": \"2026-07-18T09:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Purchase Order Communication Thread","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/threads","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","threads"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Start a new topic thread on a purchase order and post its first message. For email threads the subject doubles as the email subject sent to the supplier. Attach files by sending the request as multipart/form-data with attachments[] parts.\n\nFields: subject (required), channel (required — email, internal_note, whatsapp, or sms), body (required).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"subject\": \"Packaging & labeling requirements\",\n  \"channel\": \"email\",\n  \"body\": \"Hi — before this ships, can you confirm the labeling spec for the 480 units?\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/threads","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","threads"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 13,\n    \"subject\": \"Packaging & labeling requirements\",\n    \"channel\": \"email\",\n    \"channel_label\": \"Email\",\n    \"unread_count\": 0,\n    \"last_message_at\": \"2026-07-22T12:28:00+00:00\",\n    \"last_message\": null,\n    \"created_at\": \"2026-07-18T09:00:00+00:00\"\n  }\n}"}]},{"name":"List Purchase Order Communications","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"List the vendor communication thread for a purchase order, newest first. The thread interleaves outbound emails, inbound supplier replies, internal notes, and system events.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"direction\": \"inbound\",\n      \"direction_label\": \"Inbound\",\n      \"author_name\": \"Acme Supplies\",\n      \"author_type\": \"supplier\",\n      \"from_address\": \"sales@acme-supplies.com\",\n      \"to_addresses\": null,\n      \"subject\": \"Re: Purchase Order PO-10293\",\n      \"body_html\": null,\n      \"body_text\": \"Confirmed — shipping Friday, qty 480 (2 short).\",\n      \"attachments\": [\n        {\n          \"filename\": \"packing-slip.pdf\",\n          \"mime_type\": \"application/pdf\",\n          \"size\": 48213,\n          \"url\": \"/api/purchase-orders/101/communications/5012/attachments/0\"\n        }\n      ],\n      \"is_read\": false,\n      \"external_message_id\": \"<CAF7a2@mail.acme-supplies.com>\",\n      \"meta\": null,\n      \"link_reference\": \"PO-10293\",\n      \"link_type_label\": \"Purchase Order\",\n      \"link_route\": \"/orders/purchase-orders/101\",\n      \"created_at\": \"2026-07-16T18:22:04+00:00\"\n    },\n    {\n      \"id\": 5014,\n      \"channel\": \"internal_note\",\n      \"channel_label\": \"Internal Note\",\n      \"direction\": \"internal\",\n      \"direction_label\": \"Internal\",\n      \"author_name\": \"Jordan Buyer\",\n      \"author_type\": \"user\",\n      \"from_address\": null,\n      \"to_addresses\": null,\n      \"subject\": null,\n      \"body_html\": null,\n      \"body_text\": \"Backfill the 2 short units from WH-2.\",\n      \"attachments\": [],\n      \"is_read\": true,\n      \"external_message_id\": null,\n      \"meta\": null,\n      \"link_reference\": \"PO-10293\",\n      \"link_type_label\": \"Purchase Order\",\n      \"link_route\": \"/orders/purchase-orders/101\",\n      \"created_at\": \"2026-07-16T18:45:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/purchase-orders/101/communications?page=1\",\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/purchase-orders/101/communications?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/purchase-orders/101/communications\"\n}"}]},{"name":"Create Purchase Order Communication","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Post a message onto the purchase order's communication thread.\n\nFields:\n- channel (required): one of email, internal_note, whatsapp, sms. WhatsApp/SMS are only accepted when a messaging provider is configured for the workspace and the supplier has a messaging phone number; otherwise a 422 is returned.\n- subject (required for email, ignored for notes): the email subject line.\n- body (required): the message text.\n\nWhen channel is email the message is sent to the supplier's purchase-order email address and logged as an outbound entry; the supplier's reply threads back onto this order automatically. An internal_note is only visible to your team and is never sent externally.\n\nAuthentication: Requires Bearer token.\n\nFile attachments: send the request as multipart/form-data with one or more attachments[] file parts (max 10 files, 20 MB each; pdf/office/image/csv/text). Attached files are stored on the thread and, for emails, attached to the outbound message.\n\nSet thread_id to post into a specific thread; omit it to post into the purchase order's default \"General\" thread.","body":{"mode":"raw","raw":"{\n  \"thread_id\": 12,\n  \"channel\": \"email\",\n  \"subject\": \"Ship date confirmation\",\n  \"body\": \"Hi, could you please confirm the ship date for this order?\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5013,\n    \"channel\": \"email\",\n    \"channel_label\": \"Email\",\n    \"direction\": \"outbound\",\n    \"direction_label\": \"Outbound\",\n    \"author_name\": \"Jordan Buyer\",\n    \"author_type\": \"user\",\n    \"from_address\": null,\n    \"to_addresses\": [\n      \"sales@acme-supplies.com\"\n    ],\n    \"subject\": \"Ship date confirmation\",\n    \"body_html\": null,\n    \"body_text\": \"Hi, could you please confirm the ship date for this order?\",\n    \"attachments\": [],\n    \"is_read\": true,\n    \"external_message_id\": null,\n    \"meta\": {\n      \"delivery\": \"queued\"\n    },\n    \"link_reference\": \"PO-10293\",\n    \"link_type_label\": \"Purchase Order\",\n    \"link_route\": \"/orders/purchase-orders/101\",\n    \"created_at\": \"2026-07-16T18:40:11+00:00\"\n  }\n}"}]},{"name":"Set Supplier WhatsApp/SMS Number","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/supplier-phone","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","supplier-phone"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Set the linked supplier's WhatsApp/SMS number (E.164, e.g. +15551234567) so the messaging channels become usable on this purchase order without opening the supplier record. Send a blank value to clear the stored number. Returns the updated channel availability for this purchase order.\n\nRequires the `purchase_orders.update` permission. Returns 422 when the purchase order has no linked supplier.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"messaging_phone\": \"+15551234567\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/supplier-phone","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications","supplier-phone"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"email\",\n    \"internal_note\",\n    \"whatsapp\",\n    \"sms\"\n  ],\n  \"messaging\": {\n    \"has_supplier\": true,\n    \"supplier_has_phone\": true,\n    \"channels\": {\n      \"whatsapp\": {\n        \"available\": true,\n        \"provider_ready\": true\n      },\n      \"sms\": {\n        \"available\": true,\n        \"provider_ready\": true\n      }\n    }\n  }\n}"}]},{"name":"Mark Communication as Read","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/{communication}/read","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications",":communication","read"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"communication","value":"5012","description":"The communication ID."}]},"description":"Mark an inbound communication entry as read, clearing it from the unread count.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/communications/{communication}/read","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","communications",":communication","read"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"communication","value":"5012","description":"The communication ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5012,\n    \"channel\": \"email\",\n    \"channel_label\": \"Email\",\n    \"direction\": \"inbound\",\n    \"direction_label\": \"Inbound\",\n    \"author_name\": \"Acme Supplies\",\n    \"author_type\": \"supplier\",\n    \"from_address\": \"sales@acme-supplies.com\",\n    \"to_addresses\": null,\n    \"subject\": \"Re: Purchase Order PO-10293\",\n    \"body_html\": null,\n    \"body_text\": \"Confirmed — shipping Friday, qty 480 (2 short).\",\n    \"attachments\": [\n      {\n        \"filename\": \"packing-slip.pdf\",\n        \"mime_type\": \"application/pdf\",\n        \"size\": 48213,\n        \"url\": \"/api/purchase-orders/101/communications/5012/attachments/0\"\n      }\n    ],\n    \"is_read\": true,\n    \"external_message_id\": \"<CAF7a2@mail.acme-supplies.com>\",\n    \"meta\": null,\n    \"link_reference\": \"PO-10293\",\n    \"link_type_label\": \"Purchase Order\",\n    \"link_route\": \"/orders/purchase-orders/101\",\n    \"created_at\": \"2026-07-16T18:22:04+00:00\"\n  }\n}"}]},{"name":"List Supplier Communications (Cross-PO)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/communications","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","communications"],"variable":[{"key":"supplier","value":"55","description":"The supplier ID."}]},"description":"List every vendor communication for a supplier across all of their purchase orders, newest first. Read-only aggregate view; each item links to the purchase order it belongs to via link_route.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/communications","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","communications"],"variable":[{"key":"supplier","value":"55","description":"The supplier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 6002,\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"direction\": \"inbound\",\n      \"direction_label\": \"Inbound\",\n      \"author_name\": \"Acme Supplies\",\n      \"author_type\": \"supplier\",\n      \"from_address\": \"sales@acme-supplies.com\",\n      \"to_addresses\": null,\n      \"subject\": \"Re: Purchase Order PO-10311\",\n      \"body_html\": null,\n      \"body_text\": \"Confirmed for the second order too.\",\n      \"attachments\": [],\n      \"is_read\": false,\n      \"external_message_id\": null,\n      \"meta\": null,\n      \"link_reference\": \"PO-10311\",\n      \"link_type_label\": \"Purchase Order\",\n      \"link_id\": 118,\n      \"link_route\": \"/orders/purchase-orders/118\",\n      \"created_at\": \"2026-07-16T19:02:00+00:00\"\n    },\n    {\n      \"id\": 6001,\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"direction\": \"outbound\",\n      \"direction_label\": \"Outbound\",\n      \"author_name\": \"Jordan Buyer\",\n      \"author_type\": \"user\",\n      \"from_address\": null,\n      \"to_addresses\": [\n        \"sales@acme-supplies.com\"\n      ],\n      \"subject\": \"Purchase Order PO-10293\",\n      \"body_html\": null,\n      \"body_text\": \"Please confirm the ship date.\",\n      \"attachments\": [],\n      \"is_read\": true,\n      \"external_message_id\": null,\n      \"meta\": null,\n      \"link_reference\": \"PO-10293\",\n      \"link_type_label\": \"Purchase Order\",\n      \"link_id\": 101,\n      \"link_route\": \"/orders/purchase-orders/101\",\n      \"created_at\": \"2026-07-16T18:40:11+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/v2/suppliers/55/communications?page=1\",\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/v2/suppliers/55/communications?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/v2/suppliers/55/communications\"\n}"}]},{"name":"Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search by causer name, event, subject type, or properties","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get paginated activity log for a purchase order. Covers events on the PO, its lines, and invoices.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search by causer name, event, subject type, or properties","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1000,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"PurchaseOrder\",\n      \"subject_id\": 101,\n      \"properties\": {\n        \"old\": {\n          \"order_status\": \"draft\"\n        },\n        \"attributes\": {\n          \"order_status\": \"open\"\n        }\n      },\n      \"causer_name\": \"John Doe\",\n      \"created_at\": \"2024-01-15T10:05:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 8\n}"}]},{"name":"Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get paginated inventory movements for a purchase order (via receipt lines).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFor an outsourced-manufacturing PO, this also surfaces the backing manufacturing order's movements: the finished-good receipt (Manufacturing Output) and the component consumption at the contractor (Manufacturing Consumption), so both are visible on the PO."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2000,\n      \"type\": \"receipt\",\n      \"inventory_status\": \"in_stock\",\n      \"quantity\": 100,\n      \"reference\": \"PO-00101\",\n      \"product_id\": 10,\n      \"product_sku\": \"SKU-001\",\n      \"product_name\": \"Widget A\",\n      \"warehouse_id\": 2,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 15,\n      \"unit_cost_provisional\": false,\n      \"layer\": {\n        \"name\": \"L-2024-001\",\n        \"fifo_layer_id\": 50\n      },\n      \"inventory_movement_date\": \"2024-02-05\",\n      \"created_at\": \"2024-02-05T14:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 1\n}"}]},{"name":"FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/fifo-layers?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","fifo-layers"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search by product SKU or name","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Get paginated FIFO inventory layers created from receiving this purchase order.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFor an outsourced-manufacturing PO, this also includes the finished-good FIFO layers produced by the backing manufacturing order (the goods physically arrived via this PO receipt)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/fifo-layers?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","fifo-layers"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search by product SKU or name","disabled":true}],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 50,\n      \"product_id\": 10,\n      \"warehouse_id\": 2,\n      \"quantity\": 100,\n      \"remaining_quantity\": 95,\n      \"avg_cost\": 15,\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceiptLine\",\n      \"link_id\": 501,\n      \"created_at\": \"2024-02-05T14:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 1\n}"}]},{"name":"List PO Invoices","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/invoices","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","invoices"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]},"description":"Get paginated purchase invoices for a specific purchase order.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/invoices","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","invoices"],"variable":[{"key":"purchaseOrder","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 800,\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"purchase_invoice_date\": \"2024-01-20T00:00:00Z\",\n      \"total\": 1500\n    }\n  ],\n  \"current_page\": 1\n}"}]},{"name":"Preview Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/invoice/preview","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","invoice","preview"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Generate an invoice PDF preview and return the URL path.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/invoice/preview","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","invoice","preview"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"path\": \"https://sku2.test/storage/reports/purchase-order-invoice-101.pdf\"\n  }\n}"}]},{"name":"Create Bill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Create a landed cost bill linked to this purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"vendor_id\": 5,\n  \"invoice_number\": \"BILL-2024-001\",\n  \"invoice_date\": \"2024-01-20\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"lines\": [\n    {\n      \"description\": \"Freight charge\",\n      \"quantity\": 1,\n      \"unit_price\": 150,\n      \"tax_rate_id\": null\n    }\n  ],\n  \"allocations\": [],\n  \"proration_strategy\": \"quantity\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 900,\n    \"invoice_number\": \"BILL-2024-001\",\n    \"grand_total\": 150\n  }\n}"}]},{"name":"Get Bill","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills",":bill"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"bill","value":"900","description":"The bill ID."}]},"description":"Get a single bill linked to this purchase order. Returns 404 if the bill does not belong to this PO.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills",":bill"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"bill","value":"900","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 900,\n    \"invoice_number\": \"BILL-2024-001\",\n    \"grand_total\": 150\n  }\n}"}]},{"name":"Update Bill","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills",":bill"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"bill","value":"900","description":"The bill ID."}]},"description":"Update a bill linked to this purchase order. Returns 404 if the bill does not belong to this PO.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"invoice_number\": \"BILL-2024-001-REVISED\",\n  \"lines\": [\n    {\n      \"description\": \"Freight charge revised\",\n      \"quantity\": 1,\n      \"unit_price\": 175\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","bills",":bill"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."},{"key":"bill","value":"900","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 900,\n    \"invoice_number\": \"BILL-2024-001-REVISED\",\n    \"grand_total\": 175\n  }\n}"}]},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import/template","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","template"]},"description":"Download an XLSX import template with headers, sample data, field guide, and reference data.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary XLSX file download.\n\n**Requires permission:** `purchase_orders.import`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/import/template","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(Binary XLSX file)"}]},{"name":"Preview Purchase Order Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import/preview","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","preview"]},"description":"Preview a purchase order import file before executing. Returns a grouped preview of what would be imported.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.import`","body":{"mode":"raw","raw":"{\n  \"file\": \"temp/uploaded-po-import.xlsx\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/import/preview","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"preview\": [\n      {\n        \"purchase_order_number\": \"PO-IMPORT-001\",\n        \"supplier_name\": \"Acme Supplies\",\n        \"lines\": [\n          {\n            \"sku\": \"SKU-001\",\n            \"quantity\": 50\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Validate Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import/validate","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","validate"]},"description":"Validate mapped import rows and return a grouped preview with errors. No side effects — safe to call repeatedly.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRow fields (all optional/nullable):\n- supplier_name, purchase_order_number, purchase_order_date, destination_warehouse, currency_code\n- estimated_delivery_date, supplier_notes, tracking_number, tags, payment_term, shipping_method, incoterm\n- sku, quantity, unit_price, description, discount, tax_rate, line_estimated_delivery_date, nominal_code\n\n**Requires permission:** `purchase_orders.import`","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"supplier_name\": \"Acme Supplies\",\n      \"purchase_order_number\": \"PO-IMPORT-001\",\n      \"purchase_order_date\": \"2024-01-15\",\n      \"destination_warehouse\": \"Main Warehouse\",\n      \"currency_code\": \"USD\",\n      \"estimated_delivery_date\": \"2024-02-01\",\n      \"supplier_notes\": null,\n      \"tracking_number\": null,\n      \"tags\": null,\n      \"payment_term\": \"Net 30\",\n      \"shipping_method\": null,\n      \"incoterm\": null,\n      \"sku\": \"SKU-001\",\n      \"quantity\": 50,\n      \"unit_price\": 15,\n      \"description\": \"Widget A\",\n      \"discount\": null,\n      \"tax_rate\": null,\n      \"line_estimated_delivery_date\": null,\n      \"nominal_code\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/import/validate","host":["{{baseUrl}}"],"path":["api","purchase-orders","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"valid\": [\n    {\n      \"purchase_order_number\": \"PO-IMPORT-001\",\n      \"supplier_id\": 5,\n      \"destination_warehouse_id\": 2,\n      \"lines\": [\n        {\n          \"product_id\": 10,\n          \"quantity\": 50,\n          \"amount\": 15\n        }\n      ]\n    }\n  ],\n  \"invalid\": [],\n  \"warnings\": []\n}"}]},{"name":"Import Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/import","host":["{{baseUrl}}"],"path":["api","purchase-orders","import"]},"description":"Execute the purchase order import — create purchase orders from validated data.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 201 Created on success, 422 on failure.\n\nPurchase order fields:\n- purchase_order_date (required, date)\n- supplier_id (required, exists:suppliers)\n- destination_warehouse_id (required, exists:warehouses)\n- purchase_order_number (optional)\n- currency_id (optional), currency_code (optional)\n- order_status (optional, in:draft,open)\n- estimated_delivery_date, supplier_notes, tracking_number, tags (all optional)\n- payment_term_id, shipping_method_id, incoterm_id, store_id (all optional)\n\nLine fields:\n- quantity (required, numeric, min:1)\n- amount (required, numeric, min:0)\n- product_id, description, discount, tax_rate, nominal_code_id, estimated_delivery_date (all optional)\n\n**Requires permission:** `purchase_orders.import`","body":{"mode":"raw","raw":"{\n  \"purchase_orders\": [\n    {\n      \"purchase_order_number\": \"PO-IMPORT-001\",\n      \"purchase_order_date\": \"2024-01-15\",\n      \"supplier_id\": 5,\n      \"destination_warehouse_id\": 2,\n      \"currency_id\": 1,\n      \"order_status\": \"draft\",\n      \"estimated_delivery_date\": \"2024-02-01\",\n      \"supplier_notes\": null,\n      \"tracking_number\": null,\n      \"tags\": null,\n      \"payment_term_id\": 1,\n      \"shipping_method_id\": null,\n      \"incoterm_id\": null,\n      \"lines\": [\n        {\n          \"product_id\": 10,\n          \"quantity\": 50,\n          \"amount\": 15,\n          \"description\": \"Widget A\",\n          \"discount\": null,\n          \"tax_rate\": null,\n          \"nominal_code_id\": null,\n          \"estimated_delivery_date\": null\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/import","host":["{{baseUrl}}"],"path":["api","purchase-orders","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"created\": 1,\n  \"purchase_orders\": [\n    {\n      \"id\": 105,\n      \"purchase_order_number\": \"PO-IMPORT-001\"\n    }\n  ]\n}"}]},{"name":"Send ASN","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/asn","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","asn"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Send an Advanced Shipment Notice (ASN) for this purchase order to the 3PL warehouse.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequires destination warehouse to be of type 3PL with a valid email address configured.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/asn","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","asn"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Advanced Shipment Notice sent successfully\"\n}"}]},{"name":"Dropship (Ship Fulfillment)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/dropship","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","dropship"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Create a dropship fulfillment for a dropship purchase order (ship directly to customer).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"tracking_number\": \"DROPSHIP-TRACK-001\",\n  \"carrier\": \"UPS\",\n  \"shipped_at\": \"2024-01-20\",\n  \"lines\": [\n    {\n      \"sales_order_line_id\": 300,\n      \"quantity\": 10\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/dropship","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","dropship"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 700,\n    \"tracking_number\": \"DROPSHIP-TRACK-001\",\n    \"status\": \"shipped\"\n  }\n}"}]},{"name":"List Awaiting-Invoice POs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/awaiting-invoices","host":["{{baseUrl}}"],"path":["api","purchase-orders","awaiting-invoices"]},"description":"Paginated worklist of purchase orders still awaiting the supplier's invoice — invoice_status in (uninvoiced, partially_invoiced) AND submission_status in (submitted, finalized), not archived. Prepaid POs (a paid vendor deposit) are the priority to chase. Each row projects amount_paid (sum of paid vendor deposits) and age_days.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Quick filters** (flat Spatie QueryBuilder params):\n- filter[search] — search PO number, exact ID, or supplier name\n- filter[supplier_id] — exact supplier id\n- filter[invoice_status] — exact: uninvoiced | partially_invoiced\n- filter[prepaid_only] — true to only include POs with a paid vendor deposit\n- filter[requested] — true = already requested (invoice_requested_at not null); false = never requested\n\n**Advanced filters** (operator-aware, via GroupedFilterSupport). Send either as a base64-encoded `filter_groups` tree (AND/OR conjunctions) or as flat `filter[column.operator]=value` params. Filterable columns:\n- purchase_order_number (text)\n- invoice_status (text)\n- supplier_name (text, matches the related supplier's name)\n- total (numeric — maps to total_cost)\n- purchase_order_date (date)\n- invoice_requested_at (datetime; use is_empty / is_not_empty for never / already requested)\n- invoice_request_count (numeric)\n\nText operators: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty. Numeric operators: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty. Datetime operators additionally include before/after and relative shortcuts (today, yesterday, past_week, days_ago, between, etc.).\n\nfilter_groups example (before base64-encoding):\n{\n  \"conjunction\": \"and\",\n  \"children\": [\n    {\"type\": \"condition\", \"condition\": {\"column\": \"invoice_status\", \"operator\": \"is\", \"value\": \"partially_invoiced\"}},\n    {\"type\": \"condition\", \"condition\": {\"column\": \"total\", \"operator\": \"greater_than\", \"value\": \"1000\"}}\n  ]\n}\n\n**Sorts:** id, purchase_order_number, purchase_order_date, total_cost, amount_paid_total, age_days, invoice_requested_at, invoice_request_count (prefix with - for DESC). Default sort: purchase_order_date.\n\n**Pagination:** page, per_page (default 15).\n\n**Filter update (tab rebuild):** supplier_id is now operator-aware (supplier_id.is / .is_not / .is_one_of …) in addition to the flat filter[supplier_id]; prepaid_only and requested also accept the tree form prepaid_only.is / requested.is (value true|false) so they work as FilterInput pills + saved views. Flat forms still work."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/awaiting-invoices","host":["{{baseUrl}}"],"path":["api","purchase-orders","awaiting-invoices"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4521,\n      \"purchase_order_number\": \"PO-004521\",\n      \"purchase_order_date\": \"2025-10-21T00:00:00+00:00\",\n      \"age_days\": 255,\n      \"supplier\": {\n        \"id\": 12,\n        \"name\": \"Acme Supplier\",\n        \"email\": \"ap@acme.example\"\n      },\n      \"supplier_route\": \"/crm/suppliers/12\",\n      \"po_route\": \"/orders/purchase-orders/4521\",\n      \"invoice_status\": \"uninvoiced\",\n      \"currency_code\": \"USD\",\n      \"total\": 14202.88,\n      \"amount_paid\": 7101.44,\n      \"is_prepaid\": true,\n      \"invoice_requested_at\": null,\n      \"invoice_request_count\": 0\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 19,\n  \"from\": 1,\n  \"to\": 15,\n  \"path\": \"{{protocol}}{{domain}}/api/purchase-orders/awaiting-invoices\"\n}"}]},{"name":"Request Invoice (Single PO)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/request-invoice","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","request-invoice"],"variable":[{"key":"purchase_order","value":"4521","description":"Purchase Order ID"}]},"description":"Email the supplier requesting the outstanding invoice for a single purchase order, optionally attaching vendor-deposit documents (e.g. proof of the prepayment). The reply-to is set to the sending user. On success the PO is stamped: invoice_requested_at = now, invoice_request_count incremented, invoice_last_requested_by = current user.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOnly allowed when the PO is still awaiting its invoice (invoice_status in uninvoiced/partially_invoiced AND submission_status in submitted/finalized) — otherwise returns 422.\n\nAuthentication: Requires Bearer token.\n**Requires permission:** `purchase_orders.update`. Throttled: 60 requests/min.\n\n**Body fields:**\n- to (string, required) — recipient email\n- subject (string, required, max 255)\n- note (string, optional, max 2000) — appended to the email body\n- cc (array of emails, optional, max 10)\n- attachment_ids (array of ints, optional) — VendorDepositAttachment ids; each MUST belong to one of this PO's deposits or the request is rejected (422)","body":{"mode":"raw","raw":"{\n  \"to\": \"ap@acme.example\",\n  \"subject\": \"Invoice request for PO-004521\",\n  \"note\": \"We show this order as prepaid but have not yet received your invoice. Please send it at your earliest convenience.\",\n  \"cc\": [\n    \"buyer@ourcompany.example\"\n  ],\n  \"attachment_ids\": [\n    88,\n    91\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/request-invoice","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","request-invoice"],"variable":[{"key":"purchase_order","value":"4521","description":"Purchase Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4521,\n    \"purchase_order_number\": \"PO-004521\",\n    \"invoice_status\": \"uninvoiced\",\n    \"submission_status\": \"submitted\",\n    \"invoice_requested_at\": \"2026-07-03T14:22:05+00:00\",\n    \"invoice_request_count\": 1,\n    \"supplier_id\": 12,\n    \"currency_code\": \"USD\",\n    \"total_cost\": 14202.88,\n    \"total\": 14202.88\n  }\n}"}]},{"name":"Get Purchase Order Cash Flow Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/cash-flow-schedule","host":["{{baseUrl}}"],"path":["api","purchase-orders","cash-flow-schedule"]},"description":"Get the purchasing cash-flow schedule — expected vendor payments derived from all open, non-archived purchase orders.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach expected payment row is built from the best available source, reported as `forecast_source`:\n- `scheduled` — the PO's own payment-term deposit schedule (high confidence)\n- `inferred` — the supplier's default payment-term schedule or default deposit percentage (medium confidence)\n- `heuristic` — a due date estimated from PO/shipment ETD or ETA\n- `unscheduled` — no schedule and no usable date; rows with a null `due_date` are always included regardless of the date window\n\nIf a milestone already has a linked vendor deposit, the row amount reflects that deposit's remaining open exposure and the deposit's own due date takes precedence. Fully settled milestones are omitted.\n\nThe response contains time buckets (by the chosen granularity), per-source sections with full rows, a per-source summary, and overall exposure totals including overdue and due-in-7/30-day figures.\n\nRead-only. Requires the `purchase-orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/cash-flow-schedule","host":["{{baseUrl}}"],"path":["api","purchase-orders","cash-flow-schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"date_from\": \"2026-07-06\",\n    \"date_to\": \"2027-01-06\",\n    \"granularity\": \"week\",\n    \"available_granularities\": [\n      {\n        \"value\": \"day\",\n        \"label\": \"Day\"\n      },\n      {\n        \"value\": \"week\",\n        \"label\": \"Week\"\n      },\n      {\n        \"value\": \"month\",\n        \"label\": \"Month\"\n      }\n    ],\n    \"applied_forecast_sources\": [\n      \"scheduled\",\n      \"inferred\",\n      \"heuristic\",\n      \"unscheduled\"\n    ],\n    \"forecast_source_summary\": [\n      {\n        \"key\": \"scheduled\",\n        \"label\": \"Scheduled\",\n        \"color\": \"#0f766e\",\n        \"row_count\": 4,\n        \"amount_in_tenant_currency\": 42500\n      },\n      {\n        \"key\": \"inferred\",\n        \"label\": \"Supplier Default\",\n        \"color\": \"#1d4ed8\",\n        \"row_count\": 2,\n        \"amount_in_tenant_currency\": 9800\n      },\n      {\n        \"key\": \"heuristic\",\n        \"label\": \"Heuristic\",\n        \"color\": \"#d97706\",\n        \"row_count\": 1,\n        \"amount_in_tenant_currency\": 15200\n      },\n      {\n        \"key\": \"unscheduled\",\n        \"label\": \"Unscheduled\",\n        \"color\": \"#b91c1c\",\n        \"row_count\": 1,\n        \"amount_in_tenant_currency\": 3100\n      }\n    ],\n    \"buckets\": [\n      {\n        \"period_start\": \"2026-07-06\",\n        \"period_label\": \"Week of Jul 6, 2026\",\n        \"row_count\": 2,\n        \"purchase_order_count\": 2,\n        \"total_amount_in_tenant_currency\": 21500,\n        \"scheduled_amount_in_tenant_currency\": 18400,\n        \"inferred_amount_in_tenant_currency\": 3100,\n        \"heuristic_amount_in_tenant_currency\": 0,\n        \"unscheduled_amount_in_tenant_currency\": 0\n      }\n    ],\n    \"sections\": {\n      \"scheduled\": {\n        \"rows\": [\n          {\n            \"purchase_order_id\": 812,\n            \"purchase_order_number\": \"PO-00812\",\n            \"supplier_id\": 44,\n            \"supplier_name\": \"Shenzhen Widgets Co\",\n            \"forecast_source\": \"scheduled\",\n            \"forecast_source_label\": \"Scheduled\",\n            \"confidence\": \"high\",\n            \"confidence_label\": \"High\",\n            \"forecast_note\": \"Explicit PO payment schedule\",\n            \"payment_term_id\": 6,\n            \"payment_term_name\": \"30% Deposit / 70% on Shipment\",\n            \"milestone_sequence\": 1,\n            \"milestone_label\": \"Production Deposit\",\n            \"settlement_type\": \"vendor_deposit\",\n            \"settlement_type_label\": \"Vendor Deposit\",\n            \"trigger_event\": \"po_approved\",\n            \"trigger_event_label\": \"PO Approved\",\n            \"basis_source_label\": \"PO Approved\",\n            \"shipment_id\": null,\n            \"shipment_reference\": null,\n            \"basis_date\": \"2026-07-01\",\n            \"due_date\": \"2026-07-08\",\n            \"amount_in_tenant_currency\": 12500,\n            \"linked_vendor_deposit_id\": 91,\n            \"linked_vendor_deposit_number\": \"VD-00091\",\n            \"linked_vendor_deposit_status\": \"approved\",\n            \"is_trigger_reached\": true\n          }\n        ],\n        \"row_count\": 4,\n        \"purchase_order_count\": 3,\n        \"amount_in_tenant_currency\": 42500,\n        \"dated_amount_in_tenant_currency\": 40000,\n        \"undated_amount_in_tenant_currency\": 2500,\n        \"overdue_amount_in_tenant_currency\": 5000\n      },\n      \"inferred\": {\n        \"rows\": [],\n        \"row_count\": 0,\n        \"purchase_order_count\": 0,\n        \"amount_in_tenant_currency\": 0,\n        \"dated_amount_in_tenant_currency\": 0,\n        \"undated_amount_in_tenant_currency\": 0,\n        \"overdue_amount_in_tenant_currency\": 0\n      },\n      \"heuristic\": {\n        \"rows\": [],\n        \"row_count\": 0,\n        \"purchase_order_count\": 0,\n        \"amount_in_tenant_currency\": 0,\n        \"dated_amount_in_tenant_currency\": 0,\n        \"undated_amount_in_tenant_currency\": 0,\n        \"overdue_amount_in_tenant_currency\": 0\n      },\n      \"unscheduled\": {\n        \"rows\": [],\n        \"row_count\": 0,\n        \"purchase_order_count\": 0,\n        \"amount_in_tenant_currency\": 0,\n        \"dated_amount_in_tenant_currency\": 0,\n        \"undated_amount_in_tenant_currency\": 0,\n        \"overdue_amount_in_tenant_currency\": 0\n      }\n    },\n    \"summary\": {\n      \"total_rows\": 8,\n      \"total_purchase_orders\": 5,\n      \"total_exposure_in_tenant_currency\": 70600,\n      \"dated_exposure_in_tenant_currency\": 67500,\n      \"undated_exposure_in_tenant_currency\": 3100,\n      \"overdue_exposure_in_tenant_currency\": 5000,\n      \"due_next_7_days_in_tenant_currency\": 21500,\n      \"due_next_30_days_in_tenant_currency\": 38900,\n      \"bucket_count\": 6\n    }\n  }\n}"}]},{"name":"List Expected Vendor Deposit Milestones","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/expected-vendor-deposit-milestones","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","expected-vendor-deposit-milestones"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"}]},"description":"List the expected payment milestones for a purchase order, derived from its payment-term deposit schedule.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns one row per schedule line. Per-shipment lines fan out into one row per inbound shipment (key `line-{n}-shipment-{id}`), plus a `line-{n}-remainder` row for PO value not yet assigned to a shipment. If the payment term has no schedule, a single synthesized `Final Invoice Balance` milestone (key `synthesized-final-balance`) covers the un-deposited remainder.\n\nEach milestone's `status` is one of:\n- `expected` — planned but the trigger event has not happened yet\n- `ready_to_create` — the trigger has been reached; the milestone can be turned into a vendor deposit\n- `created` — a vendor deposit is already linked (`linked_vendor_deposit_id`)\n- `out_of_sync` — the linked deposit no longer matches the schedule (amount, due date, trigger, or shipment changed); see `status_reasons`\n\nUse the `key` value with **Create Vendor Deposit from Milestone** to materialize a `ready_to_create` milestone.\n\nRead-only. Requires the `purchase-orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/expected-vendor-deposit-milestones","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","expected-vendor-deposit-milestones"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"key\": \"line-1\",\n      \"status\": \"created\",\n      \"status_label\": \"Created\",\n      \"status_reason\": \"A vendor deposit already exists for this schedule milestone.\",\n      \"status_reasons\": [\n        \"A vendor deposit already exists for this schedule milestone.\"\n      ],\n      \"purchase_order_id\": 812,\n      \"purchase_order_number\": \"PO-00812\",\n      \"supplier_id\": 44,\n      \"supplier_name\": \"Shenzhen Widgets Co\",\n      \"currency_id\": 2,\n      \"currency_code\": \"USD\",\n      \"line_index\": 1,\n      \"shipment_id\": null,\n      \"shipment_reference\": null,\n      \"label\": \"Production Deposit\",\n      \"amount_mode\": \"percent\",\n      \"fixed_amount\": null,\n      \"percentage\": 30,\n      \"is_ownership_transfer\": false,\n      \"settlement_type\": \"vendor_deposit\",\n      \"settlement_type_label\": \"Vendor Deposit\",\n      \"creates_vendor_deposit\": true,\n      \"trigger_event\": \"po_approved\",\n      \"trigger_event_label\": \"PO Approved\",\n      \"offset_days\": 0,\n      \"per_shipment\": false,\n      \"shipment_date_basis\": null,\n      \"forecast_source\": \"actual_trigger_date\",\n      \"forecast_source_label\": \"Actual trigger date — PO Approved\",\n      \"is_synthesized\": false,\n      \"expected_amount\": 12499.95,\n      \"expected_amount_in_tenant_currency\": 12499.95,\n      \"basis_date\": \"2026-07-01\",\n      \"due_date\": \"2026-07-01\",\n      \"is_trigger_reached\": true,\n      \"is_ready_to_create\": false,\n      \"linked_vendor_deposit_id\": 91,\n      \"linked_vendor_deposit_number\": \"VD-00091\",\n      \"linked_vendor_deposit_status\": \"approved\",\n      \"linked_vendor_deposit_status_label\": \"Approved\",\n      \"schedule_snapshot\": {\n        \"line_index\": 1,\n        \"label\": \"Production Deposit\",\n        \"amount_mode\": \"percent\",\n        \"fixed_amount\": null,\n        \"percentage\": 30,\n        \"is_ownership_transfer\": false,\n        \"settlement_type\": \"vendor_deposit\",\n        \"trigger_event\": \"po_approved\",\n        \"offset_days\": 0,\n        \"per_shipment\": false,\n        \"shipment_date_basis\": null,\n        \"shipment_id\": null,\n        \"expected_amount\": 12499.95,\n        \"due_date\": \"2026-07-01\"\n      },\n      \"placeholder_reason\": null\n    },\n    {\n      \"key\": \"line-2-shipment-345\",\n      \"status\": \"ready_to_create\",\n      \"status_label\": \"Ready to Create\",\n      \"status_reason\": \"The schedule trigger has been reached and this milestone can now be turned into a vendor deposit document.\",\n      \"status_reasons\": [\n        \"The schedule trigger has been reached and this milestone can now be turned into a vendor deposit document.\"\n      ],\n      \"purchase_order_id\": 812,\n      \"purchase_order_number\": \"PO-00812\",\n      \"supplier_id\": 44,\n      \"supplier_name\": \"Shenzhen Widgets Co\",\n      \"currency_id\": 2,\n      \"currency_code\": \"USD\",\n      \"line_index\": 2,\n      \"shipment_id\": 345,\n      \"shipment_reference\": \"Shipment #345\",\n      \"label\": \"Balance on Dispatch\",\n      \"amount_mode\": \"percent\",\n      \"fixed_amount\": null,\n      \"percentage\": 70,\n      \"is_ownership_transfer\": false,\n      \"settlement_type\": \"vendor_deposit\",\n      \"settlement_type_label\": \"Vendor Deposit\",\n      \"creates_vendor_deposit\": true,\n      \"trigger_event\": \"po_shipped\",\n      \"trigger_event_label\": \"PO First Shipment\",\n      \"offset_days\": 0,\n      \"per_shipment\": true,\n      \"shipment_date_basis\": \"dispatched\",\n      \"forecast_source\": \"actual_trigger_date\",\n      \"forecast_source_label\": \"Actual trigger date — PO First Shipment\",\n      \"is_synthesized\": false,\n      \"expected_amount\": 29166.55,\n      \"expected_amount_in_tenant_currency\": 29166.55,\n      \"basis_date\": \"2026-07-04\",\n      \"due_date\": \"2026-07-04\",\n      \"is_trigger_reached\": true,\n      \"is_ready_to_create\": true,\n      \"linked_vendor_deposit_id\": null,\n      \"linked_vendor_deposit_number\": null,\n      \"linked_vendor_deposit_status\": null,\n      \"linked_vendor_deposit_status_label\": null,\n      \"schedule_snapshot\": {\n        \"line_index\": 2,\n        \"label\": \"Balance on Dispatch\",\n        \"amount_mode\": \"percent\",\n        \"fixed_amount\": null,\n        \"percentage\": 70,\n        \"is_ownership_transfer\": false,\n        \"settlement_type\": \"vendor_deposit\",\n        \"trigger_event\": \"po_shipped\",\n        \"offset_days\": 0,\n        \"per_shipment\": true,\n        \"shipment_date_basis\": \"dispatched\",\n        \"shipment_id\": 345,\n        \"expected_amount\": 29166.55,\n        \"due_date\": \"2026-07-04\"\n      },\n      \"placeholder_reason\": null\n    }\n  ]\n}"}]},{"name":"Create Vendor Deposit from Milestone","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/expected-vendor-deposit-milestones/{milestoneKey}/create-deposit","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","expected-vendor-deposit-milestones",":milestoneKey","create-deposit"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"},{"key":"milestoneKey","value":"line-2-shipment-345","description":"Milestone key from List Expected Vendor Deposit Milestones, e.g. line-1 or line-2-shipment-345"}]},"description":"Create a draft vendor deposit from a payment-term schedule milestone. No request body — the milestone key (from **List Expected Vendor Deposit Milestones**) fully identifies the action.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOnly milestones with `is_ready_to_create: true` and `settlement_type: vendor_deposit` can be materialized. The created deposit:\n- starts in `draft` status with an auto-assigned number (e.g. `VD-00092`)\n- copies supplier, currency, and rate from the purchase order\n- takes its amount and due date from the milestone, and records the schedule line and shipment it came from\n- does not post any accounting entries while in draft\n\nThe call is idempotent against races — if a deposit already exists for the same schedule line and shipment, that deposit is returned instead of creating a duplicate.\n\nErrors:\n- 404 — unknown milestone key for this purchase order\n- 422 — the milestone already has a linked vendor deposit\n- 422 — the milestone's trigger event has not happened yet\n\nSynchronous — no background processing. Requires the `purchase-orders:write` token scope and permission to update purchase orders."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/expected-vendor-deposit-milestones/{milestoneKey}/create-deposit","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","expected-vendor-deposit-milestones",":milestoneKey","create-deposit"],"variable":[{"key":"purchase_order","value":"812","description":"Purchase order ID"},{"key":"milestoneKey","value":"line-2-shipment-345","description":"Milestone key from List Expected Vendor Deposit Milestones, e.g. line-1 or line-2-shipment-345"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 92,\n  \"deposit_number\": \"VD-00092\",\n  \"status\": \"draft\",\n  \"status_label\": \"Draft\",\n  \"supplier_id\": 44,\n  \"supplier\": {\n    \"id\": 44,\n    \"name\": \"Shenzhen Widgets Co\",\n    \"email\": \"orders@szwidgets.example\",\n    \"wire_instructions\": \"Bank of China — SWIFT BKCHCNBJ — Acct 1234567890\",\n    \"link_route\": \"/v2/crm/suppliers/44\"\n  },\n  \"purchase_order_id\": 812,\n  \"payment_term_schedule_line_index\": 2,\n  \"inbound_shipment_id\": 345,\n  \"payment_term_schedule_snapshot\": {\n    \"line_index\": 2,\n    \"label\": \"Balance on Dispatch\",\n    \"amount_mode\": \"percent\",\n    \"fixed_amount\": null,\n    \"percentage\": 70,\n    \"is_ownership_transfer\": false,\n    \"settlement_type\": \"vendor_deposit\",\n    \"trigger_event\": \"po_shipped\",\n    \"offset_days\": 0,\n    \"per_shipment\": true,\n    \"shipment_date_basis\": \"dispatched\",\n    \"shipment_id\": 345,\n    \"expected_amount\": 29166.55,\n    \"due_date\": \"2026-07-04\"\n  },\n  \"is_ownership_transfer\": false,\n  \"ownership_transferred_at\": null,\n  \"purchase_order\": {\n    \"id\": 812,\n    \"purchase_order_number\": \"PO-00812\",\n    \"link_route\": \"/v2/orders/purchase-orders/812\",\n    \"link_reference\": \"PO-00812\"\n  },\n  \"currency_id\": 2,\n  \"currency\": {\n    \"id\": 2,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"currency_rate\": 1,\n  \"tenant_currency\": {\n    \"id\": 2,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"amount\": 29166.55,\n  \"amount_in_tenant_currency\": 29166.55,\n  \"amount_paid\": 0,\n  \"amount_applied\": 0,\n  \"amount_refunded\": 0,\n  \"amount_written_off\": 0,\n  \"available_balance\": 0,\n  \"tax_amount\": 0,\n  \"tax_lines\": null,\n  \"deposit_date\": \"2026-07-06\",\n  \"due_date\": \"2026-07-04\",\n  \"paid_at\": null,\n  \"external_reference\": null,\n  \"payee_bank_details\": null,\n  \"payment_requested_at\": null,\n  \"remittance_sent_at\": null,\n  \"notes\": \"Created from payment term schedule milestone: Balance on Dispatch\",\n  \"proportional_apply_enabled\": false,\n  \"auto_apply_enabled\": null,\n  \"auto_apply_effective\": true,\n  \"approved_by\": null,\n  \"approved_at\": null,\n  \"approval_notes\": null,\n  \"submit_action\": \"approve\",\n  \"submit_action_label\": \"Approve Deposit\",\n  \"applications\": [],\n  \"payments\": [],\n  \"refunds\": [],\n  \"created_at\": \"2026-07-06T09:14:22+00:00\",\n  \"updated_at\": \"2026-07-06T09:14:22+00:00\",\n  \"archived_at\": null\n}"}]},{"name":"Get Purchase Order Return Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/return-metrics","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","return-metrics"],"variable":[{"key":"purchaseOrder","value":"1042","description":"Purchase order ID"}]},"description":"Get the annualized return (Annualized ROI / IRR) for a purchase order.\n\nModels the purchase as a dated cash-flow series — vendor deposit and balance payments out, then net sales proceeds in as the received units sell through, plus any remaining stock valued at cost as of today — and solves the money-weighted annualized rate (XIRR).\n\nTwo variants are returned: `product` (purchase payments and sales proceeds only) and `fully_loaded` (also charges allocated time-based cost entries). Each variant includes the rate, cash multiple (moic), days held, realized fraction, profit, an NPV at the tenant hurdle rate, a maturity `status` (provisional, interim, final, or nm), presentation caveats, and the full signed cash-flow series.\n\nRequires a Bearer token.\n\nEach variant includes a `disposition` breakdown accounting for every received unit — bucketed into sold (direct / after transfer or kitting), still-owned (on hand / held elsewhere), and lost (written off / stock-taken) — so the sell-through figure is fully reconciled to units received."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/return-metrics","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","return-metrics"],"variable":[{"key":"purchaseOrder","value":"1042","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purchase_order_id\": 1042,\n    \"default_variant\": \"product\",\n    \"variants\": {\n      \"product\": {\n        \"variant\": \"product\",\n        \"variant_label\": \"Product\",\n        \"status\": \"interim\",\n        \"status_label\": \"Interim\",\n        \"is_rankable\": true,\n        \"is_interim\": true,\n        \"is_provisional\": false,\n        \"is_nm\": false,\n        \"is_short_hold\": false,\n        \"xirr\": 1.3421,\n        \"period_return\": 0.7834,\n        \"headline_metric\": \"xirr\",\n        \"annualized_display_capped\": false,\n        \"annualized_display_cap\": 2,\n        \"moic\": 1.85,\n        \"days_held\": 212,\n        \"pct_realized\": 0.78,\n        \"realized_xirr\": 1.1032,\n        \"total_cash_out\": 8000,\n        \"total_cash_in\": 14800,\n        \"profit\": 6800,\n        \"npv_at_hurdle\": 4120.55,\n        \"has_estimated_outflows\": false,\n        \"caveats\": [\n          \"Interim — includes remaining stock valued at cost as of today.\"\n        ],\n        \"cash_flows\": [\n          {\n            \"date\": \"2026-03-01\",\n            \"amount\": -2400,\n            \"type\": \"deposit\",\n            \"label\": \"Vendor deposit\",\n            \"source_type\": \"App\\\\Models\\\\VendorDeposit\",\n            \"source_type_label\": \"Vendor Deposit\",\n            \"source_id\": 331,\n            \"source_route\": null\n          },\n          {\n            \"date\": \"2026-04-15\",\n            \"amount\": -5600,\n            \"type\": \"balance_payment\",\n            \"label\": \"Bill payment\",\n            \"source_type\": \"App\\\\Models\\\\Bill\",\n            \"source_type_label\": \"Bill\",\n            \"source_id\": 883,\n            \"source_route\": \"/accounting/bills/883\"\n          },\n          {\n            \"date\": \"2026-06-02\",\n            \"amount\": 1180,\n            \"type\": \"sale\",\n            \"label\": \"Sale of 14 unit(s)\",\n            \"source_type\": \"App\\\\Models\\\\SalesOrderLine\",\n            \"source_type_label\": \"Sales Order Line\",\n            \"source_id\": 5521,\n            \"source_route\": null\n          },\n          {\n            \"date\": \"2026-07-17\",\n            \"amount\": 1760,\n            \"type\": \"terminal_value\",\n            \"label\": \"Remaining stock at cost\",\n            \"source_type\": \"App\\\\Models\\\\PurchaseOrder\",\n            \"source_type_label\": \"Purchase Order\",\n            \"source_id\": 1042,\n            \"source_route\": \"/orders/purchase-orders/1042\"\n          }\n        ],\n        \"disposition\": {\n          \"units_bought\": 500,\n          \"buckets\": [\n            {\n              \"key\": \"sold_direct\",\n              \"label\": \"Sold directly\",\n              \"group\": \"sold\",\n              \"units\": 360\n            },\n            {\n              \"key\": \"sold_downstream\",\n              \"label\": \"Sold after transfer / kitting\",\n              \"group\": \"sold\",\n              \"units\": 55\n            },\n            {\n              \"key\": \"on_hand\",\n              \"label\": \"On hand (unsold)\",\n              \"group\": \"held\",\n              \"units\": 40\n            },\n            {\n              \"key\": \"written_off\",\n              \"label\": \"Written off / adjusted\",\n              \"group\": \"lost\",\n              \"units\": 30\n            },\n            {\n              \"key\": \"lost_downstream\",\n              \"label\": \"Lost downstream (write-off / stock-take)\",\n              \"group\": \"lost\",\n              \"units\": 15\n            }\n          ]\n        },\n        \"as_of_date\": \"2026-07-17\",\n        \"computed_at\": \"2026-07-17T03:15:00+00:00\"\n      },\n      \"fully_loaded\": {\n        \"variant\": \"fully_loaded\",\n        \"variant_label\": \"Fully-loaded\",\n        \"status\": \"interim\",\n        \"status_label\": \"Interim\",\n        \"is_rankable\": true,\n        \"is_interim\": true,\n        \"is_provisional\": false,\n        \"is_nm\": false,\n        \"is_short_hold\": false,\n        \"xirr\": 1.1105,\n        \"period_return\": 0.6521,\n        \"headline_metric\": \"xirr\",\n        \"annualized_display_capped\": false,\n        \"annualized_display_cap\": 2,\n        \"moic\": 1.71,\n        \"days_held\": 212,\n        \"pct_realized\": 0.78,\n        \"realized_xirr\": 1.1032,\n        \"total_cash_out\": 8000,\n        \"total_cash_in\": 13680,\n        \"profit\": 5680,\n        \"npv_at_hurdle\": 3210.4,\n        \"has_estimated_outflows\": false,\n        \"caveats\": [\n          \"Interim — includes remaining stock valued at cost as of today.\"\n        ],\n        \"cash_flows\": [\n          {\n            \"date\": \"2026-03-01\",\n            \"amount\": -2400,\n            \"type\": \"deposit\",\n            \"label\": \"Vendor deposit\",\n            \"source_type\": \"App\\\\Models\\\\VendorDeposit\",\n            \"source_type_label\": \"Vendor Deposit\",\n            \"source_id\": 331,\n            \"source_route\": null\n          },\n          {\n            \"date\": \"2026-04-15\",\n            \"amount\": -5600,\n            \"type\": \"balance_payment\",\n            \"label\": \"Bill payment\",\n            \"source_type\": \"App\\\\Models\\\\Bill\",\n            \"source_type_label\": \"Bill\",\n            \"source_id\": 883,\n            \"source_route\": \"/accounting/bills/883\"\n          },\n          {\n            \"date\": \"2026-06-02\",\n            \"amount\": 1180,\n            \"type\": \"sale\",\n            \"label\": \"Sale of 14 unit(s)\",\n            \"source_type\": \"App\\\\Models\\\\SalesOrderLine\",\n            \"source_type_label\": \"Sales Order Line\",\n            \"source_id\": 5521,\n            \"source_route\": null\n          },\n          {\n            \"date\": \"2026-07-17\",\n            \"amount\": 1760,\n            \"type\": \"terminal_value\",\n            \"label\": \"Remaining stock at cost\",\n            \"source_type\": \"App\\\\Models\\\\PurchaseOrder\",\n            \"source_type_label\": \"Purchase Order\",\n            \"source_id\": 1042,\n            \"source_route\": \"/orders/purchase-orders/1042\"\n          }\n        ],\n        \"disposition\": {\n          \"units_bought\": 500,\n          \"buckets\": [\n            {\n              \"key\": \"sold_direct\",\n              \"label\": \"Sold directly\",\n              \"group\": \"sold\",\n              \"units\": 360\n            },\n            {\n              \"key\": \"sold_downstream\",\n              \"label\": \"Sold after transfer / kitting\",\n              \"group\": \"sold\",\n              \"units\": 55\n            },\n            {\n              \"key\": \"on_hand\",\n              \"label\": \"On hand (unsold)\",\n              \"group\": \"held\",\n              \"units\": 40\n            },\n            {\n              \"key\": \"written_off\",\n              \"label\": \"Written off / adjusted\",\n              \"group\": \"lost\",\n              \"units\": 30\n            },\n            {\n              \"key\": \"lost_downstream\",\n              \"label\": \"Lost downstream (write-off / stock-take)\",\n              \"group\": \"lost\",\n              \"units\": 15\n            }\n          ]\n        },\n        \"as_of_date\": \"2026-07-17\",\n        \"computed_at\": \"2026-07-17T03:15:00+00:00\"\n      }\n    }\n  }\n}"}]},{"name":"Get Consignment Settlement Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/settlement-preview","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","settlement-preview"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]},"description":"For a consignment purchase order, list each line's consigned stock that has sold but has not yet been settled with the supplier, priced at the consignment cost. Lines with nothing left to settle are omitted.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/settlement-preview","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","settlement-preview"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 5501,\n      \"sku\": \"WIDGET-1\",\n      \"sold_quantity\": 12,\n      \"settled_quantity\": 0,\n      \"sold_unsettled_quantity\": 12,\n      \"unit_cost\": 4,\n      \"amount\": 48\n    },\n    {\n      \"purchase_order_line_id\": 5502,\n      \"sku\": \"WIDGET-2\",\n      \"sold_quantity\": 5,\n      \"settled_quantity\": 0,\n      \"sold_unsettled_quantity\": 5,\n      \"unit_cost\": 6.5,\n      \"amount\": 32.5\n    }\n  ]\n}"}]},{"name":"Create Consignment Settlement","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/settlements","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","settlements"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]},"description":"Generate a settlement bill for a consignment purchase order, covering the consigned stock that has sold but not yet been settled. The bill is created for the supplier and the purchase order stays open so further sales can be settled later.\n\nRequest body (all optional):\n- settlement_date (date): the report/settlement date. Defaults to today.\n- line_quantities (object): map of purchase order line ID to the quantity to settle for that line. Each value is clamped to what is still unsettled. Omit to settle every sold-but-unsettled unit.\n\nReturns 422 when the purchase order is not a consignment order, or when there is nothing left to settle.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"settlement_date\": \"2026-07-08\",\n  \"line_quantities\": {\n    \"5501\": 12,\n    \"5502\": 5\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/settlements","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","settlements"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 9001,\n  \"purchase_order_id\": 123,\n  \"purchase_order_number\": \"PO-10432\",\n  \"supplier_invoice_number\": \"CONSIGN-PO-10432-20260708-1\",\n  \"supplier_id\": 44,\n  \"supplier_name\": \"Acme Wholesale\",\n  \"purchase_invoice_date\": \"2026-07-08\",\n  \"due_date\": \"2026-08-07\",\n  \"status\": \"unpaid\",\n  \"is_consignment_settlement\": true,\n  \"purchase_invoice_lines\": [\n    {\n      \"id\": 71001,\n      \"purchase_order_line_id\": 5501,\n      \"quantity_invoiced\": 12,\n      \"unit_price\": 4\n    },\n    {\n      \"id\": 71002,\n      \"purchase_order_line_id\": 5502,\n      \"quantity_invoiced\": 5,\n      \"unit_price\": 6.5\n    }\n  ]\n}"}]},{"name":"Return Unsold Consigned Stock","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/returns","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","returns"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]},"description":"Return unsold consigned stock to the supplier for a consignment purchase order. This removes the returned units from sellable stock; it creates no bill and no credit, because unsold consigned stock was never owed for. Returning stock also updates the purchase order's consignment settlement status, and a purchase order whose stock is now entirely sold-and-settled or returned is automatically closed.\n\nRequest body (all optional):\n- line_quantities (object): map of purchase order line ID to the quantity to return for that line. Each value is clamped to the units still unsold on hand. Omit to return every unsold unit across all lines.\n\nReturns 422 when the purchase order is not a consignment order.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"line_quantities\": {\n    \"5501\": 3\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchaseOrder}/consignment/returns","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchaseOrder","consignment","returns"],"variable":[{"key":"purchaseOrder","value":"123","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 5501,\n      \"returned\": 3\n    }\n  ],\n  \"consignment_status\": \"fully_settled\"\n}"}]},{"name":"Share Consignment Settlement Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/consignment/settlements/{settlement}/share","host":["{{baseUrl}}"],"path":["api","consignment","settlements",":settlement","share"],"variable":[{"key":"settlement","value":"9001","description":"Consignment settlement bill (purchase invoice) ID"}]},"description":"Share a consignment settlement's Account Sales Report with the supplier. The report is term-aware — it states how much is owed and when it is due, derived from the consignment payment term on the purchase order.\n\nRequest body:\n- channel (required): how to share — email, portal, or both.\n- recipient_email (optional): the address to email the report to. When omitted, the supplier's own contact email is used. Ignored when channel is portal.\n\nA public, unauthenticated portal link is always returned so it can be copied and shared directly. The portal page shows the supplier the amount owed, the due date, the line items that sold, and the payment terms.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"channel\": \"both\",\n  \"recipient_email\": \"ap@supplier.com\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/consignment/settlements/{settlement}/share","host":["{{baseUrl}}"],"path":["api","consignment","settlements",":settlement","share"],"variable":[{"key":"settlement","value":"9001","description":"Consignment settlement bill (purchase invoice) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"portal_url\": \"https://acme.example.com/consignment-report/hULzoBcZJh1nlGzqx3Rgp732pEfWwXfZKZ9huJ12S9W\",\n  \"emailed\": true,\n  \"recipient\": \"ap@supplier.com\",\n  \"report\": {\n    \"supplier_name\": \"Acme Wholesale Co.\",\n    \"purchase_order_number\": \"PO-CONSIGN-1001\",\n    \"settlement_reference\": \"CONSIGN-PO-CONSIGN-1001-20260709-1\",\n    \"report_date\": \"2026-07-09\",\n    \"due_date\": \"2026-08-08\",\n    \"currency_code\": \"USD\",\n    \"lines\": [\n      {\n        \"sku\": \"WIDGET-BLUE\",\n        \"product_name\": \"Blue Widget\",\n        \"quantity\": 15,\n        \"unit_price\": 4,\n        \"amount\": 60\n      }\n    ],\n    \"total_units\": 15,\n    \"amount_owed\": 60,\n    \"payment_term\": {\n      \"name\": \"Consignment — Monthly, Net 30\",\n      \"settlement_frequency\": \"Monthly\",\n      \"net_days\": 30,\n      \"summary\": \"Consignment — Monthly, Net 30, payment due 30 days after this report\"\n    }\n  }\n}"}]},{"name":"Get Consignment Statement of Account","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/consignment/suppliers/{supplier}/statement","host":["{{baseUrl}}"],"path":["api","consignment","suppliers",":supplier","statement"],"variable":[{"key":"supplier","value":"42","description":"Supplier ID"}]},"description":"A rolling balance-forward statement of account for a supplier's consignment settlements: opening balance, each settlement with amount / paid / outstanding and a running balance, and the closing balance. The summary also reports the consignment liability that has accrued from sales but has not yet been settled.\n\nOptionally window the statement with date_from / date_to (m/d/Y or Y-m-d): settlements before date_from roll into the opening balance; settlements after date_to are excluded.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/consignment/suppliers/{supplier}/statement","host":["{{baseUrl}}"],"path":["api","consignment","suppliers",":supplier","statement"],"variable":[{"key":"supplier","value":"42","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"supplier_id\": 42,\n  \"supplier_name\": \"Acme Wholesale Co.\",\n  \"currency_code\": \"USD\",\n  \"date_from\": null,\n  \"date_to\": null,\n  \"opening_balance\": 0,\n  \"closing_balance\": 60,\n  \"lines\": [\n    {\n      \"settlement_id\": 9001,\n      \"date\": \"2026-01-15\",\n      \"due_date\": \"2026-02-14\",\n      \"reference\": \"CONSIGN-PO-CONSIGN-1001-20260115-1\",\n      \"purchase_order_id\": 1001,\n      \"purchase_order_number\": \"PO-CONSIGN-1001\",\n      \"amount\": 40,\n      \"paid\": 10,\n      \"outstanding\": 30,\n      \"running_balance\": 30,\n      \"status\": \"partially_paid\"\n    },\n    {\n      \"settlement_id\": 9014,\n      \"date\": \"2026-02-15\",\n      \"due_date\": \"2026-03-17\",\n      \"reference\": \"CONSIGN-PO-CONSIGN-1001-20260215-1\",\n      \"purchase_order_id\": 1001,\n      \"purchase_order_number\": \"PO-CONSIGN-1001\",\n      \"amount\": 30,\n      \"paid\": 0,\n      \"outstanding\": 30,\n      \"running_balance\": 60,\n      \"status\": \"unpaid\"\n    }\n  ],\n  \"summary\": {\n    \"settlement_count\": 2,\n    \"total_settled\": 70,\n    \"total_paid\": 10,\n    \"total_outstanding\": 60,\n    \"accrued_unsettled\": 45\n  }\n}"}]},{"name":"Get Consignment Aging Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/consignment/settings","host":["{{baseUrl}}"],"path":["api","consignment","settings"]},"description":"The consignment aging-alert configuration: whether aging alerts are sent, the age (in days on consignment) at which unsold consigned stock is flagged, and whether flagged stock is automatically returned to the supplier.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/consignment/settings","host":["{{baseUrl}}"],"path":["api","consignment","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"aging_alerts_enabled\": true,\n  \"aging_threshold_days\": 90,\n  \"aging_auto_return_enabled\": false\n}"}]},{"name":"Update Consignment Aging Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/consignment/settings","host":["{{baseUrl}}"],"path":["api","consignment","settings"]},"description":"Update the consignment aging-alert configuration. All fields are optional; only the provided fields are changed.\n\nFields:\n- aging_alerts_enabled (boolean): send aging alerts when consigned stock ages past the threshold.\n- aging_threshold_days (integer, 1-3650): age in days on consignment at which unsold stock is flagged.\n- aging_auto_return_enabled (boolean): automatically return flagged stock to the supplier. Off by default — returning consigned stock is irreversible.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"aging_alerts_enabled\": true,\n  \"aging_threshold_days\": 120,\n  \"aging_auto_return_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/consignment/settings","host":["{{baseUrl}}"],"path":["api","consignment","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"aging_alerts_enabled\": true,\n  \"aging_threshold_days\": 120,\n  \"aging_auto_return_enabled\": false\n}"}]},{"name":"List Purchase Order Revisions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/snapshots","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","snapshots"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]},"description":"List the immutable revision snapshots captured for a purchase order, newest first. A snapshot is recorded every time the order is sent to the supplier, so this is the complete send history of the order.\n\nEach snapshot preserves exactly what the supplier received at that revision — the line quantities and costs, the order totals, a content hash of the sent document, who sent it and when — together with the current acknowledgement status of that revision.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n\nResponse: a collection under `data`. Each item includes `revision_number`, `reason`, `submission_format`, `sent_to_email`, `sent_by_name`, `sent_at`, `acknowledgement_status` (one of `pending`, `acknowledged`, `changes_requested`, `rejected`, `superseded`), `acknowledged_at`, `document_hash`, `total_quantity` and `total_cost`.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.view`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/snapshots","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","snapshots"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"purchase_order_id\": 739,\n      \"revision_number\": 2,\n      \"reason\": \"Corrected qty per supplier\",\n      \"submission_format\": \"email_pdf_attachment\",\n      \"sent_to_email\": \"supplier@acme.com\",\n      \"sent_by_name\": \"K. Mizzi\",\n      \"sent_at\": \"2026-07-12T09:03:00+00:00\",\n      \"acknowledgement_status\": \"acknowledged\",\n      \"acknowledged_at\": \"2026-07-12T14:00:00+00:00\",\n      \"document_hash\": \"b659cce4f6fe9e5f...\",\n      \"total_quantity\": 124,\n      \"total_cost\": 289.4\n    }\n  ]\n}"}]},{"name":"Get Purchase Order Revision","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/snapshots/{snapshot}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","snapshots",":snapshot"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."},{"key":"snapshot","value":"12","description":"The snapshot ID."}]},"description":"Retrieve a single purchase order revision snapshot with its full header and line detail. The snapshot is a frozen copy of the order as it was sent to the supplier for that revision.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n- `snapshot` (required): id of the revision snapshot to retrieve.\n\nResponse: a single snapshot object (not wrapped in `data`) with the header summary, the captured `lines[]`, and the same top-level revision metadata returned by the list endpoint (`revision_number`, `reason`, `submission_format`, `sent_to_email`, `sent_by_name`, `sent_at`, `acknowledgement_status`, `acknowledged_at`, `document_hash`, `total_quantity`, `total_cost`).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.view`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/snapshots/{snapshot}","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","snapshots",":snapshot"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."},{"key":"snapshot","value":"12","description":"The snapshot ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"purchase_order_id\": 739,\n  \"revision_number\": 2,\n  \"reason\": \"Corrected qty per supplier\",\n  \"submission_format\": \"email_pdf_attachment\",\n  \"sent_to_email\": \"supplier@acme.com\",\n  \"sent_by_name\": \"K. Mizzi\",\n  \"sent_at\": \"2026-07-12T09:03:00+00:00\",\n  \"acknowledgement_status\": \"acknowledged\",\n  \"acknowledged_at\": \"2026-07-12T14:00:00+00:00\",\n  \"document_hash\": \"b659cce4...\",\n  \"total_quantity\": 124,\n  \"total_cost\": 289.4,\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 7,\n      \"product_id\": 7,\n      \"sku\": \"SKU-1042\",\n      \"description\": \"Widget A\",\n      \"quantity\": 74,\n      \"amount\": 3.1,\n      \"discount_rate\": 0,\n      \"tax_rate\": null,\n      \"line_total\": 229.4\n    }\n  ],\n  \"header\": {\n    \"purchase_order_number\": \"PO-000739\",\n    \"supplier_id\": 14,\n    \"supplier_name\": \"Acme Supply\",\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"estimated_delivery_date\": null,\n    \"etd\": null,\n    \"incoterm_code\": null,\n    \"payment_term_name\": null,\n    \"supplier_notes\": null,\n    \"total_quantity\": 124,\n    \"total_cost\": 289.4\n  }\n}"}]},{"name":"Get Changes Since Last Sent","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/changes-since-sent","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","changes-since-sent"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]},"description":"Compare the live purchase order against the most recent revision snapshot and return a line-level and header-level diff. Use it to detect when an order has been edited after it was last sent to the supplier, so those pending changes can be reviewed and re-sent.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n\nResponse under `data`:\n- `latest_revision_number` / `latest_sent_at` — the revision the live order is compared against.\n- `has_pending_changes` — `true` when the live order differs from that revision.\n- `changes_pending_since` — when the order first diverged from the sent revision.\n- `line_changes[]` — each entry has a `change_type` of `added`, `removed` or `modified`, and (for `modified`) a `fields[]` array of `{ field, from, to }`.\n- `header_changes[]` — same shape for header-level fields.\n\nIf the order has never been sent there is no revision to compare against.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.view`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/changes-since-sent","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","changes-since-sent"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_revision_number\": 1,\n    \"latest_sent_at\": \"2026-07-10T14:14:00+00:00\",\n    \"has_pending_changes\": true,\n    \"changes_pending_since\": \"2026-07-11T10:00:00+00:00\",\n    \"line_changes\": [\n      {\n        \"purchase_order_line_id\": 7,\n        \"sku\": \"SKU-1042\",\n        \"description\": \"Widget A\",\n        \"change_type\": \"modified\",\n        \"fields\": [\n          {\n            \"field\": \"quantity\",\n            \"from\": 76,\n            \"to\": 74\n          }\n        ]\n      }\n    ],\n    \"header_changes\": []\n  }\n}"}]},{"name":"Dismiss Pending Changes","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/changes-since-sent/dismiss","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","changes-since-sent","dismiss"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]},"description":"Dismiss the pending post-send changes on a purchase order without re-sending it. Use this when an order was edited after it was sent but the change does not need to go to the supplier — the supplier keeps the last sent revision.\n\nClears the pending-changes marker (the order returns to `submitted`) and remembers the dismissed state, so routine saves that leave the order unchanged will not raise it again. Any further material change to the order (lines, quantities, pricing, terms) re-raises the pending-changes state.\n\nNo new revision is created — `revision_number` is unchanged and the last sent revision remains what the supplier has. Dismissing an order with nothing pending is a no-op.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n\nReturns the updated purchase order under `data`.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/changes-since-sent/dismiss","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","changes-since-sent","dismiss"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 739,\n    \"purchase_order_number\": \"PO-0664\",\n    \"submission_status\": \"submitted\",\n    \"revision_number\": 1,\n    \"changes_pending_since\": null\n  }\n}"}]},{"name":"List Supplier Responses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]},"description":"List the supplier responses recorded against a purchase order's sent revisions, newest first. A response captures how the supplier replied to a revision they received — accepting it, requesting changes, or rejecting it — optionally with per-line confirmed quantities, costs and dates.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n\nResponse: a collection under `data`. Each item includes `response_type` (`accepted`, `changes_requested` or `rejected`), `source`, `responder`, `note`, `recorded_by_name`, `responded_at`, the `purchase_order_snapshot_id` the response applies to, and a `lines[]` array of the supplier-confirmed line detail.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.view`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"purchase_order_id\": 739,\n      \"purchase_order_snapshot_id\": 11,\n      \"response_type\": \"changes_requested\",\n      \"source\": \"internal\",\n      \"responder\": \"Jane @ Acme\",\n      \"note\": \"MOQ is 74\",\n      \"recorded_by_name\": \"K. Mizzi\",\n      \"responded_at\": \"2026-07-11T12:00:00+00:00\",\n      \"lines\": [\n        {\n          \"id\": 9,\n          \"purchase_order_line_id\": 7,\n          \"sku\": \"SKU-1042\",\n          \"ordered_quantity\": 76,\n          \"confirmed_quantity\": 74,\n          \"confirmed_unit_cost\": null,\n          \"confirmed_date\": null,\n          \"exception_code\": \"MIN\",\n          \"status\": \"changed\",\n          \"note\": \"MOQ is 74\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Record Supplier Response","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]},"description":"Record a supplier's response to a sent purchase order revision. Use it to log that the supplier accepted the order, requested changes, or rejected it, optionally capturing the quantities, costs and dates the supplier confirmed for individual lines.\n\nRecording an `accepted` response stamps the order's last supplier confirmation time. Recording a `changes_requested` response moves the order into a supplier-change state so the confirmed quantities can be reviewed and applied.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n\nBody:\n- `response_type` (required): one of `accepted`, `changes_requested`, `rejected`.\n- `source` (optional): one of `internal`, `supplier_portal`, `email`.\n- `responder` (nullable string): name of the person on the supplier side.\n- `note` (nullable string, max 5000).\n- `snapshot_id` (nullable integer): id of the revision snapshot the response applies to.\n- `lines` (optional array). For each line:\n    - `purchase_order_line_id` (required with `lines`, integer).\n    - `ordered_quantity` (nullable numeric).\n    - `confirmed_quantity` (nullable numeric).\n    - `confirmed_unit_cost` (nullable numeric).\n    - `confirmed_date` (nullable date).\n    - `exception_code` (nullable): one of `CAP`, `MAT`, `LOG`, `PRI`, `UOM`, `SUB`, `MIN`, `DOC`.\n    - `status` (required with `lines`): one of `accepted`, `changed`, `rejected`.\n    - `note` (nullable string).\n\nReturns the recorded response and the refreshed purchase order under `data`.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`","body":{"mode":"raw","raw":"{\n  \"response_type\": \"changes_requested\",\n  \"source\": \"internal\",\n  \"responder\": \"Jane @ Acme\",\n  \"note\": \"MOQ is 74\",\n  \"snapshot_id\": 11,\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 7,\n      \"ordered_quantity\": 76,\n      \"confirmed_quantity\": 74,\n      \"confirmed_unit_cost\": null,\n      \"confirmed_date\": null,\n      \"exception_code\": \"MIN\",\n      \"status\": \"changed\",\n      \"note\": \"MOQ is 74\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Supplier response recorded.\",\n  \"data\": {\n    \"response\": {\n      \"id\": 5,\n      \"purchase_order_id\": 739,\n      \"purchase_order_snapshot_id\": 11,\n      \"response_type\": \"changes_requested\",\n      \"source\": \"internal\",\n      \"responder\": \"Jane @ Acme\",\n      \"note\": \"MOQ is 74\",\n      \"recorded_by_name\": \"K. Mizzi\",\n      \"responded_at\": \"2026-07-11T12:00:00+00:00\",\n      \"lines\": [\n        {\n          \"id\": 9,\n          \"purchase_order_line_id\": 7,\n          \"sku\": \"SKU-1042\",\n          \"ordered_quantity\": 76,\n          \"confirmed_quantity\": 74,\n          \"confirmed_unit_cost\": null,\n          \"confirmed_date\": null,\n          \"exception_code\": \"MIN\",\n          \"status\": \"changed\",\n          \"note\": \"MOQ is 74\"\n        }\n      ]\n    },\n    \"purchase_order\": {\n      \"id\": 739,\n      \"purchase_order_number\": \"PO-000739\",\n      \"submission_status\": \"change_supplier\",\n      \"last_supplier_confirmed_at\": null\n    }\n  }\n}"}]},{"name":"Apply Supplier Confirmed Changes","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses/{response}/apply","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses",":response","apply"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."},{"key":"response","value":"5","description":"The response ID."}]},"description":"Apply a `changes_requested` supplier response's confirmed line quantities back onto the live purchase order. Each confirmed quantity is written to its line, respecting the floors already received or invoiced on that line so committed quantities are never reduced below what has already happened.\n\nApplying the confirmed changes creates a divergence between the live order and the last revision the supplier received, which the buyer then re-sends as a new revision.\n\nPath params:\n- `purchase_order` (required): id of the purchase order.\n- `response` (required): id of the supplier response to apply.\n\nNo request body.\n\nResponse under `data`: the refreshed `purchase_order`, an `applied` count of lines updated, and a `skipped[]` array describing any lines that could not be changed.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/supplier-responses/{response}/apply","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","supplier-responses",":response","apply"],"variable":[{"key":"purchase_order","value":"739","description":"The purchase order ID."},{"key":"response","value":"5","description":"The response ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Applied 1 supplier-confirmed line change(s).\",\n  \"data\": {\n    \"purchase_order\": {\n      \"id\": 739,\n      \"submission_status\": \"change_buyer\",\n      \"changes_pending_since\": \"2026-07-11T12:05:00+00:00\"\n    },\n    \"applied\": 1,\n    \"skipped\": []\n  }\n}"}]}]},{"name":"Purchase Invoices","item":[{"name":"List Purchase Invoices","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices?page=1&per_page=10&sort=-id&filter[status]=open&filter[supplier_invoice_number]=INV-001&filter[supplier_name]=&filter[currency]=&filter[purchase_invoice_date]=&filter[due_date]=&filter[other_date]=&filter[attachments_count]=&filter[attachment_filename]=&filter[created_at]=&filter[updated_at]=&filter[supplier_id]=&filter[id]=&filter[purchase_order_id]=&filter[purchase_order_number]=&filter[archived]=&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-invoices"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, purchase_invoice_date, due_date, other_date, supplier_invoice_number, status, purchase_order_id, supplier_id, created_at, updated_at, purchase_order_number, supplier_name, line_item_count, attachments_count","disabled":true},{"key":"filter[status]","value":"open","description":"Filter by invoice status (open, partial, paid, etc.)","disabled":true},{"key":"filter[supplier_invoice_number]","value":"INV-001","description":"Filter by supplier invoice number (text match)","disabled":true},{"key":"filter[supplier_name]","value":"","description":"Filter by supplier name (text match)","disabled":true},{"key":"filter[currency]","value":"","description":"Filter by currency code (text match)","disabled":true},{"key":"filter[purchase_invoice_date]","value":"","description":"Filter by invoice date (date/datetime)","disabled":true},{"key":"filter[due_date]","value":"","description":"Filter by due date","disabled":true},{"key":"filter[other_date]","value":"","description":"Filter by other date","disabled":true},{"key":"filter[attachments_count]","value":"","description":"Filter by number of attached documents (numeric). Supports is, is_not, greater_than, less_than, between, is_empty, is_not_empty. Use filter[attachments_count.is]=0 (or is_empty) to find invoices with no documents yet.","disabled":true},{"key":"filter[attachment_filename]","value":"","description":"Filter to invoices that have an attached document whose file name matches (text). Supports contains, is, starts_with, ends_with, is_empty, is_not_empty. e.g. filter[attachment_filename.contains]=packing-slip","disabled":true},{"key":"filter[created_at]","value":"","description":"Filter by created_at datetime","disabled":true},{"key":"filter[updated_at]","value":"","description":"Filter by updated_at datetime","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID (numeric)","disabled":true},{"key":"filter[id]","value":"","description":"Filter by invoice ID (numeric)","disabled":true},{"key":"filter[purchase_order_id]","value":"","description":"Filter by purchase order ID (exact match)","disabled":true},{"key":"filter[purchase_order_number]","value":"","description":"Filter by purchase order number (text match)","disabled":true},{"key":"filter[archived]","value":"","description":"archived filter: omit for non-archived only, 'only' for archived only, 'all' for all records","disabled":true},{"key":"filter[search]","value":"","description":"Search across supplier_invoice_number, id, supplier name, purchase_order_number","disabled":true}]},"description":"Get a paginated list of purchase invoices with filtering and sorting.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters use the filter[field] syntax. Text filters support operators like is, is_not, contains, starts_with, ends_with, is_empty, is_not_empty.\nNumeric filters support is, is_not, greater_than, less_than, between.\nDatetime filters support date range comparisons.\n\nAllowed sorts: id, purchase_invoice_date, due_date, other_date, supplier_invoice_number, status, purchase_order_id, supplier_id, created_at, updated_at, purchase_order_number, supplier_name, line_item_count, attachments_count.\n\nEach row includes attachments_count (number of attached documents) and attachment_filenames (their file names). Filter with filter[attachments_count] (e.g. =0 for invoices with no documents) or filter[attachment_filename] (match a document's file name).\nDefault sort: -id (newest first).\nDefault: excludes archived invoices unless filter[archived] is provided.\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices?page=1&per_page=10&sort=-id&filter[status]=open&filter[supplier_invoice_number]=INV-001&filter[supplier_name]=&filter[currency]=&filter[purchase_invoice_date]=&filter[due_date]=&filter[other_date]=&filter[attachments_count]=&filter[attachment_filename]=&filter[created_at]=&filter[updated_at]=&filter[supplier_id]=&filter[id]=&filter[purchase_order_id]=&filter[purchase_order_number]=&filter[archived]=&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-invoices"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, purchase_invoice_date, due_date, other_date, supplier_invoice_number, status, purchase_order_id, supplier_id, created_at, updated_at, purchase_order_number, supplier_name, line_item_count, attachments_count","disabled":true},{"key":"filter[status]","value":"open","description":"Filter by invoice status (open, partial, paid, etc.)","disabled":true},{"key":"filter[supplier_invoice_number]","value":"INV-001","description":"Filter by supplier invoice number (text match)","disabled":true},{"key":"filter[supplier_name]","value":"","description":"Filter by supplier name (text match)","disabled":true},{"key":"filter[currency]","value":"","description":"Filter by currency code (text match)","disabled":true},{"key":"filter[purchase_invoice_date]","value":"","description":"Filter by invoice date (date/datetime)","disabled":true},{"key":"filter[due_date]","value":"","description":"Filter by due date","disabled":true},{"key":"filter[other_date]","value":"","description":"Filter by other date","disabled":true},{"key":"filter[attachments_count]","value":"","description":"Filter by number of attached documents (numeric). Supports is, is_not, greater_than, less_than, between, is_empty, is_not_empty. Use filter[attachments_count.is]=0 (or is_empty) to find invoices with no documents yet.","disabled":true},{"key":"filter[attachment_filename]","value":"","description":"Filter to invoices that have an attached document whose file name matches (text). Supports contains, is, starts_with, ends_with, is_empty, is_not_empty. e.g. filter[attachment_filename.contains]=packing-slip","disabled":true},{"key":"filter[created_at]","value":"","description":"Filter by created_at datetime","disabled":true},{"key":"filter[updated_at]","value":"","description":"Filter by updated_at datetime","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID (numeric)","disabled":true},{"key":"filter[id]","value":"","description":"Filter by invoice ID (numeric)","disabled":true},{"key":"filter[purchase_order_id]","value":"","description":"Filter by purchase order ID (exact match)","disabled":true},{"key":"filter[purchase_order_number]","value":"","description":"Filter by purchase order number (text match)","disabled":true},{"key":"filter[archived]","value":"","description":"archived filter: omit for non-archived only, 'only' for archived only, 'all' for all records","disabled":true},{"key":"filter[search]","value":"","description":"Search across supplier_invoice_number, id, supplier name, purchase_order_number","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"purchase_order_id\": 15,\n      \"purchase_order_number\": \"PO-2024-0015\",\n      \"purchase_order\": {\n        \"id\": 15,\n        \"purchase_order_number\": \"PO-2024-0015\",\n        \"purchase_order_date\": \"2024-01-15T00:00:00+00:00\",\n        \"total\": 1250,\n        \"receipts\": []\n      },\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"supplier_id\": 7,\n      \"supplier_name\": \"Acme Supplies Ltd\",\n      \"status\": \"open\",\n      \"purchase_invoice_lines\": null,\n      \"financial_lines\": null,\n      \"purchase_invoice_date\": \"2024-01-20\",\n      \"due_date\": \"2024-02-20\",\n      \"other_date\": null,\n      \"currency_id\": 1,\n      \"currency_rate\": 1,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\",\n        \"name\": \"US Dollar\",\n        \"symbol\": \"$\"\n      },\n      \"line_item_count\": 3,\n      \"first_line_sku\": \"SKU-001\",\n      \"calculated_total\": 1250,\n      \"tax_total\": 125,\n      \"total_paid\": 0,\n      \"payments\": null,\n      \"approval_status\": \"approved\",\n      \"approved_by\": null,\n      \"approved_by_name\": null,\n      \"approved_at\": null,\n      \"approval_notes\": null,\n      \"tags\": [],\n      \"created_at\": \"2024-01-20T10:30:00.000000Z\",\n      \"updated_at\": \"2024-01-20T10:30:00.000000Z\",\n      \"archived_at\": null,\n      \"attachments_count\": 2,\n      \"attachment_filenames\": [\n        \"packing-slip.pdf\",\n        \"invoice-scan.pdf\"\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"unfiltered_total\": 612,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Create Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices","host":["{{baseUrl}}"],"path":["api","purchase-invoices"]},"description":"Create a new purchase invoice linked to a purchase order.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEither purchase_invoice_lines or financial_lines must be provided on creation.\nInvoice lines must belong to the specified purchase order and must not be fully invoiced.\n\nWhen financial_lines are provided, each entry requires: id (an existing financial_lines.id), quantity (numeric), and amount (numeric). A 422 is returned if any are missing.","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 15,\n  \"purchase_invoice_date\": \"2024-01-20\",\n  \"due_date\": \"2024-02-20\",\n  \"other_date\": null,\n  \"supplier_invoice_number\": \"INV-2024-001\",\n  \"status\": \"open\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"tags\": [\n    \"urgent\",\n    \"priority\"\n  ],\n  \"purchase_invoice_lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"quantity_invoiced\": 10,\n      \"unit_price\": 25\n    }\n  ],\n  \"financial_lines\": [\n    {\n      \"id\": 55,\n      \"quantity\": 1,\n      \"amount\": 120,\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrder\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices","host":["{{baseUrl}}"],"path":["api","purchase-invoices"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"purchase_order_id\": 15,\n    \"supplier_invoice_number\": \"INV-2024-001\",\n    \"supplier_id\": 7,\n    \"supplier_name\": \"Acme Supplies Ltd\",\n    \"status\": \"open\",\n    \"purchase_invoice_date\": \"2024-01-20\",\n    \"due_date\": \"2024-02-20\",\n    \"calculated_total\": 250,\n    \"tax_total\": 0,\n    \"total_paid\": 0,\n    \"approval_status\": \"approved\",\n    \"created_at\": \"2024-01-20T10:30:00.000000Z\",\n    \"updated_at\": \"2024-01-20T10:30:00.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"Purchase invoice created successfully\"\n}"}]},{"name":"Bulk Delete Purchase Invoices","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices","host":["{{baseUrl}}"],"path":["api","purchase-invoices"]},"description":"Bulk delete purchase invoices by IDs or by applying filters.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEither ids or apply_to_all must be provided. If apply_to_all is true, filters will be used to resolve which IDs to delete."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoices","host":["{{baseUrl}}"],"path":["api","purchase-invoices"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase Invoices deleted successfully\"\n}"}]},{"name":"Get Purchase Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]},"description":"Get a single purchase invoice with full detail including lines, financial lines, payments, and accounting transaction.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe `purchase_order` object includes `total_invoiced` — the discount-netted amount billed across every invoice on the purchase order (not just this one). Subtract it from `purchase_order.total` for the amount still to be invoiced on the order."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"purchase_order_id\": 15,\n    \"purchase_order_number\": \"PO-2024-0015\",\n    \"purchase_order\": {\n      \"id\": 15,\n      \"purchase_order_number\": \"PO-2024-0015\",\n      \"total\": 500,\n      \"total_invoiced\": 250\n    },\n    \"supplier_invoice_number\": \"INV-2024-001\",\n    \"supplier_id\": 7,\n    \"supplier_name\": \"Acme Supplies Ltd\",\n    \"status\": \"open\",\n    \"purchase_invoice_lines\": [\n      {\n        \"id\": 201,\n        \"purchase_order_line_id\": 101,\n        \"quantity_invoiced\": 10,\n        \"unit_price\": 25,\n        \"subtotal\": 250\n      }\n    ],\n    \"financial_lines\": [],\n    \"purchase_invoice_date\": \"2024-01-20\",\n    \"due_date\": \"2024-02-20\",\n    \"other_date\": null,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"currency\": {\n      \"id\": 1,\n      \"code\": \"USD\",\n      \"name\": \"US Dollar\",\n      \"symbol\": \"$\"\n    },\n    \"line_item_count\": 1,\n    \"first_line_sku\": \"SKU-001\",\n    \"calculated_total\": 250,\n    \"tax_total\": 0,\n    \"total_paid\": 0,\n    \"payments\": [],\n    \"approval_status\": \"approved\",\n    \"approved_by\": null,\n    \"approved_by_name\": null,\n    \"approved_at\": null,\n    \"approval_notes\": null,\n    \"tags\": [],\n    \"created_at\": \"2024-01-20T10:30:00.000000Z\",\n    \"updated_at\": \"2024-01-20T10:30:00.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Update Purchase Invoice","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]},"description":"Update an existing purchase invoice. All fields are optional on update (uses sometimes validation).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNote: purchase_order_id cannot be changed on update.\n\nWhen financial_lines are provided, each entry requires: id (an existing financial_lines.id), quantity (numeric), and amount (numeric). A 422 is returned if any are missing.","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_date\": \"2024-01-22\",\n  \"due_date\": \"2024-02-22\",\n  \"supplier_invoice_number\": \"INV-2024-001-REV\",\n  \"status\": \"open\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"tags\": [\n    \"revised\"\n  ],\n  \"purchase_invoice_lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"quantity_invoiced\": 12,\n      \"unit_price\": 25\n    }\n  ],\n  \"financial_lines\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"supplier_invoice_number\": \"INV-2024-001-REV\",\n    \"status\": \"open\",\n    \"calculated_total\": 300,\n    \"updated_at\": \"2024-01-22T14:00:00.000000Z\"\n  },\n  \"message\": \"Purchase invoice updated successfully\"\n}"}]},{"name":"Delete Purchase Invoice","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]},"description":"Delete a single purchase invoice. Also unlinks any associated financial lines.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Purchase Invoice deleted successfully\"\n}"}]},{"name":"Get Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/line-items","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","line-items"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Get the line items for a purchase invoice (used for expand row in the list view).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/line-items","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","line-items"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"sku\": \"SKU-001\",\n      \"product_name\": \"Widget A\",\n      \"product_id\": 55,\n      \"quantity_invoiced\": 10,\n      \"unit_price\": 25,\n      \"amount\": 25,\n      \"po_unit_price\": 24,\n      \"line_total\": 250\n    }\n  ]\n}"}]},{"name":"Get Shipment Prefill (From Invoice)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/shipment-prefill","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","shipment-prefill"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Build the prefill payload used by the Create Inbound Shipment from Invoice form.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns header info (supplier, PO, invoice number, default destination warehouse from PO), one row per non-fully-shipped invoice line with quantity_remaining_to_ship pre-filled, and soft warnings (e.g. fully-shipped lines).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/shipment-prefill","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","shipment-prefill"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purchase_invoice_id\": 42,\n    \"supplier_invoice_number\": \"INV-2024-001\",\n    \"supplier_id\": 7,\n    \"supplier_name\": \"Acme Supplies Ltd\",\n    \"purchase_order_id\": 15,\n    \"purchase_order_number\": \"PO-2024-0015\",\n    \"default_destination_warehouse_id\": 1,\n    \"lines\": [\n      {\n        \"purchase_invoice_line_id\": 201,\n        \"purchase_order_id\": 15,\n        \"purchase_order_line_id\": 101,\n        \"product_id\": 10,\n        \"product_sku\": \"SKU-001\",\n        \"product_name\": \"Widget A\",\n        \"quantity_invoiced\": 10,\n        \"quantity_already_shipped\": 0,\n        \"quantity_remaining_to_ship\": 10,\n        \"unit_price\": 25\n      }\n    ],\n    \"warnings\": []\n  }\n}"}]},{"name":"List Inbound Shipments for Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/inbound-shipments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","inbound-shipments"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"List all inbound shipments that were created from this purchase invoice. Used by the Inbound Shipments traceability panel on the invoice detail page.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/inbound-shipments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","inbound-shipments"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 87,\n      \"shipment_number\": \"IS-00087\",\n      \"status\": \"draft\",\n      \"status_label\": \"Draft\",\n      \"supplier_id\": 7,\n      \"purchase_invoice_id\": 42,\n      \"destination_warehouse_id\": 1,\n      \"carrier\": \"FedEx\",\n      \"tracking_number\": null,\n      \"shipping_method_id\": 3,\n      \"expected_arrival_date\": \"2025-06-01\",\n      \"actual_arrival_date\": null,\n      \"shipped_at\": null,\n      \"created_from_receipt\": false,\n      \"notes\": null,\n      \"created_by\": 1,\n      \"asn_last_sent_at\": null,\n      \"total_expected_quantity\": 10,\n      \"total_received_quantity\": 0,\n      \"inbound_shipment_lines_count\": 1,\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Supplies Ltd\"\n      },\n      \"destination_warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 3,\n        \"name\": \"Ground\"\n      },\n      \"creator\": {\n        \"id\": 1,\n        \"name\": \"Admin User\"\n      },\n      \"created_at\": \"2025-05-07T10:00:00.000000Z\",\n      \"updated_at\": \"2025-05-07T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Print Purchase Invoice PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseOrderId}/print","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseOrderId","print"],"variable":[{"key":"purchaseOrderId","value":"15","description":"Purchase ORDER id (not a purchase invoice id)."}]},"description":"Generate and stream a PDF of the purchase order invoice.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Important:** the `:purchaseOrderId` path parameter is a **purchase ORDER id**, not a purchase invoice id. Despite living under `/api/purchase-invoices/`, this endpoint looks up the purchase order and renders its invoice PDF.\n\nAuthentication: Requires Bearer token.\n\nResponse: Inline PDF file (application/pdf). Not a JSON response."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseOrderId}/print","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseOrderId","print"],"variable":[{"key":"purchaseOrderId","value":"15","description":"Purchase ORDER id (not a purchase invoice id)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary PDF content — open in browser or save as .pdf)"}]},{"name":"Reset Invoice Due Date to Term","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/reset-due-date","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","reset-due-date"],"variable":[{"key":"purchaseInvoice","value":"","description":"The purchase invoice ID."}]},"description":"Discards a manually-overridden due date on a supplier invoice and re-derives it from the effective payment term (the invoice's own term, else the linked purchase order's term, else the supplier default). The response's `due_date_source` returns to `derived` (or `none` when no term is resolvable).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/reset-due-date","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","reset-due-date"],"variable":[{"key":"purchaseInvoice","value":"","description":"The purchase invoice ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"supplier_invoice_number\": \"INV-88231\",\n    \"supplier_id\": 40,\n    \"purchase_order_id\": 707,\n    \"purchase_order_number\": \"PO-0636\",\n    \"purchase_invoice_date\": \"2026-01-01\",\n    \"due_date\": \"2026-01-31\",\n    \"due_date_source\": \"derived\",\n    \"payment_term_name\": \"Net 30\",\n    \"payment_term_snapshot\": {\n      \"payment_term_id\": 2,\n      \"name\": \"Net 30\",\n      \"net_days\": 30,\n      \"due_date_type\": \"from_invoice_date\",\n      \"discount_percentage\": 2,\n      \"discount_days\": 10,\n      \"captured_at\": \"2026-01-01T12:00:00+00:00\"\n    },\n    \"term_diverges_from_po\": false,\n    \"discount_due_date\": \"2026-01-11\",\n    \"discount_amount\": 20,\n    \"discount_available\": true,\n    \"payment_due_status\": \"not_due\",\n    \"days_until_due\": 30\n  }\n}"}]},{"name":"Bulk Archive Purchase Invoices","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/archive","host":["{{baseUrl}}"],"path":["api","purchase-invoices","archive"]},"description":"Bulk archive purchase invoices.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/archive","host":["{{baseUrl}}"],"path":["api","purchase-invoices","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase invoice archived successfully\"\n}"}]},{"name":"Bulk Unarchive Purchase Invoices","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/unarchive","host":["{{baseUrl}}"],"path":["api","purchase-invoices","unarchive"]},"description":"Bulk unarchive purchase invoices.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/unarchive","host":["{{baseUrl}}"],"path":["api","purchase-invoices","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase invoice unarchived successfully\"\n}"}]},{"name":"Archive Purchase Invoice","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/archive","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","archive"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Archive a single purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/archive","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","archive"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase invoice INV-2024-001 archived successfully\"\n}"}]},{"name":"Unarchive Purchase Invoice","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/unarchived","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","unarchived"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Unarchive a single purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/unarchived","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","unarchived"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase invoice INV-2024-001 unarchived successfully\"\n}"}]},{"name":"Check Deletability","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/deletable","host":["{{baseUrl}}"],"path":["api","purchase-invoices","deletable"]},"description":"Check whether purchase invoices can be deleted. Invoices are always deletable.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    42,\n    43\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/deletable","host":["{{baseUrl}}"],"path":["api","purchase-invoices","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 43,\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Create Custom (Fees Received) Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/fees-received","host":["{{baseUrl}}"],"path":["api","purchase-invoices","fees-received"]},"description":"Create a custom purchase invoice for fees (e.g., freight, handling). Fires events to recalculate FIFO layers and product averages.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 15,\n  \"purchase_invoice_date\": \"2024-01-20\",\n  \"supplier_invoice_number\": \"FEE-2024-001\",\n  \"supplier_id\": 7,\n  \"status\": \"open\",\n  \"total\": 150,\n  \"description\": \"Handling and freight fee\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/fees-received","host":["{{baseUrl}}"],"path":["api","purchase-invoices","fees-received"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"custom Purchase Invoice created successfully\"\n}"}]},{"name":"Approve Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Approve a purchase invoice that requires approval.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 422 if invoice is already approved.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Approved after review of line items\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"approval_status\": \"approved\",\n    \"approved_by\": 3,\n    \"approved_by_name\": \"Jane Smith\",\n    \"approved_at\": \"2024-01-22T09:15:00.000000Z\"\n  },\n  \"message\": \"Invoice approved successfully.\"\n}"}]},{"name":"Reject Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Reject a purchase invoice that requires approval.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: notes (string, max 1000 chars).","body":{"mode":"raw","raw":"{\n  \"notes\": \"Price variance exceeds acceptable threshold\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"approval_status\": \"rejected\",\n    \"approval_notes\": \"Price variance exceeds acceptable threshold\"\n  },\n  \"message\": \"Invoice rejected.\"\n}"}]},{"name":"Resubmit Purchase Invoice for Approval","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/resubmit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","resubmit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Re-submit a rejected invoice back to pending approval status.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly rejected invoices can be resubmitted. Returns 422 otherwise."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/resubmit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","resubmit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"approval_status\": \"pending\"\n  },\n  \"message\": \"Invoice resubmitted for approval.\"\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","generate-accounting-transaction"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Generate or regenerate the accounting transaction for a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","generate-accounting-transaction"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"status\": \"pending\",\n    \"total\": 250,\n    \"reference\": \"INV-2024-001\",\n    \"transaction_date\": \"2024-01-20T00:00:00+00:00\",\n    \"type\": \"purchase_invoice\"\n  },\n  \"message\": \"Accounting transaction generated successfully.\"\n}"}]},{"name":"Sync PO Price From Invoice Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/lines/{purchaseInvoiceLine}/sync-po-price","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","lines",":purchaseInvoiceLine","sync-po-price"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"purchaseInvoiceLine","value":"501","description":"Purchase invoice line ID (must belong to the invoice)"}]},"description":"Push the unit_price from a single invoice line up to the linked PO line's amount, then re-evaluate the invoice's approval status.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse this from the 3-Way Match view when a price variance is confirmed legitimate (e.g. supplier raised the price). The PO line is updated, an activity log entry is recorded on the PO line, and the invoice is re-evaluated — typically returning it to auto_approved once the price matches. Works on both open and closed POs.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- notes (string, optional, max 1000): free-text justification stored on the activity log entry.\n\nResult statuses:\n- updated: PO line amount changed; old_amount and new_amount are returned.\n- unchanged: PO line amount already matched invoice line unit price; no write occurred.\n- skipped: nothing was done. The reason field explains why. Possible reasons: 'invoice line not linked to a PO line', 'invoice line has no unit price'.\n\nReturns 404 if the invoice line does not belong to the purchase invoice.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Confirmed price increase with supplier\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/lines/{purchaseInvoiceLine}/sync-po-price","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","lines",":purchaseInvoiceLine","sync-po-price"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"purchaseInvoiceLine","value":"501","description":"Purchase invoice line ID (must belong to the invoice)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"result\": {\n      \"status\": \"updated\",\n      \"old_amount\": 12.65,\n      \"new_amount\": 13.48\n    },\n    \"invoice\": {\n      \"id\": 42,\n      \"reference\": \"INV-2024-001\",\n      \"approval_status\": \"auto_approved\",\n      \"purchase_order_id\": 17,\n      \"invoice_date\": \"2024-01-15\",\n      \"total\": 269.6\n    }\n  },\n  \"message\": \"PO price updated from invoice.\"\n}"}]},{"name":"Sync PO Prices Bulk","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/sync-po-prices","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","sync-po-prices"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Sync PO line prices from many invoice lines on a single invoice in one request, then re-evaluate the invoice's approval status once at the end.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse this from the 3-Way Match view when several lines have confirmed price variances. Each invoice line is processed individually using the same logic as POST /api/purchase-invoices/:purchaseInvoice/lines/:purchaseInvoiceLine/sync-po-price, and the final results are returned keyed by purchase_invoice_line_id. Works on both open and closed POs.\n\nAuthentication: Requires Bearer token.\n\nRequest body fields:\n- purchase_invoice_line_ids (integer[], required, min 1): IDs of invoice lines to sync. Each must belong to this purchase invoice (validated via Rule::exists with where purchase_invoice_id).\n- notes (string, optional, max 1000): free-text justification stored on each activity log entry.\n\nPer-line result statuses (same as single endpoint):\n- updated: PO line amount changed; old_amount and new_amount are returned.\n- unchanged: PO line amount already matched invoice line unit price.\n- skipped: nothing was done; reason is one of 'invoice line not found on this invoice', 'invoice line not linked to a PO line', 'invoice line has no unit price'.\n\nThe top-level message summarises counts (e.g. 'Synced 2 line(s); 1 unchanged; 0 skipped.').","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_line_ids\": [\n    501,\n    502,\n    503\n  ],\n  \"notes\": \"Bulk reconcile after supplier price update\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/sync-po-prices","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","sync-po-prices"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"results\": {\n      \"501\": {\n        \"status\": \"updated\",\n        \"old_amount\": 12.65,\n        \"new_amount\": 13.48\n      },\n      \"502\": {\n        \"status\": \"unchanged\",\n        \"old_amount\": 8.5,\n        \"new_amount\": 8.5\n      },\n      \"503\": {\n        \"status\": \"skipped\",\n        \"reason\": \"invoice line not linked to a PO line\"\n      }\n    },\n    \"invoice\": {\n      \"id\": 42,\n      \"reference\": \"INV-2024-001\",\n      \"approval_status\": \"auto_approved\",\n      \"purchase_order_id\": 17,\n      \"total\": 540.3\n    }\n  },\n  \"message\": \"Synced 1 line(s); 1 unchanged; 1 skipped.\"\n}"}]},{"name":"Get Variance Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/variance-report?per_page=15&filter[min_variance_percent]=5&filter[search]=Acme","host":["{{baseUrl}}"],"path":["api","purchase-invoices","variance-report"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[min_variance_percent]","value":"5","description":"Minimum price variance % to include (e.g. 5 = only show lines with >=5% variance)","disabled":true},{"key":"filter[search]","value":"Acme","description":"Search across supplier invoice number, supplier name, PO number, SKU, and product name","disabled":true}]},"description":"Get paginated price variance data comparing invoice prices vs. PO prices.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns purchase invoice lines where unit_price is set, with computed variance metrics."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/variance-report?per_page=15&filter[min_variance_percent]=5&filter[search]=Acme","host":["{{baseUrl}}"],"path":["api","purchase-invoices","variance-report"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[min_variance_percent]","value":"5","description":"Minimum price variance % to include (e.g. 5 = only show lines with >=5% variance)","disabled":true},{"key":"filter[search]","value":"Acme","description":"Search across supplier invoice number, supplier name, PO number, SKU, and product name","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"purchase_invoice_id\": 42,\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"purchase_order_number\": \"PO-2024-0015\",\n      \"purchase_order_id\": 15,\n      \"supplier_name\": \"Acme Supplies Ltd\",\n      \"invoice_date\": \"2024-01-20\",\n      \"invoice_status\": \"open\",\n      \"sku\": \"SKU-001\",\n      \"product_name\": \"Widget A\",\n      \"quantity_invoiced\": 10,\n      \"po_unit_price\": 24,\n      \"invoice_unit_price\": 25,\n      \"price_variance\": 1,\n      \"price_variance_percent\": 4.17,\n      \"extended_variance\": 10\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 12\n}"}]},{"name":"Get Three-Way Match Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/three-way-match","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","three-way-match"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Get three-way match data for an invoice: compares PO quantities/prices, received quantities, and invoice quantities/prices.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReceipt sources (matches PurchaseOrderLine::getEffectiveReceivedQuantity):\n- Amazon AWD destination POs: receipts come from amazon_awd_ledgers (matched receipts).\n- Amazon FBA destination POs: receipts come from amazon_ledgers (matched receipts).\n- Standard warehouse destinations: receipts come from inbound_shipment_receipt_lines.\n\nQty match statuses: match, over_invoiced, under_invoiced.\n\nResponse fields:\n- lines[]: per-PO-line comparison (po_quantity, received_quantity, invoice_quantity, price_variance, qty_match_status, receipts[]).\n- financial_lines[]: non-product invoice lines (freight, fees, etc.).\n- has_receipts: true if any line has a non-zero received_quantity.\n\nQuantity reconciliation is evaluated at the purchase-order-line level across every invoice and matched vendor credit on the order, adjusted for short-closes and explicit billing settlement — not for this invoice in isolation. A line split across multiple invoices, or offset by a credit, reports `qty_match_status` = `match`.\n\nPer-line fields: `invoiced_all_quantity` (billed across all invoices on the PO), `credited_quantity` (matched credits on the line), `effective_ordered_quantity` (ordered, after short-close), `net_invoiced_quantity` (invoiced − credited), and `qty_status_reason` (human-readable explanation of the status)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/three-way-match","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","three-way-match"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"lines\": [\n      {\n        \"purchase_order_line_id\": 101,\n        \"product_id\": 55,\n        \"sku\": \"SKU-001\",\n        \"product_name\": \"Widget A\",\n        \"po_quantity\": 20,\n        \"po_unit_price\": 12.65,\n        \"received_quantity\": 20,\n        \"receipts\": [\n          {\n            \"id\": 9001,\n            \"received_at\": \"2024-05-27\",\n            \"quantity\": 20\n          }\n        ],\n        \"invoice_quantity\": 20,\n        \"invoice_unit_price\": 13.48,\n        \"price_variance\": 0.83,\n        \"price_variance_percent\": 6.56,\n        \"qty_match_status\": \"match\",\n        \"invoiced_all_quantity\": 20,\n        \"credited_quantity\": 0,\n        \"effective_ordered_quantity\": 20,\n        \"net_invoiced_quantity\": 20,\n        \"qty_status_reason\": \"Reconciled: 20 net invoiced matches 20 ordered across all invoices on this PO.\",\n        \"po_extended\": 253,\n        \"invoice_extended\": 269.6\n      }\n    ],\n    \"financial_lines\": [\n      {\n        \"id\": 33,\n        \"description\": \"Freight\",\n        \"quantity\": 1,\n        \"invoice_amount\": 25\n      }\n    ],\n    \"has_receipts\": true\n  }\n}"}]},{"name":"Variance Resolution Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/variance-resolution-preview","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","variance-resolution-preview"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Preview over-billed quantities per PO line so the UI can prefill a 'Resolve with vendor credit' dialog.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nA line is considered over-billed when its effective invoiced quantity (quantity_invoiced minus quantity already credited on this bill via existing vendor credit allocations) exceeds the PO line's effective received quantity. Receipt sources match `PurchaseOrderLine::getEffectiveReceivedQuantity` (standard warehouse receipts, FBA/AWD ledgers, accounting for any active short-close event).\n\nThe suggested credit quantity is exactly the over-bill delta. The suggested credit amount is `over_billed * unit_price` (invoice unit price, falling back to PO amount).\n\nResponse fields:\n- `invoice_id`, `purchase_order_id`, `supplier_id`, `currency_id`, `currency_code`\n- `has_over_bills`: true if any line has over-billed quantity\n- `total_suggested_credit`: sum of `suggested_credit_amount` across over-billed lines\n- `lines[]`: only includes lines with over-billed quantity. Each line has `purchase_invoice_line_id`, `purchase_order_line_id`, `product_id`, `sku`, `product_name`, `quantity_invoiced`, `received_quantity`, `already_credited`, `over_billed_quantity`, `suggested_credit_quantity`, `unit_price`, `suggested_credit_amount`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/variance-resolution-preview","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","variance-resolution-preview"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"invoice_id\": 42,\n    \"purchase_order_id\": 18,\n    \"supplier_id\": 7,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"has_over_bills\": true,\n    \"total_suggested_credit\": 39.5,\n    \"lines\": [\n      {\n        \"purchase_invoice_line_id\": 301,\n        \"purchase_order_line_id\": 101,\n        \"product_id\": 55,\n        \"sku\": \"T-NS02-OAK-CV\",\n        \"product_name\": \"Oak Canvas\",\n        \"quantity_invoiced\": 91,\n        \"received_quantity\": 89,\n        \"already_credited\": 0,\n        \"over_billed_quantity\": 2,\n        \"suggested_credit_quantity\": 2,\n        \"unit_price\": 19.75,\n        \"suggested_credit_amount\": 39.5\n      }\n    ]\n  }\n}"}]},{"name":"Resolve with Vendor Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/resolve-with-credit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","resolve-with-credit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Resolve an over-billed purchase invoice by issuing a vendor credit for the over-billed quantities and auto-allocating it against the bill.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe credit is created in `open` status with `restock_inventory=false` (it's a billing correction, not a physical return). After the credit is allocated, the invoice's approval status is re-evaluated so the variance flag clears automatically when the credit fully offsets the over-bill.\n\nRequest body fields:\n- `lines` (required, min 1): array of `{ purchase_order_line_id, quantity }`. Each `quantity` must be > 0 and ≤ the over-billed quantity for that PO line.\n- `credit_date` (optional, nullable, date): defaults to today.\n- `supplier_reference` (optional, nullable, max 255): defaults to the invoice's `supplier_invoice_number`.\n- `reason` (optional, nullable, max 2000): copied into the vendor credit's note.\n\nValidation errors return 422 with a `message` for: invoice not linked to a PO, PO line not on this invoice, PO line not on this invoice's PO, requested quantity exceeds over-billed delta, or no over-billed quantities provided.\n\nReturns the newly created VendorCredit (eager-loaded with supplier, currency, lines, and allocations).","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"quantity\": 2\n    }\n  ],\n  \"credit_date\": \"2026-05-14\",\n  \"supplier_reference\": \"N26A038\",\n  \"reason\": \"Short-shipped 2 units against billed quantity.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/resolve-with-credit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","resolve-with-credit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"supplier_id\": 7,\n    \"purchase_order_id\": 18,\n    \"currency_id\": 1,\n    \"credit_date\": \"2026-05-14\",\n    \"credit_status\": \"open\",\n    \"supplier_reference\": \"N26A038\",\n    \"vendor_credit_note\": \"Short-shipped 2 units against billed quantity.\",\n    \"total_credit\": 39.5,\n    \"allocated_amount\": 39.5,\n    \"remaining_amount\": 0,\n    \"vendor_credit_lines\": [\n      {\n        \"id\": 220,\n        \"purchase_order_line_id\": 101,\n        \"product_id\": 55,\n        \"quantity\": 2,\n        \"amount\": 19.75,\n        \"restock_inventory\": false\n      }\n    ],\n    \"vendor_credit_allocations\": [\n      {\n        \"id\": 130,\n        \"purchase_invoice_id\": 42,\n        \"amount\": 39.5\n      }\n    ]\n  }\n}"}]},{"name":"List Activity Log Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/activity-log?per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search across causer name, properties, and event","disabled":true}],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Get paginated activity log entries for a purchase invoice.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/activity-log?per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search across causer name, properties, and event","disabled":true}],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"PurchaseInvoice\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"old\": {\n          \"status\": \"open\"\n        },\n        \"attributes\": {\n          \"status\": \"partial\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2024-01-22T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 5\n}"}]},{"name":"Export Purchase Invoices","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/list/export?format=xlsx&content_mode=summary&scope=filtered&ids=&columns=id,supplier_invoice_number,status","host":["{{baseUrl}}"],"path":["api","purchase-invoices","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"content_mode","value":"summary","description":"Export mode: summary (one row per invoice) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Scope: all, filtered, current_page, or selected","disabled":true},{"key":"ids","value":"","description":"Comma-separated IDs when scope=selected","disabled":true},{"key":"columns","value":"id,supplier_invoice_number,status","description":"Comma-separated column keys to include. Available: id, supplier_invoice_number, purchase_order_number, supplier_name, status, purchase_invoice_date, due_date, other_date, currency_code, calculated_total, tax_total, total_paid, created_at, updated_at, archived_at","disabled":true}]},"description":"Export purchase invoices as XLSX or CSV.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download (xlsx or csv). Not a JSON response.\n\nColumn keys: id, supplier_invoice_number, purchase_order_number, supplier_name, status, purchase_invoice_date, due_date, other_date, currency_code, calculated_total, tax_total, total_paid, created_at, updated_at, archived_at.\n\nIn line_items mode, additional columns are added for each line: item_sku, item_name, item_quantity_invoiced, item_amount, item_line_total."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/list/export?format=xlsx&content_mode=summary&scope=filtered&ids=&columns=id,supplier_invoice_number,status","host":["{{baseUrl}}"],"path":["api","purchase-invoices","list","export"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"content_mode","value":"summary","description":"Export mode: summary (one row per invoice) or line_items (one row per line item)","disabled":true},{"key":"scope","value":"filtered","description":"Scope: all, filtered, current_page, or selected","disabled":true},{"key":"ids","value":"","description":"Comma-separated IDs when scope=selected","disabled":true},{"key":"columns","value":"id,supplier_invoice_number,status","description":"Comma-separated column keys to include. Available: id, supplier_invoice_number, purchase_order_number, supplier_name, status, purchase_invoice_date, due_date, other_date, currency_code, calculated_total, tax_total, total_paid, created_at, updated_at, archived_at","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary xlsx/csv file)"}]},{"name":"Get Payables Aging Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/aging-report","host":["{{baseUrl}}"],"path":["api","purchase-invoices","aging-report"]},"description":"Supplier payables aging report over outstanding (unpaid and partially paid) purchase invoices and, optionally, bills.\n\nAuthentication: Requires Bearer token.\n\nRecords are bucketed by days past the selected age-by date: current (not yet past, or no date), 1-30, 31-60, 61-90, and 90+ days. Amounts are converted to the tenant currency using each record's exchange-rate snapshot. The summary block reports total outstanding, total overdue (past due date), and the amount due within the next 7 days. Rows are grouped by supplier, sorted by total outstanding descending, and each row includes the individual invoice/bill records that make up its buckets."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/aging-report","host":["{{baseUrl}}"],"path":["api","purchase-invoices","aging-report"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"total_outstanding\": 42300,\n      \"total_overdue\": 9120,\n      \"due_this_week\": 6540,\n      \"currency\": \"USD\",\n      \"age_by\": \"due_date\"\n    },\n    \"buckets\": {\n      \"current\": 33180,\n      \"d1_30\": 5100,\n      \"d31_60\": 2820,\n      \"d61_90\": 700,\n      \"d90_plus\": 500\n    },\n    \"rows\": [\n      {\n        \"supplier_id\": 12,\n        \"supplier_name\": \"Acme Supplies Ltd\",\n        \"current\": 4120,\n        \"d1_30\": 980,\n        \"d31_60\": 0,\n        \"d61_90\": 0,\n        \"d90_plus\": 0,\n        \"total\": 5100,\n        \"items\": [\n          {\n            \"id\": 42,\n            \"type\": \"invoice\",\n            \"number\": \"INV-2024-001\",\n            \"supplier_id\": 12,\n            \"supplier_name\": \"Acme Supplies Ltd\",\n            \"invoice_date\": \"2024-01-20\",\n            \"due_date\": \"2024-02-19\",\n            \"days_overdue\": 12,\n            \"bucket\": \"d1_30\",\n            \"outstanding\": 980,\n            \"currency_code\": \"USD\",\n            \"outstanding_in_tenant_currency\": 980\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Download Due-Date Calendar Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/calendar.ics","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","calendar.ics"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Download a single-event iCalendar (.ics) file for the invoice's payment due date, suitable for importing into Outlook, Apple Calendar, or any calendar app.\n\nAuthentication: Requires Bearer token.\n\nThe response is a text/calendar file download (not JSON) containing one all-day VEVENT on the due date with a stable UID, so re-importing an updated file replaces the earlier event. The event carries popup reminders 7 days and 1 day before the deadline.\n\nReturns 422 when the invoice has no payment due date."},"response":[{"name":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/calendar.ics","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","calendar.ics"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unauthenticated.\"\n}"}]},{"name":"List Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Get paginated notes for a purchase invoice, ordered by newest first.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"note\": \"Confirmed with supplier.\",\n      \"is_pinned\": false,\n      \"created_at\": \"2024-01-21T08:00:00.000000Z\",\n      \"user\": {\n        \"id\": 3,\n        \"name\": \"Jane Smith\"\n      }\n    }\n  ],\n  \"current_page\": 1\n}"}]},{"name":"Add Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Add a note to a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: note (string).","body":{"mode":"raw","raw":"{\n  \"note\": \"Checked with supplier — price correct.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"note\": \"Checked with supplier — price correct.\",\n    \"is_pinned\": false,\n    \"created_at\": \"2024-01-22T11:30:00.000000Z\",\n    \"user\": {\n      \"id\": 3,\n      \"name\": \"Jane Smith\"\n    }\n  },\n  \"message\": \"note created successfully\"\n}"}]},{"name":"Toggle Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes",":noteId","toggle-pin"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"noteId","value":"5","description":"Note ID"}]},"description":"Toggle the pinned state of a note on a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes",":noteId","toggle-pin"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"noteId","value":"5","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"note\": \"Confirmed with supplier.\",\n    \"is_pinned\": true,\n    \"user\": {\n      \"id\": 3,\n      \"name\": \"Jane Smith\"\n    }\n  },\n  \"message\": \"Note pinned\"\n}"}]},{"name":"Delete Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes",":noteId"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"noteId","value":"5","description":"Note ID"}]},"description":"Delete a note from a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","notes",":noteId"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"},{"key":"noteId","value":"5","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 5 deleted successfully\"\n}"}]},{"name":"List Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"}]},"description":"List all payments for a purchase invoice.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"amount\": 250,\n      \"cost\": null,\n      \"payment_date\": \"2024-02-01\",\n      \"payment_type\": {\n        \"id\": 1,\n        \"name\": \"Bank Transfer\"\n      },\n      \"external_reference\": \"TXN-12345\",\n      \"type\": null,\n      \"currency_code\": \"USD\"\n    }\n  ]\n}"}]},{"name":"Create Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"}]},"description":"Record a payment against a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: payment_type_id, amount. Payment date defaults to today if omitted.\nAmount must not exceed the remaining balance. Negative amounts are allowed for refunds (cannot exceed total paid).","body":{"mode":"raw","raw":"{\n  \"payment_date\": \"2024-02-01\",\n  \"payment_type_id\": 1,\n  \"external_reference\": \"TXN-12345\",\n  \"amount\": 250,\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"amount\": 250,\n    \"payment_date\": \"2024-02-01\",\n    \"payment_type\": {\n      \"id\": 1,\n      \"name\": \"Bank Transfer\"\n    },\n    \"external_reference\": \"TXN-12345\",\n    \"currency_code\": \"USD\"\n  },\n  \"message\": \"purchase invoice payment created successfully\"\n}"}]},{"name":"Get Payment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]},"description":"Get a single payment for a purchase invoice.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"amount\": 250,\n    \"payment_date\": \"2024-02-01\",\n    \"payment_type\": {\n      \"id\": 1,\n      \"name\": \"Bank Transfer\"\n    },\n    \"external_reference\": \"TXN-12345\",\n    \"currency_code\": \"USD\"\n  }\n}"}]},{"name":"Update Payment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]},"description":"Update a payment on a purchase invoice. All fields are optional on update.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNote: payment_type_id cannot be changed for credit payment types (system-created).","body":{"mode":"raw","raw":"{\n  \"payment_date\": \"2024-02-05\",\n  \"payment_type_id\": 1,\n  \"external_reference\": \"TXN-12345-REVISED\",\n  \"amount\": 250,\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"amount\": 250,\n    \"payment_date\": \"2024-02-05\",\n    \"external_reference\": \"TXN-12345-REVISED\"\n  },\n  \"message\": \"purchase invoice payment 10 updated successfully\"\n}"}]},{"name":"Delete Payment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]},"description":"Delete a payment from a purchase invoice.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoiceId}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoiceId","payments",":payment"],"variable":[{"key":"purchaseInvoiceId","value":"42","description":"Purchase invoice ID"},{"key":"payment","value":"10","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase invoice payment 10 deleted successfully\"\n}"}]},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/import/template","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import","template"]},"description":"Download an XLSX import template with headers, sample data, field guide, and reference data from the tenant's account.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary XLSX file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/import/template","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary XLSX file — save as purchase-invoices-import-template.xlsx)"}]},{"name":"Validate Import Data","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/import/validate","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import","validate"]},"description":"Validate mapped import data and return a grouped preview. No side effects — safe to call repeatedly.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: rows array with at least one item.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"purchase_order_number\": \"PO-2024-0015\",\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"purchase_invoice_date\": \"2024-01-20\",\n      \"due_date\": \"2024-02-20\",\n      \"other_date\": null,\n      \"currency_code\": \"USD\",\n      \"sku\": \"SKU-001\",\n      \"quantity_invoiced\": 10\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/import/validate","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"valid\": [\n    {\n      \"purchase_order_id\": 15,\n      \"purchase_order_number\": \"PO-2024-0015\",\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"lines\": [\n        {\n          \"sku\": \"SKU-001\",\n          \"purchase_order_line_id\": 101,\n          \"quantity_invoiced\": 10\n        }\n      ]\n    }\n  ],\n  \"errors\": []\n}"}]},{"name":"Execute Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/import","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import"]},"description":"Execute the import — create purchase invoices from validated data.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: purchase_invoices array where each item has purchase_order_id, supplier_invoice_number, purchase_invoice_date, and lines with purchase_order_line_id and quantity_invoiced.\n\nReturns 201 on success, 422 on validation or import failure.","body":{"mode":"raw","raw":"{\n  \"purchase_invoices\": [\n    {\n      \"purchase_order_id\": 15,\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"purchase_invoice_date\": \"2024-01-20\",\n      \"due_date\": \"2024-02-20\",\n      \"other_date\": null,\n      \"currency_id\": 1,\n      \"lines\": [\n        {\n          \"purchase_order_line_id\": 101,\n          \"quantity_invoiced\": 10\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/import","host":["{{baseUrl}}"],"path":["api","purchase-invoices","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"created\": 1,\n  \"errors\": []\n}"}]},{"name":"List Purchase Invoice Attachments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]},"description":"List all file attachments on a purchase invoice, ordered oldest first.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach attachment includes its OCR scan state: `ocr_status` is `null` (never scanned), `pending`, `processing`, `completed`, or `failed`. `download_url` is an absolute URL to the download endpoint.\n\nRequires the `purchase-orders:read` token scope. Returns the full list — this endpoint is not paginated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 45,\n      \"file_name\": \"supplier-invoice-march.pdf\",\n      \"file_size\": 482113,\n      \"mime_type\": \"application/pdf\",\n      \"created_at\": \"2026-07-01T14:23:45.000000Z\",\n      \"uploaded_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Doe\"\n      },\n      \"download_url\": \"https://acme.sku.io/api/purchase-invoices/123/attachments/45/download\",\n      \"ocr_status\": \"completed\",\n      \"ocr_error_message\": null,\n      \"ocr_processed_at\": \"2026-07-01T14:25:02.000000Z\"\n    },\n    {\n      \"id\": 46,\n      \"file_name\": \"packing-list.png\",\n      \"file_size\": 120441,\n      \"mime_type\": \"image/png\",\n      \"created_at\": \"2026-07-02T09:10:11.000000Z\",\n      \"uploaded_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Doe\"\n      },\n      \"download_url\": \"https://acme.sku.io/api/purchase-invoices/123/attachments/46/download\",\n      \"ocr_status\": null,\n      \"ocr_error_message\": null,\n      \"ocr_processed_at\": null\n    }\n  ]\n}"}]},{"name":"Upload Purchase Invoice Attachment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]},"description":"Upload a file attachment to a purchase invoice. Send as `multipart/form-data` with a `file` field and an optional `category` field.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAccepted types: PDF, DOC, DOCX, PNG, JPG/JPEG. Maximum size 20 MB. Uploading to an archived invoice returns 422.\n\nFields:\n- file (required): The file to attach.\n- category (optional): Document category — one of `invoice`, `payment_proof`, or `other`. Defaults to `other`.\n\nSide effects:\n- If the invoice is already synced to a connected accounting provider (QuickBooks Online / Xero), the file is forwarded to the remote document asynchronously.\n- If Invoice OCR is enabled with auto-scan on upload and the file is a PDF, an OCR scan is queued automatically in the background — the returned attachment will show `ocr_status: \"processing\"`.\n\nRequires the `purchase-orders:write` token scope.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"category","type":"text","value":""}]}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 47,\n    \"file_name\": \"supplier-invoice-april.pdf\",\n    \"file_size\": 391208,\n    \"mime_type\": \"application/pdf\",\n    \"category\": \"invoice\",\n    \"category_label\": \"Invoice\",\n    \"created_at\": \"2026-07-06T10:15:30.000000Z\",\n    \"uploaded_by\": {\n      \"id\": 3,\n      \"name\": \"Jane Doe\"\n    },\n    \"download_url\": \"https://acme.sku.io/api/purchase-invoices/123/attachments/47/download\",\n    \"ocr_status\": null,\n    \"ocr_error_message\": null,\n    \"ocr_processed_at\": null\n  }\n}"}]},{"name":"Delete Purchase Invoice Attachment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]},"description":"Delete an attachment from a purchase invoice. Removes both the stored file and its record, including any OCR extraction history for the attachment.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 404 if the attachment does not belong to the given invoice.\n\nRequires the `purchase-orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Attachment deleted.\"\n}"}]},{"name":"Download Purchase Invoice Attachment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/download","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","download"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]},"description":"Download the attachment file. The response is a file stream (not JSON) with `Content-Disposition: attachment` and the original file name, so clients save it as a download. The `Content-Type` matches the stored file type (e.g. `application/pdf`).\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 404 if the attachment does not belong to the given invoice.\n\nRequires the `purchase-orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/download","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","download"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary file stream)"}]},{"name":"View Purchase Invoice Attachment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/view","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","view"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]},"description":"Stream the attachment file for inline display. Identical to the download endpoint except the response uses `Content-Disposition: inline`, so browsers render PDFs and images in the tab instead of saving them.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 404 if the attachment does not belong to the given invoice.\n\nRequires the `purchase-orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/view","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","view"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary file stream)"}]},{"name":"Preview Payment Approval Routing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/payment-request-routing","host":["{{baseUrl}}"],"path":["api","purchase-invoices","payment-request-routing"]},"description":"Preview where a bill payment request of a given amount would be routed, before submitting it. Returns the routing mode and the resolved payer (if the amount routes directly to a single payer).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- amount (optional, numeric, >= 0): Amount to evaluate. Defaults to 0.\n\nRouting modes: approval_levels (multi-step approval chain), payer (single designated payer to send the request to), self_payer (the acting user is the designated payer, so they approve and record the payment directly instead of sending a request to themselves), threshold_approval (single approval against a threshold), auto_approve (no approval required)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/payment-request-routing","host":["{{baseUrl}}"],"path":["api","purchase-invoices","payment-request-routing"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"mode\": \"approval_levels\",\n  \"payer\": {\n    \"id\": 5,\n    \"name\": \"Sam Manager\",\n    \"email\": \"sam@company.com\"\n  },\n  \"payer_configured\": true,\n  \"levels_count\": 2\n}"}]},{"name":"Submit Bill Payment for Approval","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/submit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","submit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Submit a bill's outstanding balance for payment authorization. Routes the request to the appropriate approval chain, designated payer, or auto-approves it depending on configuration and amount.\n\nAuthentication: Requires Bearer token.\n\nThis endpoint has no request body — the outstanding balance is used automatically. Returns the updated bill including its payment approval status and generated approval steps.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/submit","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","submit"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"open\",\n  \"outstanding_balance\": 1250,\n  \"payment_approval_status\": \"pending_approval\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": null,\n  \"payment_approved_by_name\": null,\n  \"payment_approved_at\": null,\n  \"payment_approval_notes\": null,\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"pending\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": null,\n      \"actioned_at\": null,\n      \"notes\": null\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Approve and Pay Bill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Approve a pending bill payment request and record the payment in a single step. The payment amount defaults to the bill's outstanding balance when omitted.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- amount (optional, numeric, > 0): Payment amount. Defaults to the outstanding balance.\n- payment_date (required, date): Date the payment was made.\n- currency_rate (optional, numeric, > 0): Exchange rate. Defaults to the bill's rate.\n- payment_type_id (optional, integer): Payment method ID.\n- external_reference (optional, max 255): External reference; alias 'reference' is also accepted.\n- notes (optional, max 1000): Approval notes.","body":{"mode":"raw","raw":"{\n  \"amount\": 1250,\n  \"payment_date\": \"2026-07-10\",\n  \"payment_type_id\": 2,\n  \"external_reference\": \"WIRE-99812\",\n  \"notes\": \"Verified against receipt.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"paid\",\n  \"outstanding_balance\": 0,\n  \"payment_approval_status\": \"approved\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": 5,\n  \"payment_approved_by_name\": \"Sam Manager\",\n  \"payment_approved_at\": \"2026-07-10T15:10:00+00:00\",\n  \"payment_approval_notes\": \"Verified against receipt.\",\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": 5,\n      \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n      \"notes\": \"Verified against receipt.\"\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Approve Bill Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/approve-only","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","approve-only"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Approve a pending bill payment request without recording a payment. Use this when authorization and payment are handled separately.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- notes (optional, max 1000): Approval notes.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Approved — finance will pay on Friday.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/approve-only","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","approve-only"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"open\",\n  \"outstanding_balance\": 1250,\n  \"payment_approval_status\": \"approved\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": 5,\n  \"payment_approved_by_name\": \"Sam Manager\",\n  \"payment_approved_at\": \"2026-07-10T15:10:00+00:00\",\n  \"payment_approval_notes\": \"Verified against receipt.\",\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": 5,\n      \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n      \"notes\": \"Verified against receipt.\"\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Record Bill Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/record-payment","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","record-payment"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Record a payment against a bill whose payment has already been approved.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- amount (required, numeric, > 0): Payment amount.\n- payment_date (required, date): Date the payment was made.\n- currency_rate (optional, numeric, > 0): Exchange rate. Defaults to the bill's rate.\n- payment_type_id (optional, integer): Payment method ID.\n- external_reference (optional, max 255): External reference; alias 'reference' is also accepted.\n- notes (optional, max 1000): Payment notes.","body":{"mode":"raw","raw":"{\n  \"amount\": 1250,\n  \"payment_date\": \"2026-07-11\",\n  \"payment_type_id\": 2,\n  \"external_reference\": \"WIRE-99813\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/record-payment","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","record-payment"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"paid\",\n  \"outstanding_balance\": 0,\n  \"payment_approval_status\": \"approved\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": 5,\n  \"payment_approved_by_name\": \"Sam Manager\",\n  \"payment_approved_at\": \"2026-07-10T15:10:00+00:00\",\n  \"payment_approval_notes\": \"Verified against receipt.\",\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": 5,\n      \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n      \"notes\": \"Verified against receipt.\"\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Send Invoice Payment Remittance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/send-remittance","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","send-remittance"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Email a remittance advice to the supplier for a bill that has already been paid. The message confirms the payment and can include selected invoice documents as attachments; supplier banking details are never included. A recorded payment is required first — sending before any payment is recorded returns 422. On success the bill's `remittance_sent_at` timestamp is stamped.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- to (required, email): Recipient email address.\n- cc (optional, array of email, max 10): Additional recipients.\n- subject (required, string, max 255): Email subject.\n- note (optional, string, max 2000): Message added to the remittance advice body.\n- attachment_ids (optional, array of integer): IDs of invoice attachments to include with the email.","body":{"mode":"raw","raw":"{\n  \"to\": \"accounts@acme-components.example\",\n  \"cc\": [\n    \"ap@acme.com\"\n  ],\n  \"subject\": \"Remittance advice for INV-2025-0042\",\n  \"note\": \"Payment of USD 1,250.00 sent by wire on 2026-07-11.\",\n  \"attachment_ids\": [\n    45,\n    47\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/send-remittance","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","send-remittance"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"paid\",\n  \"outstanding_balance\": 0,\n  \"payment_approval_status\": \"approved\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": 5,\n  \"payment_approved_by_name\": \"Sam Manager\",\n  \"payment_approved_at\": \"2026-07-10T15:10:00+00:00\",\n  \"payment_approval_notes\": \"Verified against receipt.\",\n  \"remittance_sent_at\": \"2026-07-11T09:20:00+00:00\",\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": 5,\n      \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n      \"notes\": \"Verified against receipt.\"\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Scan Invoice Payment Proof","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/scan-proof","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","scan-proof"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Scan a payment proof — a bank transfer confirmation image or PDF — and return the payment details read from it, used to pre-fill the record-payment form. Nothing is stored: the file is only persisted later (as a payment-proof attachment) when the payment is actually recorded.\n\nSend as `multipart/form-data` with a single `file` field. Accepted types: PDF, JPG/JPEG, PNG, GIF, WEBP, TIFF, BMP. Maximum size 10 MB. If the extraction service is unavailable the endpoint returns 422.\n\nAuthentication: Requires Bearer token.\n\nResponse fields (each nullable when a value cannot be read):\n- reference: Payment reference or transaction ID.\n- amount: Payment amount.\n- currency_code: ISO currency code.\n- value_date: Date the payment settled (YYYY-MM-DD).\n- payee_name: Beneficiary name shown on the proof.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/scan-proof","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","scan-proof"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"WIRE-99813\",\n    \"amount\": 1250,\n    \"currency_code\": \"USD\",\n    \"value_date\": \"2026-07-11\",\n    \"payee_name\": \"Acme Components Ltd\"\n  }\n}"}]},{"name":"Reject Bill Payment Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Reject a pending bill payment request.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- reason (optional, max 500): Reason for rejection.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Duplicate of INV-2025-0039.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"open\",\n  \"outstanding_balance\": 1250,\n  \"payment_approval_status\": \"rejected\",\n  \"payment_requested_by\": 3,\n  \"payment_requested_by_name\": \"Jane Buyer\",\n  \"payment_requested_at\": \"2026-07-10T14:32:00+00:00\",\n  \"payment_approved_by\": null,\n  \"payment_approved_by_name\": null,\n  \"payment_approved_at\": null,\n  \"payment_approval_notes\": \"Duplicate of INV-2025-0039.\",\n  \"payment_approval_steps\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"rejected\",\n      \"approver_user_id\": 5,\n      \"actioned_by\": 5,\n      \"actioned_at\": \"2026-07-10T15:12:00+00:00\",\n      \"notes\": null\n    }\n  ],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"Withdraw Bill Payment Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/revert-to-draft","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","revert-to-draft"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Withdraw an untouched pending payment request, returning the bill to the not-requested state. Only allowed while no approval step has been actioned.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- reason (optional, max 500): Reason for withdrawing the request.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Submitted in error.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-request/revert-to-draft","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-request","revert-to-draft"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"purchase_order_id\": 15,\n  \"purchase_order_number\": \"PO-000015\",\n  \"supplier_invoice_number\": \"INV-2025-0042\",\n  \"supplier_id\": 7,\n  \"supplier_name\": \"Acme Components Ltd\",\n  \"status\": \"open\",\n  \"outstanding_balance\": 1250,\n  \"payment_approval_status\": \"not_requested\",\n  \"payment_requested_by\": null,\n  \"payment_requested_by_name\": null,\n  \"payment_requested_at\": null,\n  \"payment_approved_by\": null,\n  \"payment_approved_by_name\": null,\n  \"payment_approved_at\": null,\n  \"payment_approval_notes\": null,\n  \"payment_approval_steps\": [],\n  \"supplier_bank_details_verified\": true\n}"}]},{"name":"List Bill Payment Approval Steps","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"List the payment approval steps for a bill, in level order. Each step represents one level of the multi-step approval chain.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 15,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Manager Approval\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"approver_user\": {\n        \"id\": 5,\n        \"name\": \"Sam Manager\",\n        \"email\": \"sam@company.com\"\n      },\n      \"actioned_by\": 5,\n      \"actioned_by_user\": {\n        \"id\": 5,\n        \"name\": \"Sam Manager\"\n      },\n      \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n      \"notes\": \"Looks good.\",\n      \"created_at\": \"2026-07-10T14:32:00+00:00\",\n      \"updated_at\": \"2026-07-10T15:10:00+00:00\"\n    },\n    {\n      \"id\": 16,\n      \"purchase_invoice_id\": 42,\n      \"approval_level_id\": 3,\n      \"level_order\": 2,\n      \"level_name\": \"Director Approval\",\n      \"status\": \"pending\",\n      \"approver_user_id\": 9,\n      \"approver_user\": {\n        \"id\": 9,\n        \"name\": \"Dana Director\",\n        \"email\": \"dana@company.com\"\n      },\n      \"actioned_by\": null,\n      \"actioned_by_user\": null,\n      \"actioned_at\": null,\n      \"notes\": null,\n      \"created_at\": \"2026-07-10T14:32:00+00:00\",\n      \"updated_at\": \"2026-07-10T14:32:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Approve Bill Payment Approval Step","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Approve the current pending step in a bill's payment approval chain. When the final step is approved the bill's payment becomes approved.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- notes (optional, max 1000): Notes for this approval step.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Looks good.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps/approve","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps","approve"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"purchase_invoice_id\": 42,\n    \"approval_level_id\": 2,\n    \"level_order\": 1,\n    \"level_name\": \"Manager Approval\",\n    \"status\": \"approved\",\n    \"approver_user_id\": 5,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\",\n      \"email\": \"sam@company.com\"\n    },\n    \"actioned_by\": 5,\n    \"actioned_by_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\"\n    },\n    \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n    \"notes\": \"Looks good.\",\n    \"created_at\": \"2026-07-10T14:32:00+00:00\",\n    \"updated_at\": \"2026-07-10T15:10:00+00:00\"\n  }\n}"}]},{"name":"Reject Bill Payment Approval Step","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]},"description":"Reject the current pending step in a bill's payment approval chain, rejecting the overall payment request.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- notes (optional, max 1000): Notes explaining the rejection.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Amount exceeds agreed PO value.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/payment-approval-steps/reject","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","payment-approval-steps","reject"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"purchase_invoice_id\": 42,\n    \"approval_level_id\": 2,\n    \"level_order\": 1,\n    \"level_name\": \"Manager Approval\",\n    \"status\": \"rejected\",\n    \"approver_user_id\": 5,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\",\n      \"email\": \"sam@company.com\"\n    },\n    \"actioned_by\": 5,\n    \"actioned_by_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\"\n    },\n    \"actioned_at\": \"2026-07-10T15:10:00+00:00\",\n    \"notes\": \"Amount exceeds agreed PO value.\",\n    \"created_at\": \"2026-07-10T14:32:00+00:00\",\n    \"updated_at\": \"2026-07-10T15:10:00+00:00\"\n  }\n}"}]},{"name":"List Purchase Invoice Approval Levels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels"]},"description":"List the configured bill payment approval levels, in level order. Levels define the multi-step approval chain and the amount threshold at which each level applies.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"level_order\": 1,\n      \"name\": \"Manager Approval\",\n      \"threshold_amount\": 5000,\n      \"approver_user_id\": 5,\n      \"approver_role_id\": null,\n      \"approver_user\": {\n        \"id\": 5,\n        \"name\": \"Sam Manager\",\n        \"email\": \"sam@company.com\"\n      },\n      \"created_at\": \"2026-07-01T09:00:00+00:00\",\n      \"updated_at\": \"2026-07-01T09:00:00+00:00\"\n    },\n    {\n      \"id\": 3,\n      \"level_order\": 2,\n      \"name\": \"Director Approval\",\n      \"threshold_amount\": 25000,\n      \"approver_user_id\": 9,\n      \"approver_role_id\": null,\n      \"approver_user\": {\n        \"id\": 9,\n        \"name\": \"Dana Director\",\n        \"email\": \"dana@company.com\"\n      },\n      \"created_at\": \"2026-07-01T09:05:00+00:00\",\n      \"updated_at\": \"2026-07-01T09:05:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Purchase Invoice Approval Level","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels"]},"description":"Create a bill payment approval level.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- level_order (required, integer, >= 1, unique): Position of this level in the approval chain. Must be unique across levels — reusing an existing order returns a 422 validation error.\n- name (required, max 100): Display name for the level.\n- threshold_amount (required, numeric, >= 0): Amount at or above which this level's approval is required.\n- approver_user_id (optional, integer): Designated approver user ID.\n- approver_role_id (optional, integer): Designated approver role ID.","body":{"mode":"raw","raw":"{\n  \"level_order\": 1,\n  \"name\": \"Manager Approval\",\n  \"threshold_amount\": 5000,\n  \"approver_user_id\": 5,\n  \"approver_role_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"level_order\": 1,\n    \"name\": \"Manager Approval\",\n    \"threshold_amount\": 5000,\n    \"approver_user_id\": 5,\n    \"approver_role_id\": null,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\",\n      \"email\": \"sam@company.com\"\n    },\n    \"created_at\": \"2026-07-01T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-01T09:00:00+00:00\"\n  }\n}"}]},{"name":"Update Purchase Invoice Approval Level","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels/{purchaseInvoiceApprovalLevel}","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels",":purchaseInvoiceApprovalLevel"],"variable":[{"key":"purchaseInvoiceApprovalLevel","value":"2","description":"Approval level ID"}]},"description":"Update a bill payment approval level. All fields are optional; only supplied fields are changed.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- level_order (optional, integer, >= 1, unique): Position of this level in the approval chain. Must be unique across levels (the level being updated is excluded from the check); reusing another level's order returns a 422 validation error.\n- name (optional, max 100): Display name for the level.\n- threshold_amount (optional, numeric, >= 0): Amount at or above which this level's approval is required.\n- approver_user_id (optional, integer): Designated approver user ID.\n- approver_role_id (optional, integer): Designated approver role ID.","body":{"mode":"raw","raw":"{\n  \"threshold_amount\": 7500,\n  \"approver_user_id\": 8\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels/{purchaseInvoiceApprovalLevel}","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels",":purchaseInvoiceApprovalLevel"],"variable":[{"key":"purchaseInvoiceApprovalLevel","value":"2","description":"Approval level ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"level_order\": 1,\n    \"name\": \"Manager Approval\",\n    \"threshold_amount\": 7500,\n    \"approver_user_id\": 8,\n    \"approver_role_id\": null,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Sam Manager\",\n      \"email\": \"sam@company.com\"\n    },\n    \"created_at\": \"2026-07-01T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-01T09:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Purchase Invoice Approval Level","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels/{purchaseInvoiceApprovalLevel}","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels",":purchaseInvoiceApprovalLevel"],"variable":[{"key":"purchaseInvoiceApprovalLevel","value":"2","description":"Approval level ID"}]},"description":"Delete a bill payment approval level.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-invoice-approval-levels/{purchaseInvoiceApprovalLevel}","host":["{{baseUrl}}"],"path":["api","purchase-invoice-approval-levels",":purchaseInvoiceApprovalLevel"],"variable":[{"key":"purchaseInvoiceApprovalLevel","value":"2","description":"Approval level ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"List Supplier Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments"]},"description":"Paginated list of supplier payments, newest first.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"supplier_id\": 12,\n      \"supplier_name\": \"Acme Supplies Ltd\",\n      \"payment_date\": \"2026-07-11\",\n      \"payment_type_id\": 1,\n      \"payment_type_name\": \"Cash\",\n      \"external_reference\": \"WIRE-42\",\n      \"total_amount\": 5000,\n      \"currency_code\": \"USD\",\n      \"created_at\": \"2026-07-11T12:00:00Z\",\n      \"allocations\": [\n        {\n          \"id\": 1,\n          \"purchase_invoice_id\": 42,\n          \"reference\": \"INV-2026-101\",\n          \"amount\": 4120,\n          \"payment_id\": 90\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Record Supplier Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments"]},"description":"Record one supplier-level payment allocated across multiple open invoices. All-or-nothing: the run is rejected (422) if any allocation exceeds its invoice's outstanding balance, targets another supplier's invoice, or repeats an invoice.\n\nFields:\n- supplier_id (required)\n- payment_date (required, Y-m-d)\n- payment_type_id (optional; defaults to Cash)\n- external_reference (optional; stored on the payment run and suffixed per invoice on the individual payment records)\n- allocations (required, min 1): purchase_invoice_id + amount (> 0, at most the invoice's outstanding balance)\n\nEach allocation creates a regular invoice payment, so invoice payment statuses (paid / partially paid) update immediately.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 12,\n  \"payment_date\": \"2026-07-11\",\n  \"payment_type_id\": 1,\n  \"external_reference\": \"WIRE-42\",\n  \"allocations\": [\n    {\n      \"purchase_invoice_id\": 42,\n      \"amount\": 4120\n    },\n    {\n      \"purchase_invoice_id\": 43,\n      \"amount\": 880\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"supplier_id\": 12,\n    \"supplier_name\": \"Acme Supplies Ltd\",\n    \"payment_date\": \"2026-07-11\",\n    \"payment_type_id\": 1,\n    \"payment_type_name\": \"Cash\",\n    \"external_reference\": \"WIRE-42\",\n    \"total_amount\": 5000,\n    \"currency_code\": \"USD\",\n    \"created_at\": \"2026-07-11T12:00:00Z\",\n    \"allocations\": [\n      {\n        \"id\": 1,\n        \"purchase_invoice_id\": 42,\n        \"reference\": \"INV-2026-101\",\n        \"amount\": 4120,\n        \"payment_id\": 90\n      },\n      {\n        \"id\": 2,\n        \"purchase_invoice_id\": 43,\n        \"reference\": \"INV-2026-102\",\n        \"amount\": 880,\n        \"payment_id\": 91\n      }\n    ]\n  }\n}"}]},{"name":"Get Allocation Suggestion","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments/allocation-suggestion?supplier_id=12","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments","allocation-suggestion"],"query":[{"key":"supplier_id","value":"12","description":"The supplier whose open invoices to allocate against","disabled":true}]},"description":"The supplier's open (unpaid or partially paid) invoices with a suggested allocation of the given total, distributed oldest due date first — the prefill for a payment run.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/supplier-payments/allocation-suggestion?supplier_id=12","host":["{{baseUrl}}"],"path":["api","purchase-invoices","supplier-payments","allocation-suggestion"],"query":[{"key":"supplier_id","value":"12","description":"The supplier whose open invoices to allocate against","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"invoices\": [\n      {\n        \"purchase_invoice_id\": 42,\n        \"supplier_invoice_number\": \"INV-2026-101\",\n        \"purchase_order_number\": \"PO-2026-0015\",\n        \"invoice_date\": \"2026-04-27\",\n        \"due_date\": \"2026-05-27\",\n        \"payment_due_status\": \"overdue\",\n        \"currency_code\": \"USD\",\n        \"outstanding\": 4120,\n        \"suggested_amount\": 4120\n      }\n    ],\n    \"suggested_total\": 4120\n  }\n}"}]}]},{"name":"Vendor Returns","item":[{"name":"List Vendor Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns","host":["{{baseUrl}}"],"path":["api","vendor-returns"]},"description":"Paginated list of vendor returns, sorted by return date (newest first) by default. Archived returns are excluded unless filter[archived] is provided.\n\nAuthentication: Requires Bearer token.\n\nFilters:\n- filter[search]: matches return ID (exact), return number, vendor RMA number, supplier name, item SKU, and purchase order number\n- filter[return_status]: draft, authorized, shipped, completed, void\n- filter[supplier_id], filter[warehouse_id]: exact ID match\n- filter[purchase_order_id]: returns containing lines from that purchase order\n- filter[return_date.from] / filter[return_date.to]: date range (YYYY-MM-DD, inclusive)\n- filter[archived]: 'only' = archived only, 'all' = both; omitted = active only\n\nAllowed sorts: id, vendor_return_number, supplier_rma_number, return_date, return_status, created_at, updated_at, supplier_name. Prefix with - for descending; default is -return_date.\n\nPagination: page and per_page (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns","host":["{{baseUrl}}"],"path":["api","vendor-returns"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 12,\n      \"vendor_return_number\": \"VR-00012\",\n      \"return_status\": \"shipped\",\n      \"return_date\": \"2026-03-14\",\n      \"supplier_rma_number\": \"RMA-4821\",\n      \"reason\": \"Damaged in transit\",\n      \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n      \"supplier_id\": 5,\n      \"supplier\": {\n        \"id\": 5,\n        \"name\": \"Acme Supplies\",\n        \"email\": \"orders@acmesupplies.com\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"currency_id\": 1,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\"\n      },\n      \"purchase_order\": {\n        \"id\": 101,\n        \"purchase_order_number\": \"PO-00101\"\n      },\n      \"is_fully_credited\": false,\n      \"total_cost\": 250,\n      \"lines\": [\n        {\n          \"id\": 34,\n          \"purchase_order_line_id\": 210,\n          \"product_id\": 88,\n          \"product\": {\n            \"id\": 88,\n            \"sku\": \"WIDGET-BLUE\",\n            \"name\": \"Blue Widget\"\n          },\n          \"quantity\": 10,\n          \"unit_cost\": 25,\n          \"reason\": \"Damaged in transit\",\n          \"is_write_off\": false,\n          \"clearing_quantity\": 6,\n          \"ap_quantity\": 4,\n          \"credited_quantity\": 0,\n          \"purchase_order_number\": \"PO-00101\"\n        }\n      ],\n      \"credits\": [],\n      \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n      \"updated_at\": \"2026-03-15T09:10:44.000000Z\",\n      \"archived_at\": null,\n      \"accounting_exempt\": false\n    }\n  ],\n  \"first_page_url\": \"https://yourdomain.example/api/vendor-returns?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"https://yourdomain.example/api/vendor-returns?page=3\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://yourdomain.example/api/vendor-returns?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://yourdomain.example/api/vendor-returns?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://yourdomain.example/api/vendor-returns?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://yourdomain.example/api/vendor-returns?page=2\",\n  \"path\": \"https://yourdomain.example/api/vendor-returns\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 24\n}"}]},{"name":"Create Vendor Return","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-returns","host":["{{baseUrl}}"],"path":["api","vendor-returns"]},"description":"Create a draft vendor return for goods that will be physically sent back to a supplier.\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- supplier_id (integer, required): supplier the goods return to\n- warehouse_id (integer, required): warehouse the goods ship out of\n- return_date (date, required, YYYY-MM-DD)\n- supplier_rma_number (string, optional, max 255): the supplier's RMA reference\n- reason (string, optional, max 255)\n- notes (string, optional)\n- currency_id (integer, optional): defaults to the account's base currency\n- lines (array, optional) - each line:\n  - purchase_order_line_id (integer, required unless product_id is given): the received purchase order line being returned\n  - product_id (integer, required unless purchase_order_line_id is given; derived from the purchase order line when omitted)\n  - quantity (number, required, greater than 0)\n  - unit_cost (number, optional; when omitted it is filled from the cost basis of the purchase order line)\n  - reason (string, optional, max 255)\n  - is_write_off (boolean, optional, default false): write-off lines are expensed to cost of goods sold at ship instead of the clearing/accounts-payable split\n\nValidation invariants:\n- Single purchase order: every line that references a purchase order line must belong to the SAME purchase order. Mixing lines from different purchase orders is rejected.\n- Returnable quantity: per purchase order line, the return quantity cannot exceed received quantity minus what was already returned (across other non-void returns and historical credits). Check availability first with List Returnable Lines For Purchase Order.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 5,\n  \"warehouse_id\": 2,\n  \"return_date\": \"2026-03-14\",\n  \"supplier_rma_number\": \"RMA-4821\",\n  \"reason\": \"Damaged in transit\",\n  \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n  \"currency_id\": 1,\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 210,\n      \"product_id\": 88,\n      \"quantity\": 10,\n      \"unit_cost\": 25,\n      \"reason\": \"Damaged in transit\",\n      \"is_write_off\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns","host":["{{baseUrl}}"],"path":["api","vendor-returns"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"draft\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"supplier\": {\n      \"id\": 5,\n      \"name\": \"Acme Supplies\",\n      \"email\": \"orders@acmesupplies.com\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"currency_id\": 1,\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"is_fully_credited\": false,\n    \"total_cost\": 250,\n    \"lines\": [\n      {\n        \"id\": 34,\n        \"purchase_order_line_id\": 210,\n        \"product_id\": 88,\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 10,\n        \"unit_cost\": 25,\n        \"reason\": \"Damaged in transit\",\n        \"is_write_off\": false,\n        \"clearing_quantity\": null,\n        \"ap_quantity\": null,\n        \"credited_quantity\": 0,\n        \"purchase_order_number\": \"PO-00101\"\n      }\n    ],\n    \"credits\": [],\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-15T09:10:44.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"The vendor return created successfully\"\n}"}]},{"name":"Get Vendor Return","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Get a single vendor return with its lines, outbound shipments, and any vendor credits created from it.\n\nAuthentication: Requires Bearer token.\n\nResponse notes:\n- purchase_order is derived from the return's lines (a return references purchase orders through its lines)\n- lines[].clearing_quantity / lines[].ap_quantity are set at ship time: the un-invoiced portion posts to the vendor-returns clearing account, the invoiced portion posts to accounts payable\n- lines[].credited_quantity is the quantity already covered by vendor credit lines referencing the return line\n- is_fully_credited is true once every line is fully covered by vendor credits\n- total_cost is the sum of line quantity x unit cost"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"shipped\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"supplier\": {\n      \"id\": 5,\n      \"name\": \"Acme Supplies\",\n      \"email\": \"orders@acmesupplies.com\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"currency_id\": 1,\n    \"currency\": {\n      \"id\": 1,\n      \"code\": \"USD\"\n    },\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"is_fully_credited\": false,\n    \"total_cost\": 250,\n    \"lines\": [\n      {\n        \"id\": 34,\n        \"purchase_order_line_id\": 210,\n        \"product_id\": 88,\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 10,\n        \"unit_cost\": 25,\n        \"reason\": \"Damaged in transit\",\n        \"is_write_off\": false,\n        \"clearing_quantity\": 6,\n        \"ap_quantity\": 4,\n        \"credited_quantity\": 0,\n        \"purchase_order_number\": \"PO-00101\"\n      }\n    ],\n    \"shipments\": [\n      {\n        \"id\": 7,\n        \"shipment_date\": \"2026-03-15\",\n        \"status\": \"shipped\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"custom_carrier\": null,\n        \"shipping_method\": {\n          \"id\": 3,\n          \"name\": \"UPS Ground\"\n        },\n        \"notes\": null\n      }\n    ],\n    \"credits\": [\n      {\n        \"id\": 55,\n        \"vendor_credit_number\": \"VC-00055\",\n        \"credit_status\": \"draft\",\n        \"total_credit\": 250\n      }\n    ],\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-15T09:10:44.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  }\n}"}]},{"name":"Update Vendor Return","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Update a DRAFT vendor return. Returns that have been authorized, shipped, completed, or voided cannot be edited.\n\nAuthentication: Requires Bearer token.\n\nAccepts the same fields as Create Vendor Return. On update, supplier_id, warehouse_id, and return_date are optional - omitted values keep their current value. When a lines array is provided it REPLACES the full existing line set; omit lines entirely to leave them unchanged.\n\nThe same validation invariants apply as on create: all lines must belong to a single purchase order, and per-line quantities cannot exceed the returnable (received minus already returned) quantity.","body":{"mode":"raw","raw":"{\n  \"supplier_rma_number\": \"RMA-4821-B\",\n  \"reason\": \"Wrong items shipped\",\n  \"notes\": \"Supplier issued an updated RMA reference.\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 210,\n      \"quantity\": 8,\n      \"unit_cost\": 25,\n      \"reason\": \"Wrong items shipped\",\n      \"is_write_off\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"draft\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"supplier\": {\n      \"id\": 5,\n      \"name\": \"Acme Supplies\",\n      \"email\": \"orders@acmesupplies.com\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"currency_id\": 1,\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"is_fully_credited\": false,\n    \"total_cost\": 250,\n    \"lines\": [\n      {\n        \"id\": 34,\n        \"purchase_order_line_id\": 210,\n        \"product_id\": 88,\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 10,\n        \"unit_cost\": 25,\n        \"reason\": \"Damaged in transit\",\n        \"is_write_off\": false,\n        \"clearing_quantity\": null,\n        \"ap_quantity\": null,\n        \"credited_quantity\": 0,\n        \"purchase_order_number\": \"PO-00101\"\n      }\n    ],\n    \"credits\": [],\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-15T09:10:44.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"The vendor return '12' updated successfully\"\n}"}]},{"name":"Delete Vendor Return","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Delete a DRAFT vendor return and its lines. Returns that have progressed past draft cannot be deleted - void them instead (Void Vendor Return), which reverses their postings while keeping an auditable record.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"The vendor return 12 deleted successfully\"\n}"}]},{"name":"Authorize Vendor Return","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/authorize","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","authorize"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Authorize a DRAFT vendor return: locks it for editing and reserves the stock. A stock allocation is created for each product line so the goods awaiting return shipment cannot be sold or allocated elsewhere. Status moves from draft to authorized.\n\nAuthentication: Requires Bearer token.\n\nFails with 422 when:\n- the return is not in draft status\n- the return has no lines\n- any line's quantity exceeds the remaining returnable quantity for its purchase order line"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/authorize","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","authorize"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"authorized\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"warehouse_id\": 2,\n    \"currency_id\": 1,\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"is_fully_credited\": false,\n    \"total_cost\": 250,\n    \"lines\": [\n      {\n        \"id\": 34,\n        \"purchase_order_line_id\": 210,\n        \"product_id\": 88,\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 10,\n        \"unit_cost\": 25,\n        \"reason\": \"Damaged in transit\",\n        \"is_write_off\": false,\n        \"clearing_quantity\": null,\n        \"ap_quantity\": null,\n        \"credited_quantity\": 0,\n        \"purchase_order_number\": \"PO-00101\"\n      }\n    ],\n    \"credits\": [],\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-14T16:02:31.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"Vendor return authorized.\"\n}"}]},{"name":"Ship Vendor Return","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/ship","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","ship"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Ship the vendor return: the goods physically leave the warehouse. Creates the outbound shipment record, posts the inventory-out movements, and posts the accounting for the return. Status moves from authorized to shipped. A DRAFT return is authorized automatically before shipping, so shipping is allowed from draft or authorized status.\n\nAccounting split, captured per line at ship time:\n- un-invoiced units debit the vendor-returns clearing account (reversing the receipt accrual)\n- units already invoiced by the supplier debit accounts payable\n- write-off lines (is_write_off = true) debit cost of goods sold instead\nUn-invoiced units are consumed first when splitting. The split is recorded on each line as clearing_quantity and ap_quantity.\n\nAuthentication: Requires Bearer token.\n\nBody fields (all optional):\n- shipment_date (date, YYYY-MM-DD; defaults to today)\n- tracking_number (string, max 255)\n- shipping_method_id (integer): ID of a shipping method\n- custom_carrier (string, max 255): free-text carrier name when no shipping method applies\n- notes (string)\n\nFails with 422 when the return is already shipped, completed, or void, or when a line's quantity exceeds the remaining returnable quantity for its purchase order line.","body":{"mode":"raw","raw":"{\n  \"shipment_date\": \"2026-03-15\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"shipping_method_id\": 3,\n  \"custom_carrier\": null,\n  \"notes\": \"Two cartons, prepaid label from supplier.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/ship","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","ship"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"shipped\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"warehouse_id\": 2,\n    \"currency_id\": 1,\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"is_fully_credited\": false,\n    \"total_cost\": 250,\n    \"lines\": [\n      {\n        \"id\": 34,\n        \"purchase_order_line_id\": 210,\n        \"product_id\": 88,\n        \"product\": {\n          \"id\": 88,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget\"\n        },\n        \"quantity\": 10,\n        \"unit_cost\": 25,\n        \"reason\": \"Damaged in transit\",\n        \"is_write_off\": false,\n        \"clearing_quantity\": 6,\n        \"ap_quantity\": 4,\n        \"credited_quantity\": 0,\n        \"purchase_order_number\": \"PO-00101\"\n      }\n    ],\n    \"shipments\": [\n      {\n        \"id\": 7,\n        \"shipment_date\": \"2026-03-15\",\n        \"status\": \"shipped\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"custom_carrier\": null,\n        \"shipping_method\": null,\n        \"notes\": \"Two cartons, prepaid label from supplier.\"\n      }\n    ],\n    \"credits\": [],\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-15T09:10:44.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"Vendor return shipped.\"\n}"}]},{"name":"Complete Vendor Return","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/complete","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","complete"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Mark a SHIPPED vendor return as completed - the supplier has acknowledged the return (typically once it is fully credited). Status moves from shipped to completed. No inventory or accounting changes are made.\n\nAuthentication: Requires Bearer token.\n\nFails with 422 when the return is not in shipped status."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/complete","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","complete"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"completed\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"warehouse_id\": 2,\n    \"currency_id\": 1,\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-20T11:41:03.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"Vendor return completed.\"\n}"}]},{"name":"Void Vendor Return","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/void","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","void"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Void a vendor return, reversing everything it posted:\n- shipped inventory movements are reversed (stock is put back)\n- reserved stock from authorization is released\n- the return's accounting entries are removed\n- per-line clearing/accounts-payable quantities are cleared\n\nStatus moves to void. Voiding an already-void return succeeds and returns it unchanged.\n\nAuthentication: Requires Bearer token.\n\nBlocked with 422 when any vendor credit line references the return - remove those credit lines first."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/void","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","void"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_return_number\": \"VR-00012\",\n    \"return_status\": \"void\",\n    \"return_date\": \"2026-03-14\",\n    \"supplier_rma_number\": \"RMA-4821\",\n    \"reason\": \"Damaged in transit\",\n    \"notes\": \"Carton crushed on arrival; supplier approved the return.\",\n    \"supplier_id\": 5,\n    \"warehouse_id\": 2,\n    \"currency_id\": 1,\n    \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n    \"updated_at\": \"2026-03-21T08:19:47.000000Z\",\n    \"archived_at\": null,\n    \"accounting_exempt\": false\n  },\n  \"message\": \"Vendor return voided.\"\n}"}]},{"name":"List Vendor Return Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/allocations","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","allocations"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"List the inventory allocations linked to this vendor return's lines - its Planned stock reservations plus any successor allocations they were promoted or demoted into. Paginated (10 per page by default). Each allocation carries its product, warehouse, quantity, status, hard-allocated flag, priority, and a `link_route` back to the source document.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `page` (integer, optional) - page number.\n- `per_page` (integer, optional) - items per page (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/allocations","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","allocations"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"product_id\": 88,\n      \"product\": {\n        \"id\": 88,\n        \"sku\": \"WIDGET-BLUE\",\n        \"name\": \"Blue Widget\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\",\n        \"locations_enabled\": false\n      },\n      \"warehouse_location_id\": null,\n      \"warehouse_location\": null,\n      \"link_id\": 34,\n      \"link_type\": \"App\\\\Models\\\\VendorReturnLine\",\n      \"link_type_label\": \"Vendor Return\",\n      \"link_route\": \"/purchases/vendor-returns/12\",\n      \"link_reference\": null,\n      \"date\": null,\n      \"quantity\": 10,\n      \"status\": \"planned\",\n      \"status_label\": \"Planned\",\n      \"hard_allocated\": false,\n      \"priority\": 100,\n      \"supplier_id\": 5,\n      \"supplier\": {\n        \"id\": 5,\n        \"name\": \"Acme Supplies Co.\"\n      },\n      \"purchase_order_line_id\": 210,\n      \"is_tight_coverage\": false,\n      \"release_source_id\": null,\n      \"release_source_type\": null,\n      \"fulfilled_at\": null,\n      \"cancelled_at\": null,\n      \"created_at\": \"2026-03-14T15:22:08.000000Z\",\n      \"updated_at\": \"2026-03-14T16:02:31.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/vendor-returns/12/allocations?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/vendor-returns/12/allocations?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}{{domain}}/api/vendor-returns/12/allocations?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/vendor-returns/12/allocations\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Vendor Return Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","activity-log"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Paginated activity feed for this vendor return - its own status transitions plus events logged on its lines, shipments, and shipment lines, all rolled up onto the return. Newest first, 15 per page by default.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- `page` (integer, optional) - page number.\n- `per_page` (integer, optional) - items per page (default 15).\n- `filter[search]` (string, optional) - filter entries by causer name, event, subject type, or change payload."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","activity-log"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"VendorReturn\",\n      \"subject_id\": 12,\n      \"properties\": {\n        \"attributes\": {\n          \"return_status\": \"shipped\"\n        },\n        \"old\": {\n          \"return_status\": \"authorized\"\n        }\n      },\n      \"causer_name\": \"Jane Buyer\",\n      \"created_at\": \"2026-04-19T14:32:10.000000Z\"\n    },\n    {\n      \"id\": 4815,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"VendorReturnShipment\",\n      \"subject_id\": 30,\n      \"properties\": {\n        \"attributes\": {\n          \"vendor_return_id\": 12,\n          \"status\": \"shipped\",\n          \"tracking_number\": \"TRK-RETURN-1\"\n        }\n      },\n      \"causer_name\": \"Jane Buyer\",\n      \"created_at\": \"2026-04-19T14:32:09.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/vendor-returns/12/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/vendor-returns/12/activity-log?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/vendor-returns/12/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Preview Vendor Return Ship Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/ship-impact","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","ship-impact"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Read-only preview of the allocation-demotion impact of shipping this vendor return. Shipping consumes the source stock reserved for the return, which can demote soft sales-order reservations to backorder and requires voiding printed shipping labels for any hard-allocated units. This returns the per-product rows describing exactly which order allocations would be affected, so the caller can collect the necessary `void_confirmations` before calling Ship Vendor Return.\n\nEach row is one product whose stock the action would consume. `shortfall_quantity` is how much more than available the action removes (stock goes negative when above zero). `unallocated_quantity` / `soft_allocated_quantity` / `hard_allocated_quantity` split the consumed quantity into free / soft-reserved / hard-allocated (label-printed) units. `affected_allocations[]` lists the order allocations consumed, highest priority first: `allocation_type` is `soft` or `hard`, and for hard rows `fulfillment_id`/`carrier` identify the label while `carrier_void_supported` and `voidable_status` say whether it can be voided through the API.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/ship-impact","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","ship-impact"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 4,\n      \"soft_allocated_quantity\": 3,\n      \"hard_allocated_quantity\": 2,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88213,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 4521,\n          \"order_number\": \"SO-10442\",\n          \"customer_name\": \"Acme Retail\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 3\n        },\n        {\n          \"allocation_id\": 88240,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 4530,\n          \"order_number\": \"SO-10450\",\n          \"customer_name\": \"Beta Wholesale\",\n          \"fulfillment_id\": 77120,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Create Vendor Credit From Return","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/create-credit","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","create-credit"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]},"description":"Create the financial vendor credit from a SHIPPED (or completed) vendor return - use this once the supplier's credit memo arrives. Returns the newly created draft vendor credit.\n\nThe credit's lines link to the return's lines at the line level, so each return line tracks how much of it has been credited (credited_quantity). Crediting the un-invoiced portion settles the vendor-returns clearing account. Only the remaining un-credited quantity of each return line is included; lines already fully credited are skipped.\n\nAuthentication: Requires Bearer token.\n\nBody fields (all optional):\n- vendor_credit_number (string, max 255, must be unique; auto-generated when omitted)\n- supplier_reference (string, max 255; defaults to the return's vendor RMA number)\n- credit_date (date, YYYY-MM-DD; defaults to today)\n\nFails with 422 when the return is not shipped/completed, or when it is already fully credited.","body":{"mode":"raw","raw":"{\n  \"vendor_credit_number\": \"VC-00055\",\n  \"supplier_reference\": \"CM-99120\",\n  \"credit_date\": \"2026-03-20\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-returns/{vendorReturn}/create-credit","host":["{{baseUrl}}"],"path":["api","vendor-returns",":vendorReturn","create-credit"],"variable":[{"key":"vendorReturn","value":"12","description":"Vendor return ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"vendor_credit_number\": \"VC-00055\",\n    \"supplier_reference\": \"CM-99120\",\n    \"supplier_po_number\": null,\n    \"credit_date\": \"2026-03-20\",\n    \"vendor_credit_note\": null,\n    \"credit_status\": \"draft\",\n    \"credit_status_label\": \"Draft\",\n    \"payment_status\": \"unpaid\",\n    \"payment_status_label\": \"Unpaid\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 5,\n    \"purchase_order_id\": 101,\n    \"purchase_order\": {\n      \"id\": 101,\n      \"purchase_order_number\": \"PO-00101\"\n    },\n    \"warehouse_id\": 2,\n    \"store_id\": null,\n    \"currency_id\": 1,\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_total\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"created_at\": \"2026-03-20T14:05:12.000000Z\",\n    \"updated_at\": \"2026-03-20T14:05:12.000000Z\",\n    \"archived_at\": null\n  },\n  \"message\": \"The vendor credit created successfully\"\n}"}]},{"name":"List Returnable Lines For Purchase Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-returns/returnable-lines/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","vendor-returns","returnable-lines",":purchaseOrder"],"variable":[{"key":"purchaseOrder","value":"101","description":"Purchase order ID"}]},"description":"For each line of a purchase order, report how much was received, how much has already been returned (across all non-void vendor returns, plus historical restock credits), and how much remains returnable. Use this before creating a vendor return to know which lines and quantities are still available to return.\n\nAuthentication: Requires Bearer token.\n\nResponse fields per line:\n- purchase_order_line_id (integer)\n- product_id (integer, nullable)\n- sku (string, nullable)\n- name (string): product name, or the line description when there is no product\n- received_quantity (number)\n- already_returned_quantity (number)\n- returnable_quantity (number): received minus already returned, never below 0"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-returns/returnable-lines/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","vendor-returns","returnable-lines",":purchaseOrder"],"variable":[{"key":"purchaseOrder","value":"101","description":"Purchase order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 210,\n      \"product_id\": 88,\n      \"sku\": \"WIDGET-BLUE\",\n      \"name\": \"Blue Widget\",\n      \"received_quantity\": 24,\n      \"already_returned_quantity\": 10,\n      \"returnable_quantity\": 14\n    },\n    {\n      \"purchase_order_line_id\": 211,\n      \"product_id\": 89,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget\",\n      \"received_quantity\": 12,\n      \"already_returned_quantity\": 0,\n      \"returnable_quantity\": 12\n    }\n  ]\n}"}]}]},{"name":"Purchase Receipts","item":[{"name":"Get Purchase Receipt","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Returns full details for a purchase receipt including shipment, purchase order, supplier, warehouse, and line items.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"received_at\": \"2024-01-15T14:00:00Z\",\n    \"created_at\": \"2024-01-15T14:00:00Z\",\n    \"updated_at\": \"2024-01-15T14:05:00Z\",\n    \"fulfilled_by\": {\n      \"id\": 5,\n      \"name\": \"John Smith\"\n    },\n    \"purchase_order\": {\n      \"id\": 20,\n      \"po_number\": \"PO-2024-0020\",\n      \"purchase_order_date\": \"2024-01-01\",\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"is_tax_included\": false\n    },\n    \"supplier\": {\n      \"id\": 3,\n      \"name\": \"Acme Supplies Co.\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"lines\": [\n      {\n        \"id\": 10,\n        \"quantity\": 100,\n        \"total_cost\": 1250,\n        \"purchase_order_line\": {\n          \"id\": 50,\n          \"quantity\": 100,\n          \"amount\": 1250,\n          \"discount_rate\": 0,\n          \"received_quantity\": 100,\n          \"description\": \"Blue Widget\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Blue Widget\",\n          \"image_url\": \"https://cdn.example.com/widget.jpg\"\n        }\n      }\n    ],\n    \"summary\": {\n      \"total_lines\": 1,\n      \"total_units\": 100\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search across causer name, properties, event","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Returns paginated activity log for a purchase receipt.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/activity-log?per_page=15&filter[search]=","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"","description":"Search across causer name, properties, event","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 200,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"PurchaseOrderShipmentReceipt\",\n      \"subject_id\": 1,\n      \"properties\": {},\n      \"causer_name\": \"John Smith\",\n      \"created_at\": \"2024-01-15T14:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/fifo-layers?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Returns paginated FIFO inventory layers that were created when this purchase receipt was processed.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/fifo-layers?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","fifo-layers"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 300,\n      \"fifo_layer_date\": \"2024-01-15\",\n      \"quantity\": 100,\n      \"fulfilled_quantity\": 30,\n      \"available_quantity\": 70,\n      \"unit_cost\": 12.5,\n      \"total_cost\": 1250,\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"source_type\": \"Purchase Receipt\",\n      \"source_reference\": \"PO-2024-0020\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceipt\",\n      \"link_id\": 1,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"condition\": null,\n      \"created_at\": \"2024-01-15T14:05:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Returns paginated inventory movements generated when this receipt was processed.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/inventory-movements?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","inventory-movements"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 400,\n      \"type\": \"purchase_receipt\",\n      \"inventory_status\": \"available\",\n      \"quantity\": 100,\n      \"reference\": \"PO-2024-0020\",\n      \"link_type\": \"App\\\\Models\\\\PurchaseOrderShipmentReceipt\",\n      \"link_id\": 1,\n      \"parent_link_id\": null,\n      \"detail_link_id\": null,\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 12.5,\n      \"unit_cost_provisional\": false,\n      \"total_cost\": 1250,\n      \"layer\": {\n        \"name\": \"FIFO Layer #300\",\n        \"layer_type\": \"App\\\\Models\\\\FifoLayer\",\n        \"layer_id\": 300\n      },\n      \"inventory_movement_date\": \"2024-01-15\",\n      \"created_at\": \"2024-01-15T14:05:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1\n}"}]},{"name":"Get Purchase Receipt Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Returns paginated notes for a purchase receipt, ordered by most recent first.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"data\": [\n      {\n        \"id\": 7,\n        \"note\": \"Receipt verified by warehouse manager.\",\n        \"is_pinned\": true,\n        \"user\": {\n          \"id\": 5,\n          \"name\": \"John Smith\"\n        },\n        \"created_at\": \"2024-01-15T15:00:00Z\",\n        \"updated_at\": \"2024-01-15T15:00:00Z\"\n      }\n    ],\n    \"current_page\": 1,\n    \"total\": 1\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Add Purchase Receipt Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Adds a note to a purchase receipt.\nAuthentication: Requires Bearer token.\n\nFields:\n- note (required): Note text content\n- is_pinned (optional, boolean): Whether to pin the note","body":{"mode":"raw","raw":"{\n  \"note\": \"Receipt verified by warehouse manager.\",\n  \"is_pinned\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8,\n    \"note\": \"Receipt verified by warehouse manager.\",\n    \"is_pinned\": false,\n    \"user\": {\n      \"id\": 5,\n      \"name\": \"John Smith\"\n    },\n    \"created_at\": \"2024-01-15T15:30:00Z\",\n    \"updated_at\": \"2024-01-15T15:30:00Z\"\n  },\n  \"message\": \"note created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Purchase Receipt Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes",":noteId"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"},{"key":"noteId","value":"8","description":"Note ID to delete"}]},"description":"Deletes a note from a purchase receipt.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes",":noteId"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"},{"key":"noteId","value":"8","description":"Note ID to delete"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 8 deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Toggle Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes",":noteId","toggle-pin"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"},{"key":"noteId","value":"8","description":"Note ID to pin/unpin"}]},"description":"Toggles the pinned state of a note on a purchase receipt.\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","notes",":noteId","toggle-pin"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"},{"key":"noteId","value":"8","description":"Note ID to pin/unpin"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8,\n    \"note\": \"Receipt verified by warehouse manager.\",\n    \"is_pinned\": true,\n    \"user\": {\n      \"id\": 5,\n      \"name\": \"John Smith\"\n    },\n    \"created_at\": \"2024-01-15T15:30:00Z\",\n    \"updated_at\": \"2024-01-15T16:00:00Z\"\n  },\n  \"message\": \"Note pinned\",\n  \"status\": \"success\"\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","generate-accounting-transaction"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]},"description":"Generates (or regenerates) the accounting transaction for a purchase receipt.\nAuthentication: Requires Bearer token.\nReturns 422 if the purchase order is a dropship order (has a sales_order_id) or has no destination warehouse."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-receipts/{receipt}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","purchase-receipts",":receipt","generate-accounting-transaction"],"variable":[{"key":"receipt","value":"1","description":"Purchase receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"transaction_date\": \"2024-01-15\",\n    \"reference\": \"PO-2024-0020\",\n    \"amount\": 1250\n  },\n  \"message\": \"Accounting transaction generated successfully.\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Purchase Order Shipments","item":[{"name":"Get Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]},"description":"Retrieve detailed information for a single purchase order shipment. Includes purchase order, supplier, destination warehouse, all shipment lines (with products), receipts, and summary totals.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 50,\n    \"shipment_date\": \"2024-03-10\",\n    \"tracking\": \"1Z999AA10123456784\",\n    \"fulfilled_shipping_method\": \"UPS Ground\",\n    \"fulfilled_shipping_method_id\": 5,\n    \"fully_received_at\": null,\n    \"created_at\": \"2024-03-10T08:00:00Z\",\n    \"updated_at\": \"2024-03-10T08:00:00Z\",\n    \"purchase_order\": {\n      \"id\": 200,\n      \"po_number\": \"PO-2024-001\",\n      \"purchase_order_date\": \"2024-03-01\",\n      \"currency_code\": \"USD\"\n    },\n    \"supplier\": {\n      \"id\": 10,\n      \"name\": \"Acme Supplies Ltd.\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"lines\": [\n      {\n        \"id\": 301,\n        \"quantity\": 100,\n        \"received_quantity\": 0,\n        \"purchase_order_line\": {\n          \"id\": 401,\n          \"quantity\": 100,\n          \"amount\": 12.5,\n          \"received_quantity\": 0,\n          \"description\": \"Blue Widget 500ml\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"SKU-ABC-123\",\n          \"name\": \"Blue Widget 500ml\",\n          \"image_url\": \"https://cdn.example.com/products/42.jpg\"\n        }\n      }\n    ],\n    \"receipts\": [],\n    \"summary\": {\n      \"total_lines\": 1,\n      \"total_shipped\": 100,\n      \"total_received\": 0,\n      \"total_receipts\": 0\n    }\n  }\n}"}]},{"name":"Update Shipment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment"],"variable":[{"key":"shipment","value":"","description":"The shipment identifier"}]},"description":"Update an existing purchase order shipment's shipping method or tracking number.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- shipping_method_id (optional): Updated system shipping method ID (or null to unset)\n- tracking (optional): Updated tracking number, max 255 characters","body":{"mode":"raw","raw":"{\n  \"shipping_method_id\": 6,\n  \"tracking\": \"1Z999AA10987654321\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment"],"variable":[{"key":"shipment","value":"","description":"The shipment identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment 50 has been successfully updated\",\n  \"data\": {\n    \"id\": 50,\n    \"tracking\": \"1Z999AA10987654321\",\n    \"shipping_method_id\": 6,\n    \"updated_at\": \"2024-03-11T09:00:00Z\"\n  }\n}"}]},{"name":"Create Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments"]},"description":"Create a new shipment for an open purchase order. If shipment_lines is omitted, creates a shipment for all remaining unshipped quantity.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- purchase_order_id (required): ID of the purchase order (must not be draft, not fully shipped)\n- shipment_date (required): Date of shipment in Y-m-d format\n- shipping_method_id (optional): System shipping method ID\n- tracking (optional): Tracking number, max 255 characters\n- shipment_lines (optional): Array of line quantities to ship. If omitted, ships everything remaining\n- shipment_lines[].purchase_order_line_id (conditional): PO line ID. Required without purchase_order_line_reference\n- shipment_lines[].purchase_order_line_reference (conditional): PO line reference code. Required without purchase_order_line_id\n- shipment_lines[].quantity (required): Quantity to ship (must not exceed unfulfilled quantity)\n\nErrors:\n- 422: AWD purchase orders use 'Mark as Shipped' instead\n- 400: Purchase order is not open (draft)","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 200,\n  \"shipment_date\": \"2024-03-10\",\n  \"shipping_method_id\": 5,\n  \"tracking\": \"1Z999AA10123456784\",\n  \"shipment_lines\": [\n    {\n      \"purchase_order_line_id\": 401,\n      \"quantity\": 100\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment has been successfully created\",\n  \"data\": {\n    \"id\": 50,\n    \"shipment_date\": \"2024-03-10\",\n    \"shipping_method_id\": 5,\n    \"fulfilled_shipping_method_id\": 5,\n    \"tracking\": \"1Z999AA10123456784\",\n    \"fully_received_at\": null,\n    \"created_at\": \"2024-03-10T08:00:00Z\",\n    \"updated_at\": \"2024-03-10T08:00:00Z\",\n    \"purchase_order_shipment_lines\": [\n      {\n        \"id\": 301,\n        \"purchase_order_line_id\": 401,\n        \"quantity\": 100\n      }\n    ],\n    \"purchase_order_shipment_receipts\": []\n  }\n}"}]},{"name":"Receive Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/receive","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receive"]},"description":"Receive goods against a purchase order shipment. Creates a receipt record and triggers inventory movements.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAsync behavior:\n- By default, this endpoint dispatches the receive to a background job chain and returns 202 Accepted with `data.tracked_job_log_id`. The frontend should open the tracked job log endpoints (notifyJobStarted) and watch lastCompletedJob to refresh.\n- Pass `?async=0` to force the legacy synchronous response (200 with the receipt resource).\n- The async path is only taken when the payload is ad-hoc eligible: requires `purchase_order_id`, and rejects any payload that includes `unexpected_items`, `inbound_shipment_id`, or negative `receipt_lines[].quantity`. Ineligible payloads silently fall back to the sync path.\n- 409 Conflict is returned when a background job is already in flight (PENDING or PROCESSING) for the same `purchase_order_id` — the caller should tell the user to track progress via the tracked job log endpoints instead of retrying.\n\nFields:\n- purchase_order_id (conditional): Required if purchase_order_shipment_id is not provided. Required for the async path.\n- purchase_order_shipment_id (optional): Specific shipment ID to receive. If omitted, receives for the entire PO\n- received_at (required): Date/time of receipt\n- warehouse_id (optional): Override destination warehouse\n- shipment_date (optional): Used if a new shipment needs to be created automatically\n- shipping_method_id (optional): Shipping method for auto-created shipment\n- tracking (optional): Tracking number for auto-created shipment, max 255 characters\n- inbound_shipment_id (optional, exists:inbound_shipments,id): Route the whole receive against this specific inbound shipment. Restricts delegation to that shipment and over-receives it past its planned capacity if the received quantity exceeds what was expected. Used by the PO-detail receive drawer when the receiver explicitly picks a target shipment. Presence forces sync fallback.\n- force_new_shipment (optional, boolean): If true, skip auto-routing/delegation to existing planned shipments and create a brand-new ad-hoc inbound shipment for this receipt. Mutually exclusive in intent with inbound_shipment_id\n- receipt_lines (optional): Array of specific line quantities to receive. If omitted, receives all unreceived lines\n- receipt_lines[].purchase_order_shipment_line_id (conditional): Shipment line ID. Required without purchase_order_line_reference or purchase_order_line_id\n- receipt_lines[].purchase_order_line_id (conditional): PO line ID. Alternative to shipment_line_id\n- receipt_lines[].purchase_order_line_reference (conditional): PO line reference code. Alternative to IDs\n- receipt_lines[].quantity (required): Quantity received. Negative quantities force sync fallback.\n- unexpected_items (optional): Items received that were not on the original PO. Presence forces sync fallback.\n- unexpected_items[].product_id (conditional): Product ID. Required without product_sku\n- unexpected_items[].product_sku (conditional): Product SKU. Required without product_id\n- unexpected_items[].quantity (required): Quantity of unexpected item\n- unexpected_items[].action (optional): Action for unexpected item (e.g., add_to_inventory)\n- unexpected_items[].amount (optional): Unit cost for unexpected item\n- unexpected_items[].description (optional): Description for unexpected item","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 200,\n  \"purchase_order_shipment_id\": 50,\n  \"received_at\": \"2024-03-15\",\n  \"warehouse_id\": 1,\n  \"inbound_shipment_id\": 42,\n  \"force_new_shipment\": false,\n  \"receipt_lines\": [\n    {\n      \"purchase_order_shipment_line_id\": 301,\n      \"quantity\": 100\n    }\n  ],\n  \"unexpected_items\": [\n    {\n      \"product_id\": 43,\n      \"quantity\": 5,\n      \"action\": \"add_to_inventory\",\n      \"amount\": 15,\n      \"description\": \"Extra items received\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/receive","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment receipt has been successfully created\",\n  \"data\": {\n    \"id\": 601,\n    \"received_at\": \"2024-03-15\",\n    \"fulfilled_by\": {\n      \"id\": 1,\n      \"name\": \"Jane Smith\"\n    },\n    \"inbound_shipment_receipt_lines\": [\n      {\n        \"id\": 701,\n        \"purchase_order_shipment_line_id\": 301,\n        \"quantity\": 100\n      }\n    ]\n  }\n}"}]},{"name":"Update Receipt","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]},"description":"Update an existing shipment receipt. Adjusts inventory movements accordingly.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- receipt: InboundShipmentReceipt (ISR) ID — canonical wire id since Phase 4.4g.6a (use the `id` returned by /api/purchase-orders/{po}/receipts).\n\nFields:\n- received_at (required): Updated receipt date\n- warehouse_id (optional): Override destination warehouse\n- shipment_date (optional): Shipment date if auto-creating a shipment\n- shipping_method_id (optional): Shipping method\n- tracking (optional): Tracking number\n- receipt_lines (required): Updated receipt line quantities\n- receipt_lines[].purchase_order_shipment_line_id (conditional): Shipment line ID\n- receipt_lines[].purchase_order_line_id (conditional): PO line ID\n- receipt_lines[].purchase_order_line_reference (conditional): PO line reference\n- receipt_lines[].quantity (required): Updated quantity received\n- unexpected_items (optional): Unexpected items\n\nResponse: returns the canonical InboundShipmentReceipt rendered with `inbound_shipment_receipt_lines`; both `data.id` and `data.inbound_shipment_receipt_lines[].id` are ISR / ISRL ids.","body":{"mode":"raw","raw":"{\n  \"received_at\": \"2024-03-16\",\n  \"warehouse_id\": 2,\n  \"receipt_lines\": [\n    {\n      \"purchase_order_shipment_line_id\": 301,\n      \"quantity\": 95\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment receipt has been successfully updated\",\n  \"data\": {\n    \"id\": 9001,\n    \"received_at\": \"2024-03-16\",\n    \"fulfilled_by\": {\n      \"id\": 1,\n      \"name\": \"Jane Smith\"\n    },\n    \"inbound_shipment_receipt_lines\": [\n      {\n        \"id\": 8101,\n        \"quantity\": 95,\n        \"purchase_order_line\": {\n          \"id\": 501,\n          \"product\": {\n            \"id\": 42,\n            \"sku\": \"WIDGET-001\",\n            \"supplier_sku\": \"SUP-WIDG-001\"\n          },\n          \"description\": \"Widget\",\n          \"received_quantity\": 95,\n          \"quantity\": 100\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Delete Receipt","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]},"description":"Delete an entire shipment receipt and reverse its inventory movements.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- receipt: InboundShipmentReceipt (ISR) ID — canonical wire id since Phase 4.4g.6a."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment receipt has been successfully deleted\"\n}"}]},{"name":"Delete Receipt Lines","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/receipts/{receipt}/delete-lines","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments","receipts",":receipt","delete-lines"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]},"description":"Delete specific lines from a shipment receipt.\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- receipt: InboundShipmentReceipt (ISR) ID — canonical wire id since Phase 4.4g.6a.\n\nBody:\n- ids (required): Array of InboundShipmentReceiptLine (ISRL) IDs to delete. The controller resolves them to the paired POSRL ids before reversing inventory.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8101,\n    8102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/receipts/{receipt}/delete-lines","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments","receipts",":receipt","delete-lines"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"purchase order shipment receipt has been successfully deleted\"\n}"}]},{"name":"Preview Receipt Delete Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt","delete-impact"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]},"description":"Read-only preview of the allocation-demotion impact of deleting this inbound shipment receipt. Because deleting it removes the stock it added, this behaves like a manual negative adjustment and returns one row per affected product: how much of the removed quantity is unallocated vs soft-allocated vs hard-allocated, plus every sales-order allocation and fulfillment (printed shipping label) the removal would disturb. Use it to decide which fulfillments to authorize voiding via `void_confirmations` on the deleting call. Nothing is mutated. A removal that only re-adds stock returns an empty `data` array.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/receipts/{receipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receipts",":receipt","delete-impact"],"variable":[{"key":"receipt","value":"9001","description":"InboundShipmentReceipt (ISR) ID — canonical wire id (Phase 4.4g.6a)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 5567,\n      \"product_sku\": \"WIDGET-BLUE\",\n      \"product_name\": \"Blue Widget\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 10,\n      \"soft_allocated_quantity\": 6,\n      \"hard_allocated_quantity\": 4,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88201,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 3120,\n          \"order_number\": \"SO-3120\",\n          \"customer_name\": \"Acme Co.\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 6\n        },\n        {\n          \"allocation_id\": 88205,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 3125,\n          \"order_number\": \"SO-3125\",\n          \"customer_name\": \"Beta LLC\",\n          \"fulfillment_id\": 90142,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 4,\n          \"allocation_ids\": [\n            88205\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Records per page. Default: 15","disabled":true}],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]},"description":"Get paginated activity log for a purchase order shipment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","activity-log"],"query":[{"key":"per_page","value":"15","description":"Records per page. Default: 15","disabled":true}],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8001,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"PurchaseOrderShipment\",\n      \"subject_id\": 50,\n      \"properties\": {},\n      \"causer_name\": \"John Doe\",\n      \"created_at\": \"2024-03-10T08:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]},"description":"Get paginated notes for a purchase order shipment, ordered by newest first.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 901,\n      \"note\": \"Checked with supplier — shipment on track\",\n      \"is_pinned\": false,\n      \"user\": {\n        \"id\": 1,\n        \"name\": \"Jane Smith\"\n      },\n      \"created_at\": \"2024-03-12T10:00:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Add Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]},"description":"Add a note to a purchase order shipment.\n\nAuthentication: Requires Bearer token.\n\nBody:\n- note (required): Note text content\n- is_pinned (optional): Whether the note should be pinned. Default: false","body":{"mode":"raw","raw":"{\n  \"note\": \"Supplier confirmed goods departed warehouse\",\n  \"is_pinned\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note has been successfully created\",\n  \"data\": {\n    \"id\": 902,\n    \"note\": \"Supplier confirmed goods departed warehouse\",\n    \"is_pinned\": true,\n    \"user\": {\n      \"id\": 1,\n      \"name\": \"Jane Smith\"\n    },\n    \"created_at\": \"2024-03-12T11:00:00Z\"\n  }\n}"}]},{"name":"Delete Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes",":noteId"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"},{"key":"noteId","value":"902","description":"Note ID to delete"}]},"description":"Delete a note from a purchase order shipment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-order-shipments/{shipment}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","purchase-order-shipments",":shipment","notes",":noteId"],"variable":[{"key":"shipment","value":"50","description":"Purchase order shipment ID"},{"key":"noteId","value":"902","description":"Note ID to delete"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"note 902 has been successfully deleted\"\n}"}]}]},{"name":"Inbound Shipments","item":[{"name":"Preview Inbound Shipment Release Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/receive/preview-release-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receive","preview-release-impact"]},"description":"Read-only preview of which back-ordered sales orders an inbound-shipment receive would fill, per receipt line. Send the same payload you would POST to receive the shipment; each line is resolved to its purchase order line, product and receive warehouse and evaluated against waiting back-ordered demand. Nothing is written.\n\nEach row describes one product the receive would restock. `releasable_quantity` is the number of incoming units that can be released to back-ordered demand; `orders[]` are the back-ordered sales orders that would be filled; `held_back[]` is demand that stays back-ordered, with `reason_kept` explaining why (e.g. \"Insufficient supply\").\n\nBody: the same shape as the receive call. Minimum: `received_at` plus either a `purchase_order_id` or `receipt_lines` (each with `purchase_order_line_id` or `purchase_order_line_reference` and a `quantity`). `warehouse_id` defaults to the purchase order's destination warehouse. `release_backorders` (true/false/null) mirrors the receive call's release control.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 20,\n  \"received_at\": \"2026-03-15\",\n  \"warehouse_id\": 2,\n  \"release_backorders\": true,\n  \"receipt_lines\": [\n    {\n      \"purchase_order_line_id\": 50,\n      \"quantity\": 8\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/receive/preview-release-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipments","receive","preview-release-impact"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"releasable_quantity\": 8,\n      \"orders\": [\n        {\n          \"sales_order_id\": 4602,\n          \"order_number\": \"SO-10501\",\n          \"customer_name\": \"Acme Retail\",\n          \"quantity\": 5\n        },\n        {\n          \"sales_order_id\": 4610,\n          \"order_number\": \"SO-10509\",\n          \"customer_name\": \"Gamma Foods\",\n          \"quantity\": 3\n        }\n      ],\n      \"held_back\": [\n        {\n          \"allocation_id\": 90311,\n          \"product_id\": 123,\n          \"sales_order_id\": 4620,\n          \"sales_order_line_id\": 55123,\n          \"sales_order_number\": \"SO-10518\",\n          \"customer_name\": \"Delta Mart\",\n          \"quantity\": 4,\n          \"from_status\": \"planned\",\n          \"to_status\": \"allocated\",\n          \"reason_kept\": \"Insufficient supply\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Inbound Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments?page=1&per_page=10&sort=-id&filter[search]=&filter[status]=&filter[date_from]=&filter[date_to]=&filter[supplier_id]=&filter[destination_warehouse_id]=&filter[purchase_order_id]=&filter[shipment_number.contains]=&filter[carrier.contains]=&filter[tracking_number.contains]=&filter[logistics_<slug>_estimate][on_or_after]=&filter[logistics_<slug>_actual][is_empty]=&filter_groups[conjunction]=and","host":["{{baseUrl}}"],"path":["api","inbound-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, shipment_number, status, carrier, tracking_number, expected_arrival_date, actual_arrival_date, shipped_at, num_lines, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"","description":"Search across shipment number, carrier, tracking number, supplier name","disabled":true},{"key":"filter[status]","value":"","description":"Filter by status (draft, in_transit, received, closed, cancelled)","disabled":true},{"key":"filter[date_from]","value":"","description":"Filter shipments created on or after this date (YYYY-MM-DD)","disabled":true},{"key":"filter[date_to]","value":"","description":"Filter shipments created on or before this date (YYYY-MM-DD)","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID (exact match)","disabled":true},{"key":"filter[destination_warehouse_id]","value":"","description":"Filter by destination warehouse ID","disabled":true},{"key":"filter[purchase_order_id]","value":"","description":"Filter shipments that include lines from the given purchase order ID","disabled":true},{"key":"filter[shipment_number.contains]","value":"","description":"Advanced text filter: shipment number contains value","disabled":true},{"key":"filter[carrier.contains]","value":"","description":"Advanced text filter: carrier contains value","disabled":true},{"key":"filter[tracking_number.contains]","value":"","description":"Advanced text filter: tracking number contains value","disabled":true},{"key":"filter[logistics_<slug>_estimate][on_or_after]","value":"","description":"Date filter on a logistics tracking field estimate date for the shipment. Replace &lt;slug> with any active LogisticsTrackingField slug (e.g. logistics_port-arrived_estimate). Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, is.","disabled":true},{"key":"filter[logistics_<slug>_actual][is_empty]","value":"","description":"Date filter on a logistics tracking field actual date for the shipment (e.g. logistics_customs-cleared_actual). Same operators as the estimate filter.","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"GroupedFilterSupport tree root conjunction: and/or. Use filter_groups[children][i][...] to express nested AND/OR conditions over the logistics tracking columns (column = `logistics_<slug>`_estimate or `logistics_<slug>`_actual).","disabled":true}]},"description":"Returns a paginated list of inbound shipments. Supports Spatie QueryBuilder filters and sorts.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAvailable sorts: id, shipment_number, status, carrier, tracking_number, expected_arrival_date, actual_arrival_date, shipped_at, num_lines, created_at, updated_at\n\nDefault sort: -id (newest first)\n\nPagination defaults: 10 per page\n\nLogistics tracking date filter columns: `logistics_<slug>`_estimate, `logistics_<slug>`_actual — where &lt;slug> is the slug of any active LogisticsTrackingField. Each shipment row also includes a logistics_tracking_field_values array with { field_slug, field_name, estimate_date, actual_date } entries for every active logistics tracking field.\n\nEach shipment row also includes a purchase_orders array — the distinct set of purchase orders linked via the shipment’s lines, each as { id, purchase_order_number }. A single linked PO yields a one-element array; multiple yields N entries."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments?page=1&per_page=10&sort=-id&filter[search]=&filter[status]=&filter[date_from]=&filter[date_to]=&filter[supplier_id]=&filter[destination_warehouse_id]=&filter[purchase_order_id]=&filter[shipment_number.contains]=&filter[carrier.contains]=&filter[tracking_number.contains]=&filter[logistics_<slug>_estimate][on_or_after]=&filter[logistics_<slug>_actual][is_empty]=&filter_groups[conjunction]=and","host":["{{baseUrl}}"],"path":["api","inbound-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, shipment_number, status, carrier, tracking_number, expected_arrival_date, actual_arrival_date, shipped_at, num_lines, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"","description":"Search across shipment number, carrier, tracking number, supplier name","disabled":true},{"key":"filter[status]","value":"","description":"Filter by status (draft, in_transit, received, closed, cancelled)","disabled":true},{"key":"filter[date_from]","value":"","description":"Filter shipments created on or after this date (YYYY-MM-DD)","disabled":true},{"key":"filter[date_to]","value":"","description":"Filter shipments created on or before this date (YYYY-MM-DD)","disabled":true},{"key":"filter[supplier_id]","value":"","description":"Filter by supplier ID (exact match)","disabled":true},{"key":"filter[destination_warehouse_id]","value":"","description":"Filter by destination warehouse ID","disabled":true},{"key":"filter[purchase_order_id]","value":"","description":"Filter shipments that include lines from the given purchase order ID","disabled":true},{"key":"filter[shipment_number.contains]","value":"","description":"Advanced text filter: shipment number contains value","disabled":true},{"key":"filter[carrier.contains]","value":"","description":"Advanced text filter: carrier contains value","disabled":true},{"key":"filter[tracking_number.contains]","value":"","description":"Advanced text filter: tracking number contains value","disabled":true},{"key":"filter[logistics_<slug>_estimate][on_or_after]","value":"","description":"Date filter on a logistics tracking field estimate date for the shipment. Replace &lt;slug> with any active LogisticsTrackingField slug (e.g. logistics_port-arrived_estimate). Operators: on, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, is.","disabled":true},{"key":"filter[logistics_<slug>_actual][is_empty]","value":"","description":"Date filter on a logistics tracking field actual date for the shipment (e.g. logistics_customs-cleared_actual). Same operators as the estimate filter.","disabled":true},{"key":"filter_groups[conjunction]","value":"and","description":"GroupedFilterSupport tree root conjunction: and/or. Use filter_groups[children][i][...] to express nested AND/OR conditions over the logistics tracking columns (column = `logistics_<slug>`_estimate or `logistics_<slug>`_actual).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"shipment_number\": \"IS-00042\",\n      \"status\": \"in_transit\",\n      \"status_label\": \"In Transit\",\n      \"supplier_id\": 7,\n      \"destination_warehouse_id\": 1,\n      \"carrier\": \"FedEx\",\n      \"tracking_number\": \"793644540\",\n      \"shipping_method_id\": 3,\n      \"expected_arrival_date\": \"2025-05-15\",\n      \"port_eta\": \"2025-05-08\",\n      \"warehouse_eta\": \"2025-05-15\",\n      \"actual_arrival_date\": null,\n      \"shipped_at\": \"2025-04-20T14:00:00+00:00\",\n      \"late_shipment\": false,\n      \"created_from_receipt\": false,\n      \"notes\": \"Priority shipment\",\n      \"created_by\": 1,\n      \"asn_last_sent_at\": null,\n      \"total_expected_quantity\": 250,\n      \"total_received_quantity\": 0,\n      \"inbound_shipment_lines_count\": 5,\n      \"purchase_orders\": [\n        {\n          \"id\": 30,\n          \"purchase_order_number\": \"PO-001029\"\n        },\n        {\n          \"id\": 31,\n          \"purchase_order_number\": \"PO-001030\"\n        }\n      ],\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Supplies\"\n      },\n      \"destination_warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 3,\n        \"name\": \"Ground\"\n      },\n      \"creator\": {\n        \"id\": 1,\n        \"name\": \"Admin User\"\n      },\n      \"inbound_shipment_lines\": [],\n      \"logistics_tracking_field_values\": [\n        {\n          \"field_slug\": \"port-arrived\",\n          \"field_name\": \"Port Arrived\",\n          \"estimate_date\": \"2025-05-08\",\n          \"actual_date\": null\n        },\n        {\n          \"field_slug\": \"customs-cleared\",\n          \"field_name\": \"Customs Cleared\",\n          \"estimate_date\": \"2025-05-12\",\n          \"actual_date\": null\n        }\n      ],\n      \"created_at\": \"2025-04-18T10:00:00.000000Z\",\n      \"updated_at\": \"2025-04-20T14:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://sku2.test/api/inbound-shipments?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"https://sku2.test/api/inbound-shipments?page=5\",\n  \"next_page_url\": \"https://sku2.test/api/inbound-shipments?page=2\",\n  \"path\": \"https://sku2.test/api/inbound-shipments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"Create Inbound Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments","host":["{{baseUrl}}"],"path":["api","inbound-shipments"]},"description":"Creates a new inbound shipment in Draft status. Lines are optional and can be added later.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- destination_warehouse_id (required): ID of the warehouse where the goods will actually land. This is the authoritative destination and is independent of the linked purchase order's header destination warehouse — a shipment may deliver a PO's goods to any warehouse, and one PO may have shipments to multiple warehouses.\n- supplier_id (optional): Supplier ID (auto-detected from PO lines if not provided)\n- carrier (optional): Carrier name\n- tracking_number (optional): Tracking number\n- shipping_method_id (optional): Shipping method ID\n- expected_arrival_date (optional): Expected arrival date (date)\n- notes (optional): Freeform notes\n- lines (optional): Array of shipment lines — each line requires purchase_order_line_id and expected_quantity\n\n**Logistics dates** (optional): `port_eta` and `warehouse_eta` are persisted as `LogisticsTrackingFieldValue` rows (slugs `port-arrived` / `warehouse-arrival`) and surfaced as flat fields on the response for backward compatibility.","body":{"mode":"raw","raw":"{\n  \"destination_warehouse_id\": 1,\n  \"supplier_id\": 7,\n  \"carrier\": \"FedEx\",\n  \"tracking_number\": null,\n  \"shipping_method_id\": 3,\n  \"expected_arrival_date\": \"2025-05-15\",\n  \"port_eta\": \"2025-05-08\",\n  \"warehouse_eta\": \"2025-05-15\",\n  \"notes\": \"Priority shipment\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"product_id\": 12,\n      \"expected_quantity\": 50\n    },\n    {\n      \"purchase_order_line_id\": 56,\n      \"product_id\": 13,\n      \"expected_quantity\": 25\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments","host":["{{baseUrl}}"],"path":["api","inbound-shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"shipment_number\": \"IS-00043\",\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"supplier_id\": 7,\n    \"destination_warehouse_id\": 1,\n    \"carrier\": \"FedEx\",\n    \"tracking_number\": null,\n    \"shipping_method_id\": 3,\n    \"expected_arrival_date\": \"2025-05-15\",\n    \"port_eta\": \"2025-05-08\",\n    \"warehouse_eta\": \"2025-05-15\",\n    \"actual_arrival_date\": null,\n    \"shipped_at\": null,\n    \"late_shipment\": false,\n    \"created_from_receipt\": false,\n    \"notes\": \"Priority shipment\",\n    \"created_by\": 1,\n    \"asn_last_sent_at\": null,\n    \"total_expected_quantity\": 75,\n    \"total_received_quantity\": 0,\n    \"inbound_shipment_lines_count\": 2,\n    \"created_at\": \"2025-04-23T10:00:00.000000Z\",\n    \"updated_at\": \"2025-04-23T10:00:00.000000Z\"\n  },\n  \"message\": \"inbound shipment created successfully\"\n}"}]},{"name":"Get Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"Inbound shipment ID"}]},"description":"Returns a single inbound shipment with its lines, supplier, destination warehouse, shipping method, purchase order references, and creator.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"Inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"shipment_number\": \"IS-00042\",\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"supplier_id\": 7,\n    \"destination_warehouse_id\": 1,\n    \"carrier\": \"FedEx\",\n    \"tracking_number\": null,\n    \"shipping_method_id\": 3,\n    \"expected_arrival_date\": \"2025-05-15\",\n    \"port_eta\": \"2025-05-08\",\n    \"warehouse_eta\": \"2025-05-15\",\n    \"actual_arrival_date\": null,\n    \"shipped_at\": null,\n    \"late_shipment\": false,\n    \"created_from_receipt\": false,\n    \"notes\": \"Fragile items\",\n    \"created_by\": 1,\n    \"asn_last_sent_at\": null,\n    \"total_expected_quantity\": 100,\n    \"total_received_quantity\": 0,\n    \"inbound_shipment_lines_count\": 2,\n    \"purchase_orders\": [\n      {\n        \"id\": 30,\n        \"purchase_order_number\": \"PO-001029\"\n      }\n    ],\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Supplies\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 3,\n      \"name\": \"Ground\"\n    },\n    \"creator\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    },\n    \"inbound_shipment_lines\": [\n      {\n        \"id\": 101,\n        \"inbound_shipment_id\": 42,\n        \"purchase_order_line_id\": 55,\n        \"product_id\": 12,\n        \"expected_quantity\": 50,\n        \"received_quantity\": 0\n      },\n      {\n        \"id\": 102,\n        \"inbound_shipment_id\": 42,\n        \"purchase_order_line_id\": 56,\n        \"product_id\": 13,\n        \"expected_quantity\": 50,\n        \"received_quantity\": 0\n      }\n    ],\n    \"created_at\": \"2025-04-18T10:00:00.000000Z\",\n    \"updated_at\": \"2025-04-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Inbound Shipment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Updates an inbound shipment. Only editable for shipments in Draft status. Lines array syncs the shipment lines (pass line id to update existing, omit id to add new, omit line entirely to delete).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**destination_warehouse_id** (optional): The shipment's destination warehouse may be changed only while the shipment has no receipts. Once goods have been received against the shipment it is locked — attempting to change it returns a 422 validation error on `destination_warehouse_id` (the receipts and their FIFO layers / inventory movements already point at it).\n\n**Logistics dates** (optional): `port_eta` and `warehouse_eta` are routed through `LogisticsTrackingFieldValue` rows. Pass them as part of the standard PATCH/PUT payload — the controller persists them only when the keys are present (use `null` to clear an existing value).","body":{"mode":"raw","raw":"{\n  \"destination_warehouse_id\": 2,\n  \"carrier\": \"UPS\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"shipping_method_id\": 2,\n  \"expected_arrival_date\": \"2025-05-20\",\n  \"port_eta\": \"2025-05-08\",\n  \"warehouse_eta\": \"2025-05-20\",\n  \"notes\": \"Updated tracking info\",\n  \"lines\": [\n    {\n      \"id\": 101,\n      \"purchase_order_line_id\": 55,\n      \"product_id\": 12,\n      \"expected_quantity\": 60\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"shipment_number\": \"IS-00042\",\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"carrier\": \"UPS\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"port_eta\": \"2025-05-08\",\n    \"warehouse_eta\": \"2025-05-20\",\n    \"updated_at\": \"2025-04-23T12:00:00.000000Z\"\n  },\n  \"message\": \"inbound shipment updated successfully\"\n}"}]},{"name":"Delete Inbound Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Deletes an inbound shipment. Only shipments in Draft or Cancelled status that have not been received can be deleted.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"inbound shipment deleted successfully\"\n}"}]},{"name":"Create Inbound Shipment From Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/from-invoice/{purchaseInvoice}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","from-invoice",":purchaseInvoice"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID to create the shipment from"}]},"description":"Create a new inbound shipment pre-filled from a supplier invoice. Each invoice line is converted into a shipment line that retains the purchase_invoice_line_id and resolves to its underlying purchase_order_line_id.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nValidation:\n- destination_warehouse_id: required, must exist on warehouses\n- lines: required, min 1, each must reference an existing purchase_invoice_line_id\n- expected_quantity: required, numeric > 0\n\nIf an invoice line has already been fully shipped on a prior shipment, the response includes a soft warning under warnings[] (key: `lines.<purchase_invoice_line_id>`) rather than failing the request. Set mark_as_shipped=true to immediately transition the new shipment to in_transit.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"destination_warehouse_id\": 1,\n  \"carrier\": \"FedEx\",\n  \"tracking_number\": \"793644540\",\n  \"shipping_method_id\": 3,\n  \"expected_arrival_date\": \"2025-06-15\",\n  \"etd\": null,\n  \"port_eta\": null,\n  \"warehouse_eta\": null,\n  \"notes\": \"Shipment created from invoice INV-2024-001\",\n  \"mark_as_shipped\": false,\n  \"lines\": [\n    {\n      \"purchase_invoice_line_id\": 201,\n      \"expected_quantity\": 10\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/from-invoice/{purchaseInvoice}","host":["{{baseUrl}}"],"path":["api","inbound-shipments","from-invoice",":purchaseInvoice"],"variable":[{"key":"purchaseInvoice","value":"42","description":"Purchase invoice ID to create the shipment from"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 87,\n    \"shipment_number\": \"IS-00087\",\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"supplier_id\": 7,\n    \"purchase_invoice_id\": 42,\n    \"destination_warehouse_id\": 1,\n    \"carrier\": \"FedEx\",\n    \"tracking_number\": \"793644540\",\n    \"shipping_method_id\": 3,\n    \"expected_arrival_date\": \"2025-06-15\",\n    \"actual_arrival_date\": null,\n    \"shipped_at\": null,\n    \"notes\": \"Shipment created from invoice INV-2024-001\",\n    \"created_by\": 1,\n    \"asn_last_sent_at\": null,\n    \"total_expected_quantity\": 10,\n    \"total_received_quantity\": 0,\n    \"inbound_shipment_lines_count\": 1,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Supplies Ltd\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 3,\n      \"name\": \"Ground\"\n    },\n    \"creator\": {\n      \"id\": 1,\n      \"name\": \"Admin User\"\n    },\n    \"purchase_invoice\": {\n      \"id\": 42,\n      \"supplier_invoice_number\": \"INV-2024-001\",\n      \"reference\": \"INV-2024-001\"\n    },\n    \"inbound_shipment_lines\": [\n      {\n        \"id\": 301,\n        \"inbound_shipment_id\": 87,\n        \"purchase_order_id\": 15,\n        \"purchase_order_line_id\": 101,\n        \"purchase_invoice_line_id\": 201,\n        \"product_id\": 10,\n        \"expected_quantity\": 10,\n        \"received_quantity\": 0\n      }\n    ],\n    \"created_at\": \"2025-05-07T10:00:00.000000Z\",\n    \"updated_at\": \"2025-05-07T10:00:00.000000Z\"\n  },\n  \"message\": \"inbound shipment created successfully\",\n  \"warnings\": []\n}"}]},{"name":"Mark As Planned","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/mark-as-planned","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","mark-as-planned"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Transitions the shipment from Draft to Planned status. Planned is an optional intermediate state indicating the shipment is scheduled but has not yet shipped. Planned shipments do not reserve quantity against purchase order fulfillment.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe shipment must be in Draft status and must have at least one line.\n\nTakes no request body.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/mark-as-planned","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","mark-as-planned"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"planned\",\n    \"status_label\": \"Planned\"\n  },\n  \"message\": \"Inbound shipment marked as planned.\"\n}"}]},{"name":"Unmark As Planned","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/unmark-as-planned","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","unmark-as-planned"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Reverts a Planned shipment back to Draft status, allowing edits. Only shipments currently in Planned status can be unmarked.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTakes no request body.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/unmark-as-planned","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","unmark-as-planned"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\"\n  },\n  \"message\": \"Inbound shipment unmarked as planned.\"\n}"}]},{"name":"Mark As Shipped","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","mark-as-shipped"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Transitions the shipment from Draft to In Transit status and records carrier/tracking information.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- carrier (optional): Carrier name\n- tracking_number (optional): Tracking number\n- shipped_at (optional): Date/time shipped (defaults to now)","body":{"mode":"raw","raw":"{\n  \"carrier\": \"FedEx\",\n  \"tracking_number\": \"793644540123\",\n  \"shipped_at\": \"2025-04-23T10:00:00\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/mark-as-shipped","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","mark-as-shipped"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"in_transit\",\n    \"status_label\": \"In Transit\",\n    \"carrier\": \"FedEx\",\n    \"tracking_number\": \"793644540123\",\n    \"shipped_at\": \"2025-04-23T10:00:00+00:00\"\n  },\n  \"message\": \"Inbound shipment marked as shipped.\"\n}"}]},{"name":"Receive Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/receive","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","receive"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Records receipt of items for the specified shipment lines and updates inventory. Can be called multiple times for partial receiving.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- received_at (required): Date/time of receipt\n- warehouse_id (optional): Override destination warehouse for this receipt\n- receipt_lines (required): Array of lines to receive — each requires inbound_shipment_line_id and quantity (min 0.0001)","body":{"mode":"raw","raw":"{\n  \"received_at\": \"2025-05-15T09:00:00\",\n  \"warehouse_id\": 1,\n  \"receipt_lines\": [\n    {\n      \"inbound_shipment_line_id\": 101,\n      \"quantity\": 50\n    },\n    {\n      \"inbound_shipment_line_id\": 102,\n      \"quantity\": 25\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/receive","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","receive"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"received\",\n    \"status_label\": \"Received\",\n    \"total_received_quantity\": 75,\n    \"actual_arrival_date\": \"2025-05-15\"\n  },\n  \"message\": \"Items received successfully.\"\n}"}]},{"name":"Create Receipt","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/receipts","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","receipts"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Creates a native InboundShipmentReceipt with lines and posts FIFO/inventory directly via the new IS-first path (Phase 1 of the InboundShipment / PurchaseOrderShipment unification). Coexists with the legacy `/receive` endpoint, which delegates through the PO shipment receipt path.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- received_at (required, datetime): Date/time of receipt\n- warehouse_id (required, exists:warehouses): Receiving warehouse for this receipt\n- notes (optional, string): Free-text notes attached to the receipt\n- receipt_lines (required, min 1):\n  - inbound_shipment_line_id (required, exists:inbound_shipment_lines): Must belong to this inbound shipment\n  - quantity (required, numeric, min 0.0001)\n\nSide effects:\n- Creates an `inbound_shipment_receipts` row + per-line `inbound_shipment_receipt_lines` rows\n- Creates a FIFO layer + InventoryMovement per line (TYPE_PURCHASE_RECEIPT) at the receipt's warehouse\n- Increments `received_quantity` on each InboundShipmentLine and the matching PurchaseOrderLine\n- Transitions the InboundShipment to `partially_received` or `received` (sets `fully_received_at` when all lines are fully received)","body":{"mode":"raw","raw":"{\n  \"received_at\": \"2026-04-26T09:00:00\",\n  \"warehouse_id\": 1,\n  \"notes\": \"Partial receipt — pallet 1 of 3\",\n  \"receipt_lines\": [\n    {\n      \"inbound_shipment_line_id\": 101,\n      \"quantity\": 50\n    },\n    {\n      \"inbound_shipment_line_id\": 102,\n      \"quantity\": 25\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/receipts","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","receipts"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 18,\n    \"inbound_shipment_id\": 42,\n    \"warehouse_id\": 1,\n    \"received_at\": \"2026-04-26T09:00:00.000000Z\",\n    \"notes\": \"Partial receipt — pallet 1 of 3\",\n    \"received_by\": {\n      \"id\": 7,\n      \"name\": \"Casey Receiver\"\n    },\n    \"inbound_shipment_receipt_lines\": [\n      {\n        \"id\": 31,\n        \"inbound_shipment_receipt_id\": 18,\n        \"inbound_shipment_line_id\": 101,\n        \"purchase_order_line_id\": 5012,\n        \"quantity\": \"50.0000\",\n        \"total_cost\": \"1250.0000\"\n      },\n      {\n        \"id\": 32,\n        \"inbound_shipment_receipt_id\": 18,\n        \"inbound_shipment_line_id\": 102,\n        \"purchase_order_line_id\": 5013,\n        \"quantity\": \"25.0000\",\n        \"total_cost\": \"500.0000\"\n      }\n    ]\n  },\n  \"message\": \"Inbound shipment receipt created successfully.\"\n}"}]},{"name":"Cancel Shipment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/cancel","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","cancel"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Cancels an inbound shipment. Only shipments in Draft or In Transit status can be cancelled.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/cancel","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","cancel"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"cancelled\",\n    \"status_label\": \"Cancelled\"\n  },\n  \"message\": \"Inbound shipment cancelled.\"\n}"}]},{"name":"Close Shipment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/close","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","close"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Closes an inbound shipment, marking it as fully processed. Only Received shipments can be closed.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/close","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","close"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"closed\",\n    \"status_label\": \"Closed\"\n  },\n  \"message\": \"Inbound shipment closed.\"\n}"}]},{"name":"Revert to Draft","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","revert-to-draft"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Reverts an In Transit shipment back to Draft status, allowing edits. Only In Transit shipments that have not been received can be reverted.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","revert-to-draft"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\"\n  },\n  \"message\": \"Inbound shipment reverted to draft.\"\n}"}]},{"name":"Preview Import Resolution","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/resolve-import","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","resolve-import"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Resolves SKUs and PO numbers from a bulk import file, returning matched products and purchase order lines before committing. Use this as a preview/validation step before calling import-items.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- skus (required): Array of SKUs or barcodes to resolve (1-5000 items)\n- po_numbers (optional): Array of PO numbers to filter matching lines","body":{"mode":"raw","raw":"{\n  \"skus\": [\n    \"SKU-001\",\n    \"SKU-002\",\n    \"SKU-003\"\n  ],\n  \"po_numbers\": [\n    \"PO-0042\",\n    \"PO-0043\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/resolve-import","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","resolve-import"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"resolved\": [\n    {\n      \"sku\": \"SKU-001\",\n      \"product_id\": 12,\n      \"product_name\": \"Widget A\",\n      \"matched_po_lines\": [\n        {\n          \"purchase_order_line_id\": 55,\n          \"po_number\": \"PO-0042\",\n          \"unreceived_quantity\": 100\n        }\n      ]\n    }\n  ],\n  \"unresolved\": [\n    \"SKU-003\"\n  ]\n}"}]},{"name":"Import Items","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/import-items","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","import-items"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Bulk imports items into an inbound shipment. Adds shipment lines for each item. Set replace_existing=true to clear existing lines first.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- items (required): Array of items (1-5000) — each requires product_id and expected_quantity; purchase_order_line_id is optional\n- replace_existing (optional): If true, removes all existing unlinked lines before adding. Default: false","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"product_id\": 12,\n      \"purchase_order_line_id\": 55,\n      \"expected_quantity\": 50\n    },\n    {\n      \"product_id\": 13,\n      \"purchase_order_line_id\": null,\n      \"expected_quantity\": 25\n    }\n  ],\n  \"replace_existing\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/import-items","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","import-items"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"shipment_number\": \"IS-00042\",\n    \"status\": \"draft\",\n    \"inbound_shipment_lines_count\": 2\n  },\n  \"message\": \"Items imported successfully.\"\n}"}]},{"name":"List Available Purchase Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/available-purchase-orders","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","available-purchase-orders"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Returns open purchase orders that have unreceived lines available to be added to this inbound shipment. Excludes POs where all lines are already fully assigned.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Warehouse scope:** results are NOT restricted to the shipment's destination warehouse. The PO header `destination_warehouse_id` is only a pre-fill default — an inbound shipment carries its own authoritative destination, so any open, unreceived PO may be assigned regardless of its header warehouse. POs whose header warehouse matches this shipment's destination are surfaced first as the likeliest match, then ordered by id descending."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/available-purchase-orders","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","available-purchase-orders"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10,\n      \"purchase_order_number\": \"PO-0042\",\n      \"date\": \"2025-04-01\",\n      \"supplier_name\": \"Acme Supplies\",\n      \"unreceived_lines_count\": 3,\n      \"total_unreceived_quantity\": 150,\n      \"lines_on_active_shipments\": 1,\n      \"all_lines_assigned\": false\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 5\n}"}]},{"name":"List Available Purchase Order Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/available-po-lines?purchase_order_ids=10,11&search=","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","available-po-lines"],"query":[{"key":"purchase_order_ids","value":"10,11","description":"Comma-separated list of purchase order IDs to fetch lines for (required)","disabled":true},{"key":"search","value":"","description":"Optional search to filter lines by SKU or product name","disabled":true}],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Returns unreceived PO lines grouped by purchase order for the given PO IDs. Each line shows how much quantity is available to assign to this shipment.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- purchase_order_ids (required): Comma-separated PO IDs\n- search (optional): Filter by product SKU or name"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/available-po-lines?purchase_order_ids=10,11&search=","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","available-po-lines"],"query":[{"key":"purchase_order_ids","value":"10,11","description":"Comma-separated list of purchase order IDs to fetch lines for (required)","disabled":true},{"key":"search","value":"","description":"Optional search to filter lines by SKU or product name","disabled":true}],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_id\": 10,\n      \"purchase_order_number\": \"PO-0042\",\n      \"supplier_name\": \"Acme Supplies\",\n      \"lines\": [\n        {\n          \"purchase_order_line_id\": 55,\n          \"product_id\": 12,\n          \"sku\": \"SKU-001\",\n          \"product_name\": \"Widget A\",\n          \"ordered_quantity\": 100,\n          \"received_quantity\": 0,\n          \"unreceived_quantity\": 100,\n          \"already_on_shipment\": false,\n          \"on_current_shipment\": false,\n          \"assigned_quantity\": 0,\n          \"available_quantity\": 100\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Returns all landed cost bills attached to this inbound shipment, ordered by invoice date descending. Includes bill lines and allocations to purchase order lines.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"vendor_id\": 3,\n      \"vendor_name\": \"Freight Co.\",\n      \"invoice_number\": \"INV-20250420\",\n      \"invoice_date\": \"2025-04-20\",\n      \"currency_id\": 1,\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"proration_strategy\": \"cost_based\",\n      \"total_amount\": 500,\n      \"totals\": {\n        \"line_count\": 1,\n        \"amount\": 500,\n        \"tax\": 0,\n        \"grand_total\": 500\n      },\n      \"lines\": [\n        {\n          \"id\": 20,\n          \"description\": \"Ocean freight\",\n          \"quantity\": 1,\n          \"amount\": 500,\n          \"extended_amount\": 500,\n          \"nominal_code_id\": 5\n        }\n      ],\n      \"allocations\": [\n        {\n          \"id\": 11,\n          \"allocation_amount\": 250,\n          \"allocation_percentage\": 50,\n          \"proration_strategy\": \"cost_based\",\n          \"purchase_order_line_id\": 55,\n          \"purchase_order_line\": {\n            \"id\": 55,\n            \"description\": \"Widget A\",\n            \"quantity\": 100,\n            \"product\": {\n              \"id\": 12,\n              \"name\": \"Widget A\",\n              \"sku\": \"SKU-001\"\n            }\n          }\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Create Bill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Creates a landed cost bill attached to this inbound shipment. Cannot be added to cancelled shipments.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- vendor_id (required): Vendor/supplier ID\n- invoice_number (required, unique): Invoice number\n- invoice_date (required): Invoice date\n- currency_id (optional): Currency ID\n- currency_rate (optional): Exchange rate\n- proration_strategy (required): One of: cost_based, quantity_based, weight_based, manual\n- lines (required): Array of bill line items — each requires description, quantity, amount; nominal_code_id optional\n- allocations (optional): Array of allocations to PO lines or warehouse transfer lines — allocation amounts must not exceed bill total","body":{"mode":"raw","raw":"{\n  \"vendor_id\": 3,\n  \"invoice_number\": \"INV-20250420\",\n  \"invoice_date\": \"2025-04-20\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"cost_based\",\n  \"lines\": [\n    {\n      \"description\": \"Ocean freight\",\n      \"quantity\": 1,\n      \"amount\": 500,\n      \"nominal_code_id\": 5,\n      \"tax_rate_id\": null\n    }\n  ],\n  \"allocations\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"warehouse_transfer_line_id\": null,\n      \"allocation_amount\": 250,\n      \"proration_strategy\": \"cost_based\"\n    },\n    {\n      \"purchase_order_line_id\": 56,\n      \"warehouse_transfer_line_id\": null,\n      \"allocation_amount\": 250,\n      \"proration_strategy\": \"cost_based\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"vendor_id\": 3,\n    \"vendor_name\": \"Freight Co.\",\n    \"invoice_number\": \"INV-20250420\",\n    \"invoice_date\": \"2025-04-20\",\n    \"total_amount\": 500\n  },\n  \"message\": \"Bill created successfully.\"\n}"}]},{"name":"Get Bill","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]},"description":"Returns a single bill attached to this inbound shipment with all lines and allocations.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"vendor_id\": 3,\n    \"vendor_name\": \"Freight Co.\",\n    \"invoice_number\": \"INV-20250420\",\n    \"invoice_date\": \"2025-04-20\",\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"proration_strategy\": \"cost_based\",\n    \"total_amount\": 500,\n    \"lines\": [\n      {\n        \"id\": 20,\n        \"description\": \"Ocean freight\",\n        \"quantity\": 1,\n        \"amount\": 500,\n        \"extended_amount\": 500\n      }\n    ],\n    \"allocations\": []\n  }\n}"}]},{"name":"Update Bill","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]},"description":"Updates a bill attached to this inbound shipment. Cannot modify bills on a cancelled shipment.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- vendor_id (required): Vendor ID\n- invoice_number (required): Invoice number\n- invoice_date (required): Invoice date\n- currency_id (optional): Currency ID\n- currency_rate (optional): Exchange rate\n- proration_strategy (optional): One of: cost_based, quantity_based, weight_based, manual\n- allocations (optional): Updated allocations — replaces existing allocations","body":{"mode":"raw","raw":"{\n  \"vendor_id\": 3,\n  \"invoice_number\": \"INV-20250420-REV\",\n  \"invoice_date\": \"2025-04-20\",\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"proration_strategy\": \"quantity_based\",\n  \"allocations\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"warehouse_transfer_line_id\": null,\n      \"allocation_amount\": 300\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"invoice_number\": \"INV-20250420-REV\",\n    \"proration_strategy\": \"quantity_based\",\n    \"total_amount\": 500\n  },\n  \"message\": \"Bill updated successfully.\"\n}"}]},{"name":"Delete Bill","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]},"description":"Deletes a bill attached to this inbound shipment. Cannot delete bills on a cancelled shipment.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/bills/{bill}","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","bills",":bill"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."},{"key":"bill","value":"7","description":"The bill ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bill deleted successfully.\"\n}"}]},{"name":"Landed Cost Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/landed-cost-preview","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","landed-cost-preview"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]},"description":"Returns a per-PO-line aggregation of all landed cost allocations across every bill attached to this shipment. Useful for previewing total landed costs before closing.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipments/{inbound_shipment}/landed-cost-preview","host":["{{baseUrl}}"],"path":["api","inbound-shipments",":inbound_shipment","landed-cost-preview"],"variable":[{"key":"inbound_shipment","value":"42","description":"The inbound shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_line_id\": 55,\n      \"sku\": \"SKU-001\",\n      \"product_name\": \"Widget A\",\n      \"total_landed_cost\": 250\n    },\n    {\n      \"purchase_order_line_id\": 56,\n      \"sku\": \"SKU-002\",\n      \"product_name\": \"Widget B\",\n      \"total_landed_cost\": 250\n    }\n  ]\n}"}]},{"name":"Get Inbound Shipment Receipt","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Returns full details for an inbound shipment receipt including the parent inbound shipment, supplier, destination warehouse, all distinct purchase orders represented across receipt lines, line items (with product + PO line context), and the linked accounting transaction.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA single receipt may span multiple purchase orders — the `purchase_orders` array lists every distinct PO referenced by its lines. Each line also carries its own `purchase_order` reference for per-line attribution.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"received_at\": \"2024-04-15T14:00:00Z\",\n    \"created_at\": \"2024-04-15T14:00:00Z\",\n    \"updated_at\": \"2024-04-15T14:05:00Z\",\n    \"notes\": \"Received in good condition\",\n    \"fulfilled_by\": {\n      \"id\": 5,\n      \"name\": \"John Smith\"\n    },\n    \"inbound_shipment\": {\n      \"id\": 12,\n      \"shipment_number\": \"ISH-2024-0012\",\n      \"reference\": \"ISH-2024-0012\"\n    },\n    \"purchase_orders\": [\n      {\n        \"id\": 20,\n        \"po_number\": \"PO-2024-0020\",\n        \"purchase_order_date\": \"2024-04-01\",\n        \"currency_code\": \"USD\",\n        \"currency_rate\": 1,\n        \"is_tax_included\": false\n      },\n      {\n        \"id\": 21,\n        \"po_number\": \"PO-2024-0021\",\n        \"purchase_order_date\": \"2024-04-02\",\n        \"currency_code\": \"USD\",\n        \"currency_rate\": 1,\n        \"is_tax_included\": false\n      }\n    ],\n    \"supplier\": {\n      \"id\": 3,\n      \"name\": \"Acme Supplies Co.\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\",\n      \"display_name\": \"Main Warehouse\"\n    },\n    \"lines\": [\n      {\n        \"id\": 10,\n        \"quantity\": 100,\n        \"total_cost\": 1250,\n        \"purchase_order\": {\n          \"id\": 20,\n          \"po_number\": \"PO-2024-0020\"\n        },\n        \"purchase_order_line\": {\n          \"id\": 50,\n          \"quantity\": 100,\n          \"amount\": 1250,\n          \"discount_rate\": 0,\n          \"received_quantity\": 100,\n          \"description\": \"Blue Widget\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Blue Widget\",\n          \"image_url\": \"https://cdn.example.com/widget.jpg\"\n        }\n      }\n    ],\n    \"summary\": {\n      \"total_lines\": 1,\n      \"total_units\": 100,\n      \"total_purchase_orders\": 2\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Inbound Shipment Receipt","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Deletes an inbound shipment receipt and reverses the inventory movements it created. Because it removes the stock the receipt added, it behaves like a manual negative adjustment and rebalances any now-unbacked reservations to backorder.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Voiding hard-allocated labels (`void_confirmations`):** When this removal would consume stock that is hard-allocated to a fulfillment (a printed shipping label), include a `void_confirmations` array in the request body — one entry per fulfillment you authorize voiding: `{ \"fulfillment_id\": <int>, \"attempt_void\": true, \"reason\": <string|null> }`. Each confirmed label is voided first so the removal can proceed. Omit `void_confirmations` (or leave out a fulfillment that is in the way) and the request is rejected with 422 when hard-allocated stock blocks the operation. Call the matching delete-impact / reverse-impact preview endpoint first to see exactly which fulfillments block it.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipment receipt deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Purchase Receipt Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Paginated activity log entries for an inbound shipment receipt. Supports search across causer name, properties JSON, and event; filterable by event, causer, and date range.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","activity-log"],"query":[{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 901,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"InboundShipmentReceipt\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"received_at\": \"2024-04-15T14:00:00Z\"\n        }\n      },\n      \"causer_name\": \"John Smith\",\n      \"created_at\": \"2024-04-15T14:00:00Z\"\n    }\n  ],\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/fifo-layers?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","fifo-layers"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Paginated list of FIFO layers created by this inbound shipment receipt's lines. Each layer is scoped to `link_type = InboundShipmentReceiptLine` and the receipt's line IDs.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/fifo-layers?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","fifo-layers"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"fifo_layer_date\": \"2024-04-15\",\n      \"quantity\": 100,\n      \"fulfilled_quantity\": 0,\n      \"available_quantity\": 100,\n      \"unit_cost\": 12.5,\n      \"total_cost\": 1250,\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"source_type\": \"inbound_shipment_receipt\",\n      \"source_reference\": \"ISR-1\",\n      \"link_type\": \"App\\\\Models\\\\InboundShipmentReceiptLine\",\n      \"link_id\": 10,\n      \"parent_link_id\": 20,\n      \"detail_link_id\": 1,\n      \"condition\": \"active\",\n      \"created_at\": \"2024-04-15T14:00:00Z\"\n    }\n  ],\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Paginated inventory movements generated by this inbound shipment receipt's lines. Includes per-movement FIFO layer reference and unit/total cost.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/inventory-movements?per_page=15","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","inventory-movements"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5500,\n      \"type\": \"purchase_receipt\",\n      \"inventory_status\": \"active\",\n      \"quantity\": 100,\n      \"reference\": \"ISR-1\",\n      \"link_type\": \"App\\\\Models\\\\InboundShipmentReceiptLine\",\n      \"link_id\": 10,\n      \"parent_link_id\": 20,\n      \"detail_link_id\": 1,\n      \"product_id\": 42,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 12.5,\n      \"unit_cost_provisional\": false,\n      \"total_cost\": 1250,\n      \"layer\": {\n        \"name\": \"FIFO Layer #1001\",\n        \"layer_type\": \"App\\\\Models\\\\FifoLayer\",\n        \"layer_id\": 1001\n      },\n      \"inventory_movement_date\": \"2024-04-15\",\n      \"created_at\": \"2024-04-15T14:00:00Z\"\n    }\n  ],\n  \"first_page_url\": \"...\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"...\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"...\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","generate-accounting-transaction"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Generates (or regenerates) the accounting transaction entry for an inbound shipment receipt. Returns the created transaction with its nominal-code-tagged lines.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","generate-accounting-transaction"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"transaction_date\": \"2024-04-15\",\n    \"reference\": \"ISR-1\"\n  },\n  \"message\": \"Accounting transaction generated successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Preview Inbound Shipment Receipt Delete Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","delete-impact"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]},"description":"Read-only preview of the allocation-demotion impact of deleting this inbound shipment receipt. Because deleting it removes the stock it added, this behaves like a manual negative adjustment and returns one row per affected product: how much of the removed quantity is unallocated vs soft-allocated vs hard-allocated, plus every sales-order allocation and fulfillment (printed shipping label) the removal would disturb. Use it to decide which fulfillments to authorize voiding via `void_confirmations` on the deleting call. Nothing is mutated. A removal that only re-adds stock returns an empty `data` array.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/delete-impact","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","delete-impact"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 5567,\n      \"product_sku\": \"WIDGET-BLUE\",\n      \"product_name\": \"Blue Widget\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 10,\n      \"soft_allocated_quantity\": 6,\n      \"hard_allocated_quantity\": 4,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88201,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 3120,\n          \"order_number\": \"SO-3120\",\n          \"customer_name\": \"Acme Co.\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 6\n        },\n        {\n          \"allocation_id\": 88205,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 3125,\n          \"order_number\": \"SO-3125\",\n          \"customer_name\": \"Beta LLC\",\n          \"fulfillment_id\": 90142,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 4,\n          \"allocation_ids\": [\n            88205\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Preview Receipt Line Quantity","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/lines/{line}/quantity-preview?quantity=8","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"8","description":"Proposed new received quantity","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"},{"key":"line","value":"5012","description":"Receipt line ID"}]},"description":"Read-only preview of the effect of changing a receipt line's received quantity before saving. Returns how the change flows onto the inbound shipment line quantity and the purchase order line quantity (`implications`), the FIFO teardown/redistribution needed for a reduction (`inventory`), and - when the new quantity is LOWER than the current one - a `demotion_impact` list describing which order allocations the reduction would consume.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach row is one product whose stock the action would consume. `shortfall_quantity` is how much more than available the action removes (stock goes negative when above zero). `unallocated_quantity` / `soft_allocated_quantity` / `hard_allocated_quantity` split the consumed quantity into free / soft-reserved / hard-allocated (label-printed) units. `affected_allocations[]` lists the order allocations consumed, highest priority first: `allocation_type` is `soft` or `hard`, and for hard rows `fulfillment_id`/`carrier` identify the label while `carrier_void_supported` and `voidable_status` say whether it can be voided through the API.\n\n`demotion_impact` is empty for an increase or a no-op; only a reduction can strand an allocation. Use it to decide whether Update Receipt Line Quantity needs `void_confirmations`.\n\nQuery parameters:\n- `quantity` (integer, required) - the proposed new received quantity.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/lines/{line}/quantity-preview?quantity=8","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","lines",":line","quantity-preview"],"query":[{"key":"quantity","value":"8","description":"Proposed new received quantity","disabled":true}],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"},{"key":"line","value":"5012","description":"Receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"receipt_type\": \"inbound_shipment\",\n    \"line_id\": 5012,\n    \"current_quantity\": 12,\n    \"new_quantity\": 8,\n    \"delta\": -4,\n    \"requires_confirmation\": true,\n    \"can_update\": true,\n    \"implications\": {\n      \"shipment_quantity\": {\n        \"label\": \"Inbound shipment line quantity\",\n        \"current\": 12,\n        \"after_if_updated\": 8,\n        \"differs_after_edit\": true\n      },\n      \"order_quantity\": {\n        \"label\": \"Purchase order line quantity\",\n        \"current\": 12,\n        \"after_if_updated\": 8,\n        \"received_after_edit\": 8,\n        \"differs_after_edit\": true\n      }\n    },\n    \"inventory\": {\n      \"fifo_layer\": {\n        \"id\": 44120,\n        \"product_id\": 123,\n        \"warehouse_id\": 2,\n        \"original_quantity\": 12,\n        \"fulfilled_quantity\": 5,\n        \"available_quantity\": 7\n      },\n      \"decrease_quantity\": 4,\n      \"available_without_reassignment\": 7,\n      \"usage_quantity_to_redistribute\": 0,\n      \"requires_redistribution\": false,\n      \"can_redistribute\": true,\n      \"blocks_update\": false,\n      \"alternative_available_quantity\": 0,\n      \"alternative_shortage_quantity\": 0,\n      \"movable_usage_quantity\": 0,\n      \"movable_usage_shortage_quantity\": 0,\n      \"usages\": [],\n      \"alternative_layers\": []\n    },\n    \"demotion_impact\": [\n      {\n        \"product_id\": 123,\n        \"product_sku\": \"WIDGET-001\",\n        \"product_name\": \"Blue Widget 500ml\",\n        \"shortfall_quantity\": 0,\n        \"unallocated_quantity\": 4,\n        \"soft_allocated_quantity\": 3,\n        \"hard_allocated_quantity\": 2,\n        \"affected_allocations\": [\n          {\n            \"allocation_id\": 88213,\n            \"allocation_type\": \"soft\",\n            \"sales_order_id\": 4521,\n            \"order_number\": \"SO-10442\",\n            \"customer_name\": \"Acme Retail\",\n            \"fulfillment_id\": null,\n            \"carrier\": null,\n            \"carrier_void_supported\": null,\n            \"voidable_status\": null,\n            \"voidable_detail\": null,\n            \"quantity\": 3\n          },\n          {\n            \"allocation_id\": 88240,\n            \"allocation_type\": \"hard\",\n            \"sales_order_id\": 4530,\n            \"order_number\": \"SO-10450\",\n            \"customer_name\": \"Beta Wholesale\",\n            \"fulfillment_id\": 77120,\n            \"carrier\": \"ups\",\n            \"carrier_void_supported\": true,\n            \"voidable_status\": \"voidable\",\n            \"voidable_detail\": null,\n            \"quantity\": 2\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Update Receipt Line Quantity","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/lines/{line}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","lines",":line"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"},{"key":"line","value":"5012","description":"Receipt line ID"}]},"description":"Change a receipt line's received quantity. An increase adds stock to the line's FIFO layer; a reduction removes it. Reducing below the currently allocated quantity consumes order allocations - soft reservations are demoted to backorder, and hard-allocated (label-printed) units require voiding their labels first.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nConfirmation flow: preview the change first (see Preview Receipt Line Quantity). If the change alters the shipment or order line quantity, or needs FIFO redistribution, the request returns 409 with the preview payload until you resubmit with `confirmed_implications` (and, when redistribution is needed, `redistribute_usages`) set to true.\n\nBody fields:\n- `quantity` (integer, required) - the new received quantity (>= 0).\n- `confirmed_implications` (boolean, optional) - acknowledge the shipment/order quantity changes.\n- `redistribute_usages` (boolean, optional) - authorize moving existing FIFO usages to other layers.\n- `update_shipment_quantity` (boolean, optional) - also adjust the inbound shipment line quantity.\n- `update_order_quantity` (boolean, optional) - also adjust the purchase order line quantity.\n\nOptional void confirmations (`void_confirmations`):\nThis action consumes the stock reserved for it. When that stock is hard-allocated to a sales-order fulfillment whose shipping label is already printed, include one `void_confirmations` entry per fulfillment to authorize voiding that label and reclaiming its stock; omit it and the request fails with a 422 conflict listing the blocking fulfillments.\n- `void_confirmations` (array, optional)\n- `void_confirmations[].fulfillment_id` (integer, required) - the fulfillment whose label may be voided.\n- `void_confirmations[].attempt_void` (boolean, required) - true to void the label and consume its stock.\n- `void_confirmations[].reason` (string, optional) - free-text audit note for the void.\n\n422 (hard-allocation conflict): returned when the action would consume stock hard-allocated to a printed shipping label and no matching `void_confirmations` entry authorized voiding it. `conflict.requested_quantity` is what the action needs, `available_quantity` is what is free, `protected_quantity` is the hard-allocated + held amount, and `conflicting_allocations` lists the blocking fulfillments (`line_details.fulfillment_id`).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"quantity\": 8,\n  \"confirmed_implications\": true,\n  \"redistribute_usages\": false,\n  \"update_shipment_quantity\": false,\n  \"update_order_quantity\": false,\n  \"void_confirmations\": [\n    {\n      \"fulfillment_id\": 77120,\n      \"attempt_void\": true,\n      \"reason\": \"Customer cancelled after the label was printed\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/inbound-shipment-receipts/{receipt}/lines/{line}","host":["{{baseUrl}}"],"path":["api","inbound-shipment-receipts",":receipt","lines",":line"],"variable":[{"key":"receipt","value":"1","description":"Inbound shipment receipt ID"},{"key":"line","value":"5012","description":"Receipt line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"received_at\": \"2026-03-15T14:00:00Z\",\n    \"notes\": null,\n    \"inbound_shipment\": {\n      \"id\": 12,\n      \"shipment_number\": \"ISH-2026-0012\",\n      \"reference\": \"ISH-2026-0012\"\n    },\n    \"supplier\": {\n      \"id\": 3,\n      \"name\": \"Acme Supplies Co.\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\",\n      \"display_name\": \"Main Warehouse\"\n    },\n    \"lines\": [\n      {\n        \"id\": 5012,\n        \"quantity\": 8,\n        \"total_cost\": 200,\n        \"purchase_order_line\": {\n          \"id\": 50,\n          \"quantity\": 12,\n          \"received_quantity\": 8\n        },\n        \"product\": {\n          \"id\": 123,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Blue Widget 500ml\"\n        }\n      }\n    ]\n  },\n  \"message\": \"Receipt line quantity updated successfully.\"\n}"}]}]},{"name":"Sales Order OCR","item":[{"name":"Upload Customer PO Document","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/upload","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr","upload"]},"description":"Upload a customer PO PDF to start the OCR extraction process. Returns the extraction ID and a tracked-job ID; the actual OCR work runs asynchronously via Azure Document Intelligence. Poll GET /sales-orders/ocr/{id} until status is 'pending_review' (or 'failed' / 'duplicate_detected').\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse 201 includes:\n- extraction_id\n- tracked_job_log_id (for the JobProgressTray)\n- status: 'processing'","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"customer_id","type":"text","value":""}]}}},{"name":"Get OCR Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Retrieve a single OCR extraction record by ID. Returns the extracted header (customer PO number, dates, customer match, totals), per-line items with quantities/prices/match status, and the current review status.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nStatuses: processing, pending_review, confirmed, failed, rejected, duplicate_detected\n\nSource-related fields:\n- `source` — `manual`, `email`, or `email_body` (new). `email_body` indicates the extraction came from email body text rather than a PDF attachment, processed via Azure OpenAI gpt-4o-mini.\n- `source_email_from`, `source_email_subject` — set when `source` is `email` or `email_body`.\n- `source_body_text`, `source_body_html` — set when `source` is `email_body`. The frontend renders these in a body preview pane instead of the PDF viewer.\n- `sales_order_id` — the linked sales order created from this extraction (set when `status` is `confirmed`). When the linked sales order is later deleted, the FK `nullOnDelete` clears this field, leaving the extraction in an \"orphaned confirmed\" state which the rescan/delete/clone-from/reclassify guards treat as unlocked (see those endpoints' descriptions).\n- `sales_order` — eager-loaded summary `{ id, number, order_date, customer_po_number }` of the linked sales order, present when `sales_order_id` is set. The OCR review page uses it to render a click-through link to the created sales order's detail page. Omitted from list responses where the relation is not loaded.\n- `clone_of_sales_order_id` — set when this extraction was cloned from a prior sales order (via the LLM `clone_last_order` flag, or manually via the Clone Lines from Sales Order endpoint).\n- `clone_of_sales_order` — eager-loaded summary `{ id, number, order_date, customer_po_number }` of the source order when `clone_of_sales_order_id` is set.\n\n**Header field normalization (added 2026-05-06):**\nThe extractors store header keys with names that vary by source:\n- Azure Document Intelligence (PDF) returns `po_number` and `invoice_date`.\n- OpenAI (email body) returns `po_number` and `order_date`.\n\nThe API response layers canonical UI keys on top of these so the frontend has stable field names to bind to:\n- `customer_po_number` — derived from `po_number` (or already-set canonical value).\n- `po_date` — derived from `order_date` → `invoice_date` (or already-set canonical value).\n- `deliver_by_date` — the customer-requested delivery date. The PDF flow stores it under `due_date` (Azure `DueDate` / the LLM header extractor maps `deliver_by_date` → `due_date`); the email-body flow emits `deliver_by_date` directly. The response bridges `due_date` → `deliver_by_date` so the UI always has the key.\n\nThe original extractor keys are preserved alongside the canonical ones, so consumers that read `po_number` / `invoice_date` / `order_date` / `due_date` directly continue to work.\n\n**Per-PO ship-to address (added 2026-05-18):**\nThe header includes `ship_to_address` — a nullable object `{ name, company, address1, address2, city, province, zip, country_code }` extracted from the customer PO's \"Ship To\" / \"Deliver To\" block. A customer can specify a different shipping destination on each PO, so this is captured per-extraction. It is `null` when the PO states no separate shipping destination."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"status\": \"pending_review\",\n    \"sales_order_id\": null,\n    \"sales_order\": null,\n    \"source\": \"manual\",\n    \"source_email_from\": null,\n    \"source_email_subject\": null,\n    \"source_body_text\": null,\n    \"source_body_html\": null,\n    \"clone_of_sales_order_id\": null,\n    \"file_url\": \"https://sku2.test/api/sales-orders/ocr/3/pdf\",\n    \"page_count\": 1,\n    \"header\": {\n      \"invoice_number\": null,\n      \"invoice_date\": \"2026-04-27\",\n      \"due_date\": \"2026-05-18\",\n      \"customer_name\": \"Las Cosas Kitchen Shoppe\",\n      \"vendor_name\": \"A Bar Above\",\n      \"vendor_address\": null,\n      \"customer_address\": null,\n      \"ship_to_address\": {\n        \"name\": \"APPLEBEES CORTLANDT MOHEGAN 251\",\n        \"company\": \"DOHERTY APPLE NY STATEWIDE LLC\",\n        \"address1\": \"3127 EAST MAIN STREET\",\n        \"address2\": null,\n        \"city\": \"MOHEGAN LAKE\",\n        \"province\": \"NY\",\n        \"zip\": \"10547\",\n        \"country_code\": \"US\"\n      },\n      \"total_amount\": 595.2,\n      \"subtotal\": 595.2,\n      \"tax_amount\": null,\n      \"currency_code\": \"USD\",\n      \"po_number\": \"BAR42326\",\n      \"customer_po_number\": \"BAR42326\",\n      \"po_date\": \"2026-04-27\",\n      \"deliver_by_date\": \"2026-05-18\",\n      \"matched_customer_id\": 142,\n      \"matched_customer_name\": \"Stephen Young Group - LA\"\n    },\n    \"lines\": [\n      {\n        \"id\": \"3f1b1c4e-3a76-4a2a-9f9b-2c1d8e6c0e21\",\n        \"raw_sku\": \"JGR-BELL-GO\",\n        \"raw_description\": \"Bell Jigger Gold\",\n        \"quantity\": 6,\n        \"unit_price\": 10.5,\n        \"unit_price_source\": \"extracted\",\n        \"line_total\": 63,\n        \"confidence\": 0.97,\n        \"match_status\": \"exact\",\n        \"matched_product_id\": 4321,\n        \"matched_product_name\": \"Bell Jigger Gold\",\n        \"matched_product_sku\": \"JGR-BELL-GO\",\n        \"catalog_price\": 10.5,\n        \"price_variance_pct\": 0,\n        \"customer_sku_mapping_id\": null,\n        \"saved_financial_line_type_id\": null,\n        \"resolved_from_history\": false\n      }\n    ],\n    \"unmatched_line_count\": 0,\n    \"azure_cost_usd\": 0.001,\n    \"error_message\": null,\n    \"created_at\": \"2026-05-06T14:22:11.000000Z\"\n  }\n}"}]},{"name":"Delete OCR Extraction","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Delete an OCR extraction record and its associated uploaded PDF. Use this to discard an extraction that will not be converted to a sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the extraction is *locked confirmed* — i.e. `status='confirmed'` AND `sales_order_id` is non-null. Orphaned confirmed extractions (linked sales order was deleted, `sales_order_id` is null via FK `nullOnDelete`) are treated as unlocked and *can* be deleted."}},{"name":"Stream Extraction PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/pdf","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","pdf"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Stream the original uploaded PDF back to the client through the backend (avoids CORS issues when fetching from S3 directly). Returns Content-Type: application/pdf with inline disposition. 404 if the underlying S3 object is missing.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create Sales Order from Extraction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/create-order","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","create-order"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Create a sales order from a reviewed OCR extraction. The request body contains the confirmed/edited field values from the review UI.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWhen save_sku_mappings is true, any resolved customer SKU-to-product mappings from the extraction lines are persisted to the customer's SKU mapping table for future use.\n\n**ship_to_address (optional, nullable object):** the per-PO shipping destination extracted from the customer PO's \"Ship To\" block. A customer can have a different ship-to address on each PO, so this is captured per-extraction rather than read from the customer's default address. When present and non-empty, it is passed through to the API as the order's `shipping_address`. Fields: `name`, `company`, `address1`, `address2`, `city`, `province` (all nullable, max 255), `zip` (nullable, max 50), `country_code` (nullable, max 10). Omit or send null when the PO states no separate shipping destination.\n\nReturns the newly created sales order id and number, and marks the extraction status as 'confirmed'.","body":{"mode":"raw","raw":"{\n  \"customer_id\": 1,\n  \"customer_po_number\": \"PO-12345\",\n  \"order_date\": \"2024-01-15\",\n  \"deliver_by_date\": \"2024-02-15\",\n  \"sales_channel_id\": 1,\n  \"currency_id\": 1,\n  \"memo_for_customer\": null,\n  \"ship_to_address\": {\n    \"name\": \"APPLEBEES CORTLANDT MOHEGAN 251\",\n    \"company\": \"DOHERTY APPLE NY STATEWIDE LLC\",\n    \"address1\": \"3127 EAST MAIN STREET\",\n    \"address2\": null,\n    \"city\": \"MOHEGAN LAKE\",\n    \"province\": \"NY\",\n    \"zip\": \"10547\",\n    \"country_code\": \"US\"\n  },\n  \"save_sku_mappings\": true,\n  \"lines\": [\n    {\n      \"product_id\": 1,\n      \"quantity\": 10,\n      \"amount\": 25,\n      \"description\": \"Widget\",\n      \"warehouse_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/create-order","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","create-order"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"sales_order_number\": \"SO-004821\"\n  },\n  \"message\": \"Sales order created successfully.\"\n}"}]},{"name":"Clone Lines from Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/clone-from","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","clone-from"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Clone confirmed lines from a prior sales order into this extraction's lines_data.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUsed when the extraction's customer history (or LLM analysis on email-body extractions) suggests this PO is a repeat order — the reviewer can pull lines from a previous confirmed sales order in one click instead of editing line by line.\n\nRequest body:\n- `sales_order_id` (required, integer) — the source sales order to clone from. Must belong to the same customer as the extraction (when extraction has a customer_id set).\n\nBehavior:\n- Replaces (or merges with) `lines_data` on the extraction with one entry per source order line.\n- Each cloned line records the matched product (sku, name, average cost) and a unit price computed as `amount / quantity`.\n- Lines whose product is archived or missing are still copied but flagged `match_status: unmatched` so the reviewer must reassign.\n- Sets `clone_of_sales_order_id` on the extraction so the UI can show the \"cloned from\" banner.\n\nReturns the updated SalesOrderOcrExtraction resource (with `cloneOfSalesOrder` eager-loaded).\n\nErrors:\n- 422 — Confirmed extractions cannot be modified (only when the extraction is *locked*: `status='confirmed'` AND `sales_order_id` is non-null. Orphaned confirmed extractions — where the linked sales order was deleted and the FK `nullOnDelete` cleared `sales_order_id` — are treated as unlocked and *can* be re-cloned).\n- 422 — Source order belongs to a different customer than the extraction.\n- 404 — Source sales order not found.\n- 422 — Validation: `sales_order_id` is required and must exist in `sales_orders`.","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 12345\n}","options":{"raw":{"language":"json"}}}}},{"name":"Reclassify as Supplier Invoice","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/reclassify-as-supplier-invoice","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","reclassify-as-supplier-invoice"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Reclassify a Customer PO OCR extraction as a Supplier Invoice. Used when an inbound email was routed to orders@ but the attached PDF is actually a supplier invoice.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nCopies the file_path, header_data, lines_data, and source email metadata into a new PurchaseInvoiceOcrExtraction (status: pending_review). Marks the original SalesOrderOcrExtraction as 'rejected' with an error_message that references the new extraction ID, preserving an audit trail.\n\nReturns 422 if the extraction is *locked confirmed* — i.e. `status='confirmed'` AND `sales_order_id` is non-null. Orphaned confirmed extractions (linked sales order was deleted, `sales_order_id` is null) are treated as unlocked and *can* be reclassified.\n\nResponse:\n```json\n{ \"data\": { \"purchase_invoice_extraction_id\": 42 } }\n```\n\nThe frontend should redirect to /purchases/invoices/ocr/{id} for the user to continue review."}},{"name":"Rescan Customer PO OCR","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/ocr/{extraction_id}/rescan","host":["{{baseUrl}}"],"path":["api","sales-orders","ocr",":extraction_id","rescan"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Re-run OCR extraction on an existing Customer PO record. Resets status to 'processing', clears any prior error_message, and re-dispatches the OCR job. Useful when the extraction failed initially (status='failed') or when the matching/parsing logic has improved and the user wants to re-derive the extracted data from the original PDF or email body.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 if:\n- Extraction is *locked confirmed* — i.e. `status='confirmed'` AND `sales_order_id` is non-null (already used to create a sales order that still exists — cannot be re-scanned). Orphaned confirmed extractions (linked sales order deleted, `sales_order_id` null via FK `nullOnDelete`) are treated as unlocked and *can* be re-scanned.\n- Both file_path and source_body_text are null (no source content to re-scan)\n\nResponse 200:\n```json\n{\n  \"data\": {\n    \"extraction_id\": 7,\n    \"tracked_job_log_id\": 1234,\n    \"status\": \"processing\"\n  },\n  \"message\": \"Re-scan started\"\n}\n```\n\nThe frontend subscribes to the returned tracked_job_log_id via the global JobProgressTray (job name starts with 'Customer PO OCR:') and re-fetches the extraction once the job completes."}}]},{"name":"Purchase Invoice OCR","item":[{"name":"Upload Supplier Invoice PDF","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/upload","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr","upload"]},"description":"Upload a supplier invoice PDF to start the OCR extraction. Requires Invoice OCR to be enabled in Settings → Invoice OCR (returns 422 if not enabled).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nResponse 201:\n```json\n{\n  \"data\": {\n    \"extraction_id\": 7,\n    \"tracked_job_log_id\": 1234,\n    \"status\": \"processing\"\n  },\n  \"message\": \"OCR processing started\"\n}\n```\n\nPoll GET /purchase-invoices/ocr/{id} until status is 'pending_review' (or 'failed' / 'duplicate_detected').","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"supplier_id","type":"text","value":""}]}}},{"name":"Get Invoice Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Retrieve a purchase invoice OCR extraction record. Returns extracted header data merged with matched supplier and PO info, line items with per-line product matches (5-tier match: supplier_sku → SKU → barcode → MPN → fuzzy name), candidate purchase orders for the supplier (with attach-to-existing-invoice metadata), error_message (if failed/duplicate), and inbound-email source metadata.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nExample 200 response:\n```json\n{\n  \"data\": {\n    \"id\": 7,\n    \"status\": \"pending_review\",\n    \"file_url\": \"https://sku2.test/api/purchase-invoices/ocr/7/pdf\",\n    \"page_count\": 2,\n    \"header\": {\n      \"supplier_invoice_number\": \"INV-9988\",\n      \"invoice_date\": \"2026-04-20\",\n      \"due_date\": \"2026-05-20\",\n      \"subtotal\": 1250.00,\n      \"tax_amount\": 125.00,\n      \"total_amount\": 1375.00,\n      \"po_number\": \"PO-12345\",\n      \"matched_supplier_id\": 12,\n      \"matched_supplier_name\": \"Acme Supplies\",\n      \"matched_purchase_order_id\": 88,\n      \"matched_purchase_order_number\": \"PO-12345\"\n    },\n    \"is_matched_supplier\": true,\n    \"extracted_supplier_name\": \"Acme Supplies, Inc.\",\n    \"lines\": [\n      {\n        \"raw_sku\": \"WID-001\",\n        \"description\": \"Widget Type 1\",\n        \"quantity\": 50,\n        \"unit_price\": 25.00,\n        \"line_total\": 1250.00,\n        \"matched_product_id\": 4321,\n        \"matched_product_sku\": \"WID-001\",\n        \"matched_product_name\": \"Widget Type 1 — Blue\"\n      }\n    ],\n    \"unmatched_line_count\": 0,\n    \"azure_cost_usd\": 0.0125,\n    \"error_message\": null,\n    \"source\": \"email\",\n    \"source_email_from\": \"billing@acme.com\",\n    \"source_email_subject\": \"Invoice INV-9988\",\n    \"supplier\": { \"id\": 12, \"name\": \"Acme Supplies\" },\n    \"purchase_order\": {\n      \"id\": 88,\n      \"purchase_order_number\": \"PO-12345\",\n      \"purchase_order_date\": \"2026-04-15\"\n    },\n    \"candidate_purchase_orders\": [\n      {\n        \"id\": 88,\n        \"purchase_order_number\": \"PO-12345\",\n        \"purchase_order_date\": \"2026-04-15\",\n        \"order_status\": \"closed\",\n        \"existing_invoice_id\": 211,\n        \"existing_invoice_number\": \"INV-9988\",\n        \"existing_invoice_has_document\": false,\n        \"can_attach_document\": true\n      }\n    ],\n    \"created_at\": \"2026-04-25T10:30:00.000000Z\"\n  }\n}\n```\n\n**Candidate purchase orders behavior:** The backend includes both open POs for the matched supplier AND a fallback lookup by PO number across all statuses (open/closed). When a candidate PO has `can_attach_document: true`, the frontend should offer the user the option to attach the OCR'd PDF to the existing invoice via POST `/api/purchase-invoices/ocr/{extraction}/attach-to-invoice` instead of creating a new invoice.\n\n**Existing-invoice fields (`existing_invoice_id`, `existing_invoice_number`, `existing_invoice_has_document`, `can_attach_document`):** These are populated ONLY when the OCR'd `supplier_invoice_number` matches an existing invoice on that PO (case-insensitive, trimmed comparison). For partial-invoice scenarios where a single PO has multiple invoices with different supplier_invoice_numbers, the candidate PO returns `null` for these fields when no invoice matches the OCR'd number — allowing a new invoice to be created instead of triggering a false \"already invoiced\" warning."}},{"name":"Delete Extraction","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Delete a purchase invoice OCR extraction record and its associated PDF. Confirmed extractions cannot be deleted (returns 422).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Stream Extraction PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/pdf","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","pdf"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Stream the original supplier invoice PDF through the backend (avoids CORS when fetching from S3). Returns Content-Type: application/pdf, inline disposition. 404 if the underlying S3 object is missing.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Create Purchase Invoice from Extraction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/create-invoice","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","create-invoice"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Accept the reviewed/edited extraction data (header + lines + cost lines) and create a PurchaseInvoice record, marking the extraction as 'confirmed'. The extraction must be in `pending_review` or `duplicate_detected` status (a duplicate-detected extraction is allowed because the user may confirm it is not actually a duplicate and proceed to create a new invoice).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe payload supports two kinds of line items:\n- **`lines`** — product line items, attached to PurchaseOrderLines on the target PO. Each may set `purchase_order_line_id` to bind to a specific PO line, or `ignored: true` to skip persisting (kept for audit but not invoiced).\n- **`cost_lines`** — non-product COST-classified financial lines (freight, duty, handling). These create FinancialLine records on the PurchaseInvoice keyed by a COST-classification `financial_line_type_id`. `allocate_to_products` is always `true` for OCR-created cost lines.\n\nAt least one of `lines` or `cost_lines` is required (`lines` is `required_without:cost_lines`).\n\n**Request body fields:**\n| Field | Type | Required | Notes |\n|-------|------|----------|-------|\n| purchase_order_id | integer | yes | Must exist in `purchase_orders`. |\n| invoice_number | string | yes | Max 255 chars. |\n| invoice_date | date | yes | |\n| due_date | date | no | |\n| lines | array | required_without:cost_lines | Product lines. |\n| lines[].description | string | no | |\n| lines[].qty | numeric | yes | Negative values are accepted (e.g. PO-level discount rows surfaced as standalone negative lines). The manager filters out `ignored: true` and `match_status: discount_confirmation` lines before persisting. |\n| lines[].unit_price | numeric | yes | Negative values are accepted (e.g. PO-level discount rows surfaced as standalone negative lines). The manager filters out `ignored: true` and `match_status: discount_confirmation` lines before persisting. |\n| lines[].purchase_order_line_id | integer | no | Must exist in `purchase_order_lines`. |\n| lines[].ignored | boolean | no | Skip persisting this line. |\n| cost_lines | array | no | Non-product COST FinancialLines. |\n| cost_lines[].financial_line_type_id | integer | yes (per cost line) | Must exist in `financial_line_types` and be COST classification. |\n| cost_lines[].description | string | no | Max 500 chars. |\n| cost_lines[].quantity | numeric | yes (per cost line) | Min 0. |\n| cost_lines[].amount | numeric | yes (per cost line) | Min 0. Per-line amount (not total). |\n| remember_mappings | boolean | no | When `true`, upserts `(supplier_id, description) → financial_line_type_id` mappings into `supplier_description_mappings` so future OCR imports auto-tag matching descriptions as cost lines (Tier 0 match). |\n\n**Response 201:**\n```json\n{\n  \"data\": {\n    \"purchase_invoice_id\": 312,\n    \"extraction_id\": 7\n  },\n  \"message\": \"Purchase invoice created from OCR extraction.\"\n}\n```\n\n**Response 422 — wrong status (e.g. `confirmed` or `failed`):**\n```json\n{ \"message\": \"Only extractions pending review can be used to create an invoice.\" }\n```\n\n**Response 422 — validation failure (no lines or cost lines):**\n```json\n{\n  \"message\": \"The lines field is required when cost lines is not present.\",\n  \"errors\": { \"lines\": [\"The lines field is required when cost lines is not present.\"] }\n}\n```","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 88,\n  \"invoice_number\": \"INV-9988\",\n  \"invoice_date\": \"2026-04-20\",\n  \"due_date\": \"2026-05-20\",\n  \"lines\": [\n    {\n      \"description\": \"Widget Type 1\",\n      \"qty\": 50,\n      \"unit_price\": 25,\n      \"purchase_order_line_id\": 421,\n      \"ignored\": false\n    }\n  ],\n  \"cost_lines\": [\n    {\n      \"financial_line_type_id\": 12,\n      \"description\": \"Freight Shipping\",\n      \"quantity\": 1,\n      \"amount\": 25\n    }\n  ],\n  \"remember_mappings\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Attach OCR Document to Existing Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/attach-to-invoice","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","attach-to-invoice"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Attach the OCR'd PDF to an existing PurchaseInvoice that does not yet have a document. Used when the OCR extraction's PO number matches a PO that has already been invoiced — instead of creating a new invoice, the user can retroactively attach the extracted PDF to the prior invoice as the supporting document.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThis is the primary resolution path for `duplicate_detected` extractions: the OCR detected the same supplier + invoice number combination already exists, and the user wants to attach the new PDF to that prior invoice.\n\nUploads the original PDF (still in S3 from the upload step) as a PurchaseInvoiceAttachment, marks the extraction as 'confirmed', and links the extraction to the target invoice.\n\n**Request body fields:**\n| Field | Type | Required | Notes |\n|-------|------|----------|-------|\n| purchase_invoice_id | integer | yes | Must exist in `purchase_invoices`. The invoice's supplier_id must match the extraction's matched supplier and the invoice must not already have an attachment. |\n\n**Allowed only when:**\n- Extraction status is `pending_review` or `duplicate_detected`\n- Target invoice's supplier matches the extraction's matched supplier\n- Target invoice has no existing attachments (i.e. `can_attach_document: true` from the candidate_purchase_orders block)\n\nResponse 201:\n```json\n{\n  \"data\": {\n    \"purchase_invoice_id\": 211,\n    \"extraction_id\": 7,\n    \"attachment_id\": 559\n  },\n  \"message\": \"OCR document attached to existing invoice.\"\n}\n```\n\nResponse 422 — wrong extraction status (e.g. `confirmed` or `failed`):\n```json\n{ \"message\": \"Only extractions pending review can be attached.\" }\n```\n\nResponse 422 — supplier mismatch:\n```json\n{ \"message\": \"The selected invoice's supplier does not match the extraction's matched supplier.\" }\n```\n\nResponse 422 — invoice already has a document:\n```json\n{ \"message\": \"The selected invoice already has an attached document.\" }\n```\n\nResponse 404 — invoice not found (route model + findOrFail failure).","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_id\": 211\n}","options":{"raw":{"language":"json"}}}}},{"name":"Re-scan Extraction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/rescan","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","rescan"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Re-dispatch the OCR extraction job for an existing PurchaseInvoiceOcrExtraction. Resets status to 'processing', clears any previous error_message, and re-queues a background job against the original PDF in S3. Useful when Azure misread the document (wrong supplier match, missing lines) and the user wants to re-run extraction without re-uploading.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAllowed from any status except 'confirmed' (a confirmed extraction has already produced a PurchaseInvoice and is locked).\n\nResponse 200:\n```json\n{\n  \"data\": {\n    \"extraction_id\": 7,\n    \"tracked_job_log_id\": 1234,\n    \"status\": \"processing\"\n  },\n  \"message\": \"Re-scan started.\"\n}\n```\n\nResponse 422 — confirmed extraction:\n```json\n{ \"message\": \"Confirmed extractions cannot be re-scanned.\" }\n```\n\nResponse 422 — file no longer available:\n```json\n{ \"message\": \"Cannot re-scan — original file is no longer available.\" }\n```\n\nPoll GET /purchase-invoices/ocr/{id} until status flips back to 'pending_review' (or 'failed').","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Reclassify as Customer PO","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/reclassify-as-customer-po","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","reclassify-as-customer-po"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Reclassify a Supplier Invoice OCR extraction as a Customer PO. Used when an inbound email was routed to invoices@ but the attached PDF is actually a customer purchase order — the inverse of POST /api/sales-orders/ocr/{id}/reclassify-as-supplier-invoice.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nCopies the file_path, header_data, lines_data, and source email metadata (source, source_email_from, source_email_subject, source_email_recipient) into a new SalesOrderOcrExtraction (status: pending_review). Marks the original PurchaseInvoiceOcrExtraction as 'rejected' with an error_message that references the new extraction ID, preserving an audit trail.\n\nReturns 422 if the extraction is in 'confirmed' status (confirmed extractions cannot be reclassified).\n\nResponse 200:\n```json\n{\n  \"message\": \"Reclassified as customer PO.\",\n  \"data\": { \"sales_order_extraction_id\": 42 }\n}\n```\n\nThe frontend should redirect to /orders/sales-orders/ocr/{id} for the user to continue review."}},{"name":"Reclassify as Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/reclassify-as-credit","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","reclassify-as-credit"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]},"description":"Reclassify a Supplier Invoice OCR extraction as a Vendor Credit. Used when a document landed in the supplier-invoice queue but is actually a credit memo — the inverse of POST /api/vendor-credits/ocr/{id}/reclassify-as-invoice.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBehavior:\n- Copies the PDF to a new S3 key under ocr/vendor-credits/ (the original file is left in place for the rejected record's audit trail)\n- Creates a new VendorCreditOcrExtraction carrying over supplier_id, source, source email metadata (source_email_from, source_email_forwarded_from, source_email_subject, source_email_recipient, source_message_id), and the stored Azure raw_response\n- Marks the original PurchaseInvoiceOcrExtraction as 'rejected' with an error_message referencing the new extraction ID\n- If a stored Azure raw_response exists, the vendor credit pipeline re-processes it synchronously (no new Azure call, no extra cost). Otherwise a Scan Credit Memo job is dispatched to re-analyze the PDF.\n\nOnly extractions in pending_review, duplicate_detected, or failed status can be reclassified.\n\nErrors:\n- 422 if the extraction is in 'confirmed' status\n- 422 if the extraction status is not reclassifiable, or the original file is no longer available\n\nThe frontend should direct the user to the vendor credit OCR review page for the returned vendor_credit_extraction_id."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/ocr/{purchase_extraction_id}/reclassify-as-credit","host":["{{baseUrl}}"],"path":["api","purchase-invoices","ocr",":purchase_extraction_id","reclassify-as-credit"],"variable":[{"key":"purchase_extraction_id","value":"","description":"The purchase extraction ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Reclassified as vendor credit. Review it in the vendor credit OCR queue.\",\n  \"data\": {\n    \"vendor_credit_extraction_id\": 57\n  }\n}"}]},{"name":"Get Attachment OCR Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","ocr"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]},"description":"Get the latest OCR extraction result for an invoice attachment. Read-only — never triggers a scan.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns `\"data\": null` when the attachment has not been scanned yet (or the first scan is still running). Re-scanning keeps history; only the newest extraction is returned.\n\nThe extraction contains:\n- `header` — extracted invoice fields, each as `{value, confidence}` (invoice_number, invoice_date, due_date, vendor_name, total_amount, subtotal, tax_amount, currency_code, po_number, addresses).\n- `extracted_lines` — document lines matched to purchase order product lines (`matched_po_line_id`) or cost lines (`matched_financial_line_id`), with `match_confidence` of `high`, `medium`, `low`, or `none`, plus unit price variance versus the PO.\n- `unmatched_lines` — lines that could not be matched; `ignored` reflects choices saved via Apply OCR Extraction to Invoice.\n\nReturns 404 if the attachment does not belong to the given invoice. Requires the `purchase-orders:read` token scope."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","ocr"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"attachment_id\": 45,\n    \"provider\": \"azure_document_intelligence\",\n    \"confidence_score\": 0.94,\n    \"header\": {\n      \"invoice_number\": {\n        \"value\": \"INV-20441\",\n        \"confidence\": 0.98\n      },\n      \"invoice_date\": {\n        \"value\": \"2026-06-28\",\n        \"confidence\": 0.97\n      },\n      \"due_date\": {\n        \"value\": \"2026-07-28\",\n        \"confidence\": 0.95\n      },\n      \"vendor_name\": {\n        \"value\": \"Shenzhen Widget Co.\",\n        \"confidence\": 0.96\n      },\n      \"customer_name\": {\n        \"value\": \"Acme Retail LLC\",\n        \"confidence\": 0.91\n      },\n      \"total_amount\": {\n        \"value\": 12450,\n        \"confidence\": 0.99\n      },\n      \"subtotal\": {\n        \"value\": 11840,\n        \"confidence\": 0.98\n      },\n      \"tax_amount\": {\n        \"value\": 0,\n        \"confidence\": 0.97\n      },\n      \"currency_code\": {\n        \"value\": \"USD\",\n        \"confidence\": 0.99\n      },\n      \"po_number\": {\n        \"value\": \"PO-1088\",\n        \"confidence\": 0.93\n      }\n    },\n    \"extracted_lines\": [\n      {\n        \"product_code\": \"WDG-100\",\n        \"description\": \"Widget 100-pack WDG-100\",\n        \"quantity\": 500,\n        \"unit_price\": 22.5,\n        \"line_total\": 11250,\n        \"confidence\": 0.97,\n        \"matched_po_line_id\": 3311,\n        \"matched_financial_line_id\": null,\n        \"matched_product_id\": 902,\n        \"matched_po_line_description\": \"Widget 100-pack\",\n        \"matched_po_line_unit_price\": 22,\n        \"matched_po_line_quantity\": 500,\n        \"match_confidence\": \"high\",\n        \"price_variance\": 0.5,\n        \"price_variance_pct\": 2.27\n      },\n      {\n        \"product_code\": null,\n        \"description\": \"Shipping Cost\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"line_total\": 610,\n        \"confidence\": null,\n        \"matched_po_line_id\": null,\n        \"matched_financial_line_id\": 74,\n        \"matched_product_id\": null,\n        \"matched_po_line_description\": \"Shipping\",\n        \"matched_po_line_unit_price\": 610,\n        \"matched_po_line_quantity\": 1,\n        \"match_confidence\": \"high\",\n        \"price_variance\": null,\n        \"price_variance_pct\": null\n      }\n    ],\n    \"unmatched_lines\": [\n      {\n        \"product_code\": null,\n        \"description\": \"Fuel surcharge\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"line_total\": 45,\n        \"confidence\": 0.88,\n        \"matched_po_line_id\": null,\n        \"matched_financial_line_id\": null,\n        \"matched_product_id\": null,\n        \"match_confidence\": \"none\",\n        \"ignored\": true\n      }\n    ],\n    \"created_at\": \"2026-07-01T14:25:01.000000Z\"\n  }\n}"}]},{"name":"Scan Invoice Attachment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","ocr"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]},"description":"Start an OCR scan of a purchase invoice attachment. No request body.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Asynchronous** — this queues a background scan and returns immediately. The attachment's `ocr_status` moves through `processing` and finishes as `completed` (with `ocr_processed_at` set) or `failed` (with `ocr_error_message`). Poll **Get Attachment OCR Extraction** or **List Purchase Invoice Attachments** to track progress. Scanning does not modify the invoice itself — use **Apply OCR Extraction to Invoice** to accept the results.\n\nThe scan extracts invoice header fields and line items from the document and matches them against the linked purchase order's product and cost lines.\n\nRequirements and errors:\n- Invoice OCR must be enabled in Settings, otherwise 422.\n- Only PDF and image (JPEG/PNG) attachments can be scanned — 422 for other types.\n- Archived invoices return 422.\n- A scan already in progress for the attachment returns 409.\n\nRequires the `purchase-orders:write` token scope."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","attachments",":attachment","ocr"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"},{"key":"attachment","value":"45","description":"Attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 812,\n    \"attachment_id\": 45\n  },\n  \"message\": \"OCR processing started\"\n}"}]},{"name":"Apply OCR Extraction to Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/ocr-apply","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","ocr-apply"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]},"description":"Apply reviewed OCR extraction results to a purchase invoice. Synchronous — the invoice is updated immediately.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `extraction_id` (integer, optional) — the extraction whose unmatched-line decisions should be saved.\n- `header.supplier_invoice_number` (string, optional, max 255) and `header.purchase_invoice_date` (date, optional) — update the invoice header. Null values are ignored (fields cannot be blanked here).\n- `lines` (array, required, min 1) — the resulting invoice lines. Each line needs `quantity_invoiced` (numeric, required, min 0), optional `unit_price` (numeric, min 0), and either `purchase_order_line_id` (existing PO line) or `financial_line_id` (existing cost line).\n- `unmatched_lines` (array, optional) — snapshot of unmatched document lines; set `ignored: true` on lines to exclude. Saved onto the extraction for future reads.\n\n**Line replacement semantics:** entries with `purchase_order_line_id` fully sync the invoice's product lines — invoice lines whose PO line is not in the payload are **deleted**, new ones are created, and existing ones are updated. Entries with `financial_line_id` update the invoice's cost lines, or copy the PO's planned cost line onto the invoice if not present (the PO's own line is never modified).\n\nAfter applying, the invoice's approval status is re-evaluated: price or quantity variances against the PO (or invoicing more than was received) set `pending_approval`; otherwise `auto_approved`.\n\nArchived invoices return 422. Requires the `purchase-orders:write` token scope.","body":{"mode":"raw","raw":"{\n  \"extraction_id\": 17,\n  \"header\": {\n    \"supplier_invoice_number\": \"INV-20441\",\n    \"purchase_invoice_date\": \"2026-06-28\"\n  },\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 3311,\n      \"quantity_invoiced\": 500,\n      \"unit_price\": 22.5\n    },\n    {\n      \"financial_line_id\": 74,\n      \"quantity_invoiced\": 1,\n      \"unit_price\": 610\n    }\n  ],\n  \"unmatched_lines\": [\n    {\n      \"description\": \"Fuel surcharge\",\n      \"line_total\": 45,\n      \"ignored\": true\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-invoices/{purchaseInvoice}/ocr-apply","host":["{{baseUrl}}"],"path":["api","purchase-invoices",":purchaseInvoice","ocr-apply"],"variable":[{"key":"purchaseInvoice","value":"123","description":"Purchase invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"approval_status\": \"pending_approval\"\n  },\n  \"message\": \"Invoice lines updated from OCR extraction.\"\n}"}]}]},{"name":"Landed Cost Invoice OCR","item":[{"name":"List Extractions (Inbox)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr"]},"description":"List landed cost invoice OCR extractions for the inbox queue. Requires Bearer token. Returns a paginated `LengthAwarePaginator` of landed cost invoice OCR extraction object items. All filters are optional. Useful for the OCR Inbox page that surfaces freight/customs/brokerage/insurance invoices awaiting review.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 18,\n      \"status\": \"pending_review\",\n      \"file_url\": \"https://sku2.test/api/landed-cost-invoices/ocr/18/pdf\",\n      \"file_name\": \"DHL-Invoice-INV-44219.pdf\",\n      \"page_count\": 2,\n      \"header\": {\n        \"vendor_name\": {\n          \"value\": \"DHL Express\",\n          \"confidence\": 0.94\n        },\n        \"invoice_number\": {\n          \"value\": \"INV-44219\",\n          \"confidence\": 0.91\n        },\n        \"invoice_date\": {\n          \"value\": \"2026-04-12\",\n          \"confidence\": 0.88\n        },\n        \"currency_code\": {\n          \"value\": \"USD\",\n          \"confidence\": 0.97\n        },\n        \"currency_rate\": 1,\n        \"total_amount\": {\n          \"value\": 1850.75,\n          \"confidence\": 0.93\n        },\n        \"matched_supplier_id\": 12,\n        \"matched_supplier_name\": \"DHL Express\"\n      },\n      \"is_matched_supplier\": true,\n      \"extracted_supplier_name\": \"DHL Express\",\n      \"lines\": [\n        {\n          \"description\": \"Freight Charges\",\n          \"quantity\": 1,\n          \"unit_price\": 1500,\n          \"line_total\": 1500,\n          \"matched_cost_category_id\": 4,\n          \"matched_cost_category_name\": \"Freight\",\n          \"match_tier\": \"exact_name\",\n          \"ignored\": false\n        },\n        {\n          \"description\": \"Fuel Surcharge\",\n          \"quantity\": 1,\n          \"unit_price\": 350.75,\n          \"line_total\": 350.75,\n          \"matched_cost_category_id\": 4,\n          \"matched_cost_category_name\": \"Freight\",\n          \"match_tier\": \"keyword\",\n          \"ignored\": false\n        }\n      ],\n      \"unmatched_line_count\": 0,\n      \"candidate_targets\": [\n        {\n          \"target_type\": \"inbound_shipment\",\n          \"target_id\": 142,\n          \"reference\": \"IS-00142\",\n          \"reason\": \"prebind\"\n        }\n      ],\n      \"working_state\": null,\n      \"prebind_target_type\": null,\n      \"prebind_target_id\": null,\n      \"azure_cost_usd\": 0.0125,\n      \"error_message\": null,\n      \"source\": \"email\",\n      \"source_email_from\": \"billing@dhl.com\",\n      \"source_email_subject\": \"DHL Invoice INV-44219\",\n      \"tracked_job_log_id\": 9221,\n      \"confirmed_at\": null,\n      \"confirmed_by_user_id\": null,\n      \"created_at\": \"2026-05-01T08:14:00.000000Z\",\n      \"updated_at\": \"2026-05-01T08:14:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 20,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 20\n}"}]},{"name":"Upload Landed Cost Invoice PDF","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/upload","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr","upload"]},"description":"Upload a landed cost invoice PDF to start OCR extraction. Requires Invoice OCR to be enabled in Settings → Invoice OCR (returns 422 if not enabled).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAsync — returns immediately with a `tracked_job_log_id` for progress tracking via the tracked job log endpoints. Poll `GET /landed-cost-invoices/ocr/{id}` until status is `pending_review` (or `failed` / `duplicate_detected`).\n\nResponse 201:\n```json\n{\n  \"data\": {\n    \"extraction_id\": 18,\n    \"tracked_job_log_id\": 9221,\n    \"status\": \"processing\"\n  },\n  \"message\": \"OCR processing started.\"\n}\n```\n\nResponse 422 (OCR disabled):\n```json\n{ \"message\": \"Landed Cost Invoice OCR is not enabled. Please configure it in Settings → Invoice OCR.\" }\n```","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"supplier_id","type":"text","value":""},{"key":"prebind_target_type","type":"text","value":""},{"key":"prebind_target_id","type":"text","value":""}]}}},{"name":"Get Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id"],"variable":[{"key":"landed_cost_extraction_id","value":"18","description":"ID of the LandedCostInvoiceOcrExtraction record."}]},"description":"Retrieve a landed cost invoice OCR extraction record. Eager-loads the matched supplier and any extraction→bill pivots created during apply. Returns extracted header data merged with matched supplier info, line items with per-line cost-category matches (6-tier match: mapped → exact_name → name_substring → keyword → fuzzy_name → fuzzy_mapped → unmatched), candidate targets (inbound shipments / POs / warehouse transfers that fit the supplier + ETA window), and inbound-email source metadata.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nExample 200 response:\n```json\n{\n  \"data\": {\n    \"id\": 18,\n    \"status\": \"pending_review\",\n    \"file_url\": \"https://sku2.test/api/landed-cost-invoices/ocr/18/pdf\",\n    \"file_name\": \"DHL-Invoice-INV-44219.pdf\",\n    \"page_count\": 2,\n    \"header\": {\n      \"vendor_name\": {\"value\": \"DHL Express\", \"confidence\": 0.94},\n      \"invoice_number\": {\"value\": \"INV-44219\", \"confidence\": 0.91},\n      \"invoice_date\": {\"value\": \"2026-04-12\", \"confidence\": 0.88},\n      \"currency_code\": {\"value\": \"USD\", \"confidence\": 0.97},\n      \"currency_rate\": 1.0,\n      \"total_amount\": {\"value\": 1850.75, \"confidence\": 0.93},\n      \"matched_supplier_id\": 12,\n      \"matched_supplier_name\": \"DHL Express\"\n    },\n    \"is_matched_supplier\": true,\n    \"extracted_supplier_name\": \"DHL Express\",\n    \"lines\": [\n      {\n        \"description\": \"Freight Charges\",\n        \"quantity\": 1,\n        \"unit_price\": 1500.00,\n        \"line_total\": 1500.00,\n        \"matched_cost_category_id\": 4,\n        \"matched_cost_category_name\": \"Freight\",\n        \"match_tier\": \"exact_name\",\n        \"ignored\": false\n      }\n    ],\n    \"unmatched_line_count\": 0,\n    \"candidate_targets\": [\n      {\n        \"target_type\": \"inbound_shipment\",\n        \"target_id\": 142,\n        \"reference\": \"IS-00142\",\n        \"eta\": \"2026-04-15\",\n        \"reason\": \"supplier_eta_close\"\n      },\n      {\n        \"target_type\": \"purchase_order\",\n        \"target_id\": 88,\n        \"reference\": \"PO-12345\",\n        \"reason\": \"supplier_match\"\n      }\n    ],\n    \"working_state\": null,\n    \"prebind_target_type\": null,\n    \"prebind_target_id\": null,\n    \"azure_cost_usd\": 0.0125,\n    \"error_message\": null,\n    \"source\": \"email\",\n    \"source_email_from\": \"billing@dhl.com\",\n    \"source_email_subject\": \"DHL Invoice INV-44219\",\n    \"tracked_job_log_id\": 9221,\n    \"supplier\": { \"id\": 12, \"name\": \"DHL Express\" },\n    \"extraction_bills\": [],\n    \"confirmed_at\": null,\n    \"confirmed_by_user_id\": null,\n    \"created_at\": \"2026-05-01T08:14:00.000000Z\",\n    \"updated_at\": \"2026-05-01T08:14:00.000000Z\"\n  }\n}\n```\n\n**Match tiers** (in order of confidence): `mapped` (Tier 0 — saved supplier mapping), `exact_name`, `name_substring`, `keyword`, `fuzzy_name`, `fuzzy_mapped`, `unmatched`.\n\n**Candidate target reasons**: `prebind` (from upload param), `supplier_eta_close` (open inbound shipment for matched supplier with ETA within window), `supplier_match` (any open PO / WT for matched supplier)."}},{"name":"Delete Extraction","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id"],"variable":[{"key":"landed_cost_extraction_id","value":"","description":"The landed cost extraction ID."}]},"description":"Soft-delete a landed cost invoice OCR extraction record (and its associated S3 PDF). Confirmed extractions cannot be deleted (returns 422).\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Response:** 204 No Content on success.\n\n**Response 422 (already confirmed):**\n```json\n{ \"message\": \"Confirmed extractions cannot be deleted.\" }\n```"}},{"name":"Stream Extraction PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}/pdf","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id","pdf"],"variable":[{"key":"landed_cost_extraction_id","value":"","description":"The landed cost extraction ID."}]},"description":"Stream the original landed cost invoice PDF through the backend (avoids CORS when fetching from S3). Returns Content-Type: application/pdf, `Content-Disposition: inline; filename=\"landed-cost-invoice.pdf\"`. Returns 404 if the underlying S3 object is missing. Cache-Control: private, max-age=300.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Apply Extraction (Create Bills)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}/apply","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id","apply"],"variable":[{"key":"landed_cost_extraction_id","value":"","description":"The landed cost extraction ID."}]},"description":"Accept the reviewed/edited extraction and create one or more `Bill` records — one per target entity (inbound shipment, purchase order, or warehouse transfer) — each with its own apportionment of the cost lines. Marks the extraction as `confirmed` and persists `Bill` rows linked via the polymorphic `bills.link_type` / `link_id` columns. Bridges supplier → vendor since Bills require `vendor_id`.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe extraction must be in `pending_review` or `duplicate_detected` status (a duplicate-detected extraction is allowed because the user may confirm it is not actually a duplicate and proceed). Returns 422 otherwise.\n\nWhen multiple targets are supplied, the invoice number is suffixed per target (`{invoice_number}-{type3}-{target_id}`) to avoid `bills.invoice_number` unique constraint violations.\n\n**Request body fields:**\n| Field | Type | Required | Notes |\n|-------|------|----------|-------|\n| supplier_id | integer | yes | Must exist in suppliers. |\n| invoice_number | string | yes | Max 255 chars. |\n| invoice_date | date | yes | |\n| currency_code | string | yes | ISO 4217 (size:3). |\n| currency_rate | numeric | yes | Min 0. Conversion rate to base currency. |\n| total_amount | numeric | yes | Total invoice amount. |\n| cost_lines | array | yes | At least 1 line. |\n| cost_lines[].description | string | yes | Max 500 chars. |\n| cost_lines[].quantity | numeric | yes | |\n| cost_lines[].unit_price | numeric | yes | |\n| cost_lines[].line_total | numeric | yes | |\n| cost_lines[].cost_category_id | integer | no (nullable) | Must exist in cost_categories. Null = unclassified line. |\n| cost_lines[].ignored | boolean | no | Skip persisting this line (audit-only). |\n| targets | array | yes | At least 1 target. Allocation shares MUST sum to 1.0 ±0.001. |\n| targets[].target_type | string | yes | One of: inbound_shipment, purchase_order, warehouse_transfer. |\n| targets[].target_id | integer | yes | ID of target entity. |\n| targets[].proration_strategy | string | yes | FinancialLineProrationStrategyEnum: revenue_based, cost_based, weight_based, volume_based, quantity_based, specific_line, manual. |\n| targets[].allocation_share | numeric | yes | 0–1. Share of the total this target receives. |\n| remember_mappings | boolean | no | When `true`, upserts `(supplier_id, normalized_description) → cost_category_id` mappings into `supplier_landed_cost_mappings` so future OCR imports auto-tag matching descriptions as cost lines (Tier 0 match). |\n\n**Response 201:**\n```json\n{\n  \"data\": {\n    \"id\": 18,\n    \"status\": \"confirmed\",\n    \"extraction_bills\": [\n      {\"id\": 33, \"bill_id\": 491, \"target_type\": \"inbound_shipment\", \"target_id\": 142, \"allocation_share\": 0.6},\n      {\"id\": 34, \"bill_id\": 492, \"target_type\": \"purchase_order\", \"target_id\": 88, \"allocation_share\": 0.4}\n    ],\n    \"confirmed_at\": \"2026-05-01T08:30:00.000000Z\",\n    \"confirmed_by_user_id\": 7\n  },\n  \"message\": \"Landed cost invoice applied.\"\n}\n```\n\n**Response 422 — wrong status:**\n```json\n{ \"message\": \"Only extractions pending review can be applied.\" }\n```\n\n**Response 422 — allocation shares do not sum to 1.0:**\n```json\n{ \"message\": \"Target allocation shares must sum to 1.0.\" }\n```","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 12,\n  \"invoice_number\": \"INV-44219\",\n  \"invoice_date\": \"2026-04-12\",\n  \"currency_code\": \"USD\",\n  \"currency_rate\": 1,\n  \"total_amount\": 1850.75,\n  \"cost_lines\": [\n    {\n      \"description\": \"Freight Charges\",\n      \"quantity\": 1,\n      \"unit_price\": 1500,\n      \"line_total\": 1500,\n      \"cost_category_id\": 4,\n      \"ignored\": false\n    },\n    {\n      \"description\": \"Fuel Surcharge\",\n      \"quantity\": 1,\n      \"unit_price\": 350.75,\n      \"line_total\": 350.75,\n      \"cost_category_id\": 4,\n      \"ignored\": false\n    }\n  ],\n  \"targets\": [\n    {\n      \"target_type\": \"inbound_shipment\",\n      \"target_id\": 142,\n      \"proration_strategy\": \"cost_based\",\n      \"allocation_share\": 0.6\n    },\n    {\n      \"target_type\": \"purchase_order\",\n      \"target_id\": 88,\n      \"proration_strategy\": \"quantity_based\",\n      \"allocation_share\": 0.4\n    }\n  ],\n  \"remember_mappings\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Re-scan Extraction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}/rescan","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id","rescan"],"variable":[{"key":"landed_cost_extraction_id","value":"","description":"The landed cost extraction ID."}]},"description":"Re-run Azure Document Intelligence OCR on the original PDF (e.g., after Azure model improvements, or to retry a failed extraction). Async — returns a `tracked_job_log_id` for progress tracking via the tracked job log endpoints.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRefuses (422) if the extraction is in `confirmed` status, or if the original `file_path` is missing.\n\n**Response 200:**\n```json\n{\n  \"data\": {\n    \"extraction_id\": 18,\n    \"tracked_job_log_id\": 9311,\n    \"status\": \"processing\"\n  },\n  \"message\": \"Re-scan started.\"\n}\n```\n\n**Response 422 (already confirmed):**\n```json\n{ \"message\": \"Confirmed extractions cannot be re-scanned.\" }\n```\n\n**Response 422 (file missing):**\n```json\n{ \"message\": \"Cannot re-scan — original file is no longer available.\" }\n```","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Save Draft (Working State)","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/landed-cost-invoices/ocr/{landed_cost_extraction_id}/draft","host":["{{baseUrl}}"],"path":["api","landed-cost-invoices","ocr",":landed_cost_extraction_id","draft"],"variable":[{"key":"landed_cost_extraction_id","value":"","description":"The landed cost extraction ID."}]},"description":"Persist in-progress edits to the review form so users can resume later (across browser refresh / device switch). The `working_state` body is an opaque object stored on the extraction — the frontend defines its shape (typically header_overrides, line_overrides, selected_targets, etc.). Returns the updated extraction.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n| Field | Type | Required | Notes |\n|-------|------|----------|-------|\n| working_state | object | yes | Opaque JSON; shape defined by the frontend review UI. |\n\nRefuses (422) if the extraction is in `confirmed` status.","body":{"mode":"raw","raw":"{\n  \"working_state\": {\n    \"header_overrides\": {\n      \"invoice_number\": \"INV-44219\",\n      \"invoice_date\": \"2026-04-12\"\n    },\n    \"line_overrides\": [\n      {\n        \"index\": 0,\n        \"cost_category_id\": 4\n      },\n      {\n        \"index\": 1,\n        \"cost_category_id\": 4\n      }\n    ],\n    \"selected_targets\": [\n      {\n        \"target_type\": \"inbound_shipment\",\n        \"target_id\": 142,\n        \"allocation_share\": 0.6\n      },\n      {\n        \"target_type\": \"purchase_order\",\n        \"target_id\": 88,\n        \"allocation_share\": 0.4\n      }\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Cost Category Keyword Aliases","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/cost-category-keyword-aliases","host":["{{baseUrl}}"],"path":["api","cost-category-keyword-aliases"]},"description":"List active cost-category keyword aliases used by the OCR cost-line matcher. Returns an object keyed by `cost_category_id` with arrays of keyword strings. Used by the Settings page that lets users curate which keywords (e.g., \"freight\", \"fuel surcharge\", \"customs\", \"duty\", \"clearance\") map to which CostCategory.\n\n**Required scope: `purchase-orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nKeywords feed Tier 4 (`keyword`) of the 6-tier match cascade in the OCR manager.\n\n**Response 200:**\n```json\n{\n  \"data\": {\n    \"4\": [\"freight\", \"shipping\", \"fuel surcharge\", \"airfreight\"],\n    \"5\": [\"customs\", \"duty\", \"clearance\", \"import duty\"],\n    \"6\": [\"insurance\", \"cargo insurance\"]\n  }\n}\n```"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/cost-category-keyword-aliases","host":["{{baseUrl}}"],"path":["api","cost-category-keyword-aliases"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"4\": [\n      \"freight\",\n      \"shipping\",\n      \"fuel surcharge\"\n    ],\n    \"5\": [\n      \"customs\",\n      \"duty\",\n      \"clearance\"\n    ],\n    \"6\": [\n      \"insurance\",\n      \"cargo insurance\"\n    ]\n  }\n}"}]},{"name":"Replace Cost Category Keyword Aliases","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/cost-category-keyword-aliases","host":["{{baseUrl}}"],"path":["api","cost-category-keyword-aliases"]},"description":"Replace the full set of keyword aliases for a single cost category. Idempotent — the repository diffs the supplied list against the existing rows: removes keywords not in the new list, inserts new ones. Default-flagged keywords (seeded by migration) are preserved if they remain in the new list, or removed if dropped. Keywords are normalized to lowercase + trimmed; duplicates are deduped server-side.\n\n**Required scope: `purchase-orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n| Field | Type | Required | Notes |\n|-------|------|----------|-------|\n| cost_category_id | integer | yes | Must exist in cost_categories. |\n| keywords | array | yes (present) | Each keyword: string, min 2 / max 100 chars. May be empty array to clear all keywords. |\n\n**Response 200:**\n```json\n{\n  \"data\": {\n    \"cost_category_id\": 4,\n    \"keywords\": [\"freight\", \"shipping\", \"fuel surcharge\", \"airfreight\"]\n  },\n  \"message\": \"Keyword aliases updated.\"\n}\n```\n\n**Response 422 (validation):**\n```json\n{\n  \"message\": \"The cost category id field is required.\",\n  \"errors\": {\n    \"cost_category_id\": [\"The cost category id field is required.\"],\n    \"keywords.0\": [\"Each keyword must be at least 2 characters.\"]\n  }\n}\n```","body":{"mode":"raw","raw":"{\n  \"cost_category_id\": 4,\n  \"keywords\": [\n    \"freight\",\n    \"shipping\",\n    \"fuel surcharge\",\n    \"airfreight\"\n  ]\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Document Inbox","item":[{"name":"List Inbox Documents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/document-inbox","host":["{{baseUrl}}"],"path":["api","document-inbox"]},"description":"Return a unified, paginated, descending-by-created_at list combining customer PO, supplier invoice, vendor credit, and landed cost invoice OCR extractions. Each item is normalized to the same shape so a single mixed-type list can be rendered. Vendor credit extractions that are attached to an existing vendor credit (vendor_credit_attachment_id set) are excluded — they belong to that credit's documents, not the inbox.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nExample item:\n```json\n{\n  \"id\": 42,\n  \"type\": \"supplier_invoice\",\n  \"status\": \"pending_review\",\n  \"source\": \"email\",\n  \"source_email_from\": \"Jane Doe <jane@tenant.com>\",\n  \"source_email_forwarded_from\": \"orders-usa@tecmate.com\",\n  \"source_email_subject\": \"Fwd: Invoice Number-0002020\",\n  \"customer_name\": null,\n  \"supplier_name\": \"TecMATE\",\n  \"document_type\": \"invoice\",\n  \"detection_signals\": [],\n  \"auto_routed\": false,\n  \"ocr_header\": {\n    \"doc_number\": {\"value\": \"0002020\", \"confidence\": 0.97},\n    \"total\": {\"value\": 37.06, \"confidence\": 0.97},\n    \"tax_amount\": {\"value\": 2.10, \"confidence\": 0.9},\n    \"currency_code\": {\"value\": \"USD\", \"confidence\": 0.99},\n    \"doc_date\": {\"value\": \"2026-07-17\", \"confidence\": 0.97},\n    \"po_number\": {\"value\": \"PO-0671\", \"confidence\": 0.95}\n  },\n  \"confirmed_record\": null,\n  \"error_message\": null,\n  \"created_at\": \"2026-07-17T22:28:48.000000Z\"\n}\n```\n\nSender fields:\n- `source_email_from` — the sender of the email that reached the intake address. For forwarded emails this is the forwarder, not the original contact.\n- `source_email_forwarded_from` — the original sender parsed out of a forwarded email's body/headers (null for direct sends and uploads). Prefer this as the document's real contact when present.\n\nOCR header summary (`ocr_header`):\n- A compact summary of what OCR extracted from the document, or null while the document is still processing (or when extraction failed before analysis).\n- Each field is `{value, confidence}`; `confidence` is 0–1 or null when the extraction pipeline did not score the field.\n- `doc_number` — the document's own number: invoice number (supplier_invoice, landed_cost_invoice), credit memo number (vendor_credit), or customer PO number (customer_po).\n- `total`, `tax_amount`, `currency_code` — extracted money fields.\n- `doc_date` — the document's own date (invoice date, credit date, or order date), distinct from `created_at` (when the document arrived).\n- `po_number` — for supplier invoices, the purchase order number referenced on the invoice (null for customer POs, where the PO number IS `doc_number`).\n\nClassification fields:\n- `document_type` — what the classifier decided the document is: `invoice` or `credit_memo`. Populated on supplier_invoice and vendor_credit items; always null for customer_po and landed_cost_invoice.\n- `detection_signals` — array of signal keys that drove the classification (e.g. `keyword:credit memo`, `doc_number:CM prefix`, `total:negative`). Null when no detection ran.\n- `auto_routed` — true when the document arrived in the supplier invoice pipeline but was automatically routed to the vendor credit queue by the classifier. Always false for customer_po, supplier_invoice, and landed_cost_invoice items.\n\nWhen status is 'confirmed', `confirmed_record` is populated with `{ id, type, number }` of the created sales order, purchase invoice, vendor credit (type: `vendor_credit`, number: the vendor_credit_number), or landed cost bill (type: `landed_cost_invoice`).\n\nLanded cost invoice items (`type: \"landed_cost_invoice\"`) expose `supplier_id`/`supplier_name` (the matched supplier, when detected) and always have `customer_id`, `customer_name`, `document_type`, and `detection_signals` as null with `auto_routed` false."}},{"name":"Get Pending Count","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/document-inbox/pending-count","host":["{{baseUrl}}"],"path":["api","document-inbox","pending-count"]},"description":"Lightweight count of all extractions currently in 'pending_review' status (sales + purchase + vendor credit + landed cost invoice). Vendor credit extractions that belong to an existing credit (vendor_credit_attachment_id set) are excluded from the count. Polled by the navigation drawer every 60 seconds to render the inbox badge.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nResponse:\n```json\n{ \"data\": { \"pending_review\": 7 } }\n```"}},{"name":"Retry Failed Extraction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/document-inbox/customer_po/{extraction_id}/retry","host":["{{baseUrl}}"],"path":["api","document-inbox","customer_po",":extraction_id","retry"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Re-dispatch OCR processing for a failed extraction. Path param `type` must be one of `customer_po`, `supplier_invoice`, `vendor_credit`, or `landed_cost_invoice` (regex-constrained); `id` is the matching extraction ID.\n\nValidations (return 422):\n- Extraction status must be 'failed'\n- Original file must still be present (file_path != null)\n- type must be customer_po, supplier_invoice, vendor_credit, or landed_cost_invoice\n\nOn success for customer_po / supplier_invoice: resets the extraction status to 'processing', clears error_message, dispatches the appropriate OCR job.\n\nFor vendor_credit: routes, which claims the extraction for processing, then re-runs the parse from the stored Azure `raw_response` synchronously when available (no second Azure charge), or dispatches the Scan Credit Memo job otherwise. Returns 422 with the manager's error message if the credit's documents are locked or a scan is already in progress.\n\nFor landed_cost_invoice: routes, which marks the extraction as processing and re-dispatches a background job. Returns 422 with the manager's error message on failure.\n\nResponse 200:\n```json\n{ \"message\": \"Retry queued.\" }\n```"}},{"name":"Bulk Delete Inbox Documents","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/document-inbox/bulk-destroy","host":["{{baseUrl}}"],"path":["api","document-inbox","bulk-destroy"]},"description":"Bulk-delete a polymorphic mix of OCR extractions from the unified Document Inbox. Powers the bulk-actions toolbar shown when rows are selected in the inbox UI.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nRequest body:\n- `items` (required, array, min:1) — list of extractions to delete\n- `items.*.type` (required, string, in:customer_po,supplier_invoice,vendor_credit,landed_cost_invoice) — which OCR extraction model the id belongs to\n- `items.*.id` (required, integer) — extraction ID\n\nBehavior:\n- Validates the entire payload with Laravel validation (returns 422 on shape errors)\n- Iterates each item; routes `customer_po` to the API::deleteExtraction`, `supplier_invoice` to the API::deleteExtraction`, `vendor_credit` to the API::deleteExtraction`, and `landed_cost_invoice` to the API::deleteExtraction` (deletes the S3 file and soft-deletes the extraction row)\n- All managers delete the S3 file (if any) and the DB record (vendor credit deletes skip the S3 delete when the file belongs to an attachment on an existing credit)\n- **Confirmed extractions are SKIPPED** (cannot be deleted — same constraint as the single-record DELETE endpoints)\n- Missing IDs are reported in `not_found` rather than failing the whole request — partial success is allowed\n\nResponse 200:\n```json\n{\n  \"deleted\": 2,\n  \"skipped\": [\n    { \"type\": \"customer_po\", \"id\": 91, \"reason\": \"confirmed\" }\n  ],\n  \"not_found\": [],\n  \"message\": \"2 document(s) deleted successfully. 1 skipped (confirmed).\"\n}\n```","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"type\": \"customer_po\",\n      \"id\": 42\n    },\n    {\n      \"type\": \"supplier_invoice\",\n      \"id\": 17\n    },\n    {\n      \"type\": \"vendor_credit\",\n      \"id\": 9\n    },\n    {\n      \"type\": \"landed_cost_invoice\",\n      \"id\": 5\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Adjacent Documents","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/document-inbox/customer_po/{extraction_id}/siblings","host":["{{baseUrl}}"],"path":["api","document-inbox","customer_po",":extraction_id","siblings"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Returns the previous and next document in the unified inbox relative to the given extraction. Powers the prev/next pager on the OCR review pages so the user can walk through the queue without bouncing back to the inbox list.\n\nPath params:\n- `type` (required) — one of `customer_po`, `supplier_invoice`, `vendor_credit`, or `landed_cost_invoice` (regex-constrained at the route level; unknown values return 404)\n- `id` (required, integer) — extraction ID of the currently-viewed document\n\nBehavior:\n- Walks `sales_order_ocr_extractions`, `purchase_invoice_ocr_extractions`, `vendor_credit_ocr_extractions`, and `landed_cost_invoice_ocr_extractions` together (vendor credit rows tied to an existing credit's attachment are excluded, matching the inbox listing)\n- Only `pending_review` extractions participate in the walk — confirmed/failed/processing rows have no Review button in the inbox, so the OCR review page wouldn't show anything actionable for them\n- The current item itself is ALWAYS included even if it's no longer `pending_review` (e.g. the user just confirmed it but hasn't navigated yet) — keeps `position`/`total` correct on the open page\n- Sort order matches the inbox listing: `created_at DESC, id DESC`\n- `prev`/`next` cross table boundaries — the next document may be a customer PO, vendor credit, or landed cost invoice even if the current one is a supplier invoice\n- `prev`/`next` are `null` at the boundaries of the list\n- Each sibling reference includes both `type` and `id` so the frontend can route to the correct OCR review page\n- `position` is 1-indexed (1 = newest); `null` if the current item is not found at all (e.g. just deleted)\n\nResponse 200:\n```json\n{\n  \"data\": {\n    \"prev\": { \"type\": \"supplier_invoice\", \"id\": 17 },\n    \"next\": { \"type\": \"vendor_credit\", \"id\": 9 },\n    \"position\": 2,\n    \"total\": 47\n  }\n}\n```\n\nResponse 404: route constraint blocks `type` values other than `customer_po`, `supplier_invoice`, `vendor_credit`, or `landed_cost_invoice`."}},{"name":"Reclassify Document Type","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/document-inbox/customer_po/{extraction_id}/reclassify","host":["{{baseUrl}}"],"path":["api","document-inbox","customer_po",":extraction_id","reclassify"],"variable":[{"key":"extraction_id","value":"","description":"The extraction ID."}]},"description":"Reclassify an inbox extraction as a different document type — the user-facing escape hatch when automatic type detection got it wrong. Copies the original file into the target pipeline, creates a new extraction there, and rejects the source extraction with a back-reference.\n\nPath params:\n- `type` (required) — current document type: one of `customer_po`, `supplier_invoice`, `vendor_credit`, or `landed_cost_invoice` (regex-constrained at the route level; unknown values return 404)\n- `id` (required, integer) — extraction ID\n\nRequest body:\n- `target_type` (required, string, in:customer_po,supplier_invoice,vendor_credit,landed_cost_invoice) — the type to reclassify the document as (returns 422 validation error otherwise)\n\nBehavior:\n- Source extraction must be in a reclassifiable status: `pending_review`, `duplicate_detected`, or `failed`\n- Three pairwise conversions are delegated to their existing dedicated flows (which can reuse the stored Azure `raw_response` to avoid a second OCR charge): customer_po → supplier_invoice, supplier_invoice → vendor_credit, and vendor_credit → supplier_invoice\n- All other source/target pairs use the generic flow: the original file is copied from the source pipeline's storage into the target pipeline's staging directory, a new extraction row is created in the target table, and the target's OCR job is dispatched. When the source already has a stored `raw_response` and the target is supplier_invoice or vendor_credit, the result is parsed synchronously instead of dispatching a job\n- The source extraction is marked `rejected` with error_message \"Reclassified as {label} (extraction #{id}).\" inside the same transaction\n\nResponse 200:\n```json\n{\n  \"message\": \"Document reclassified.\",\n  \"data\": { \"type\": \"supplier_invoice\", \"id\": 88 }\n}\n```\n`data.type`/`data.id` identify the NEW extraction so the frontend can route straight to the correct OCR review page.\n\nErrors (422, `{ \"error\": \"...\" }`):\n- \"The document is already classified as a {label}.\" — target_type equals the current type\n- \"Only extractions pending review can be reclassified.\" — source status not in pending_review/duplicate_detected/failed\n- \"Original OCR file is no longer available.\" — source file_path is empty\n- Standard Laravel validation error when `target_type` is missing or not one of the four allowed values\n\nResponse 404: route constraint blocks unknown `type` path values; unknown `id` returns 404 via findOrFail.","body":{"mode":"raw","raw":"{\n  \"target_type\": \"supplier_invoice\"\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Documents","item":[{"name":"List Documents for a Record","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/documents?type=purchase_order&id=900","host":["{{baseUrl}}"],"path":["api","documents"],"query":[{"key":"type","value":"purchase_order","description":"Required. The record type to list documents for. One of: purchase_order, purchase_invoice, bill.","disabled":true},{"key":"id","value":"900","description":"Required. The record's ID.","disabled":true}]},"description":"Lists the documents linked to a given business record (purchase order, purchase invoice, or bill). Because one document can be linked to several records, the same file appears here for every record it relates to.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/documents?type=purchase_order&id=900","host":["{{baseUrl}}"],"path":["api","documents"],"query":[{"key":"type","value":"purchase_order","description":"Required. The record type to list documents for. One of: purchase_order, purchase_invoice, bill.","disabled":true},{"key":"id","value":"900","description":"Required. The record's ID.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"file_name\": \"invoice-INV-5501.pdf\",\n      \"mime_type\": \"application/pdf\",\n      \"is_image\": false,\n      \"file_size\": 81234,\n      \"source\": \"ocr_supplier_invoice\",\n      \"file_url\": \"{{protocol}}{{domain}}/api/documents/42/file\",\n      \"linked_records\": [\n        {\n          \"type\": \"App\\\\Models\\\\PurchaseOrder\",\n          \"id\": 900\n        },\n        {\n          \"type\": \"App\\\\Models\\\\PurchaseInvoice\",\n          \"id\": 1201\n        }\n      ],\n      \"created_at\": \"2026-07-18T01:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Stream Document File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/documents/{documentId}/file","host":["{{baseUrl}}"],"path":["api","documents",":documentId","file"],"variable":[{"key":"documentId","value":"42","description":"Document ID"}]},"description":"Streams a document's file inline (PDF or image) through the backend. Content-Type reflects the stored file's type.\n\nAuthentication: Requires Bearer token."}}]},{"name":"Fulfillment Orders","item":[{"name":"List Fulfillment Orders for a Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfillment-orders"],"variable":[{"key":"salesOrder","value":"123","description":"Sales order ID"}]},"description":"Lists every FulfillmentOrder attached to a SalesOrder with eager-loaded lines + warehouse. Powers the Pending sub-tab in the application UI SO detail page.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Channel double-fulfillment coverage (F6):** each FO carries a transient boolean `has_channel_covered_units` — true when an still-open sales-channel (Shopify) fulfillment order may yet ship some of this FO's units. When present, every line carries `channel_covered`: `true` for a line the channel may still ship (\"awaiting channel\"), `false` for a line safe to dispatch natively (\"dispatchable\"). Both fields are stamped only by this list endpoint (not the single-FO detail endpoint) and omitted on FOs whose lines are not loaded. They drive the per-line awaiting-channel vs dispatchable badges and the submit-time guardrail.\n\nReturns 404 if the feature flag is off.\n\nResponse is a JSON:API-style resource collection (no pagination — typically a handful of FOs per SO).\n\n**Fulfillability:** each line carries `fulfillable_quantity` and `unfulfillable_quantity`, computed against the FulfillmentOrder's own (intent) warehouse — not the SalesOrderLine's warehouse_id. The warehouse block's `tracks_inventory` flag is false for externally-managed warehouses (Amazon FBA/AWD).\n\n**Line field `executed_quantity`** (per FO line): the physically-executed quantity — the sum of non-voided child SalesOrderFulfillmentLine quantities. Distinct from the accounting figure `quantity - remaining_quantity`; when the two disagree the line carries a masked shortfall (e.g. a bundle line grown to its component quantity with `remaining_quantity = 0` though fewer component units actually shipped).\n\n**`provider_order_link`** (object|null): INTERNAL cross-link to this FO's registered shipping-provider order detail page inside SKU — `{ link_reference, link_type_label, link_id, link_route }`. Distinct from the EXTERNAL `provider_order_url`. Populated for providers with an in-app per-order page (ShipStation, ShipHero, Starshipit, Trackstar, VeraCore, Shipfusion); `null` for providers with no detail page (ShipMyOrders), for pre-submit FOs, and for FBA/Manual FOs with no provider order. `link_route` is a application UI path, e.g. `/integrations/shipstation/4/orders/92532`.\n\n**Line field `sales_order_fulfillment_lines`** (per FO line): the child SalesOrderFulfillmentLine (execution) records for this FOL — a debug aid so support can trace SOL → FOL → SOFL on any line. Each entry is `{ id, sales_order_fulfillment_id, voided }`; `voided` reflects the parent SalesOrderFulfillment's `voided_at` (a voided SOFL can pin its FOL at quantity 0). Empty array until the FO is submitted into a carrier shipment. Example populated value: `[{ \"id\": 1194390, \"sales_order_fulfillment_id\": 685484, \"voided\": false }]`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","fulfillment-orders"],"variable":[{"key":"salesOrder","value":"123","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 451,\n      \"sales_order_id\": 123,\n      \"warehouse_id\": 7,\n      \"status\": \"open\",\n      \"request_status\": \"unsubmitted\",\n      \"external_id\": null,\n      \"external_type\": null,\n      \"integration_instance_id\": null,\n      \"effective_fulfillment_provider\": \"manual\",\n      \"effective_integration_instance_name\": null,\n      \"provider_order_link\": null,\n      \"submitted_at\": null,\n      \"accepted_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"rejection_reason\": null,\n      \"created_at\": \"2026-05-26T10:15:00+00:00\",\n      \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n      \"has_channel_covered_units\": true,\n      \"sales_channel_fulfillment_link\": {\n        \"channel\": \"shopify\",\n        \"fulfillment\": null,\n        \"fulfillment_orders\": [\n          {\n            \"link_id\": 8001,\n            \"link_reference\": \"#8593402003694\",\n            \"link_type_label\": \"Shopify Fulfillment Order\",\n            \"link_route\": \"/integrations/shopify/fulfillment-orders/8001?filter[integration_instance_ids]=2\",\n            \"status\": \"open\",\n            \"status_label\": \"Open\",\n            \"tracking_company\": null,\n            \"tracking_number\": null,\n            \"tracking_url\": null,\n            \"items\": [\n              {\n                \"sku\": \"RCF5OZ\",\n                \"name\": \"Bellwether Farms Creme Fraiche 5 oz\",\n                \"quantity\": 1\n              }\n            ],\n            \"item_match\": {\n              \"matches\": true,\n              \"lines\": [\n                {\n                  \"sku\": \"RCF5OZ\",\n                  \"name\": \"Bellwether Farms Creme Fraiche 5 oz\",\n                  \"our_qty\": 1,\n                  \"channel_qty\": 1,\n                  \"state\": \"ok\"\n                }\n              ]\n            }\n          }\n        ]\n      },\n      \"lines\": [\n        {\n          \"id\": 901,\n          \"fulfillment_order_id\": 451,\n          \"sales_order_line_id\": 55347,\n          \"quantity\": 3,\n          \"remaining_quantity\": 3,\n          \"fulfillable_quantity\": 3,\n          \"unfulfillable_quantity\": 0,\n          \"executed_quantity\": 0,\n          \"sales_order_fulfillment_lines\": [],\n          \"lot_allocation\": null,\n          \"channel_covered\": true,\n          \"sku\": \"WIDGET-01\",\n          \"name\": \"Blue Widget\",\n          \"product_id\": 88,\n          \"warehouse_id\": 7,\n          \"created_at\": \"2026-05-26T10:15:00+00:00\",\n          \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n        }\n      ],\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"standard\",\n        \"tracks_inventory\": true\n      }\n    },\n    {\n      \"id\": 452,\n      \"sales_order_id\": 123,\n      \"warehouse_id\": 9,\n      \"status\": \"open\",\n      \"request_status\": \"submitted\",\n      \"external_id\": \"shipfusion-93214\",\n      \"external_type\": \"shipfusion\",\n      \"integration_instance_id\": 4,\n      \"effective_fulfillment_provider\": \"shipfusion\",\n      \"effective_integration_instance_name\": \"Shipfusion — Atlanta\",\n      \"provider_order_link\": {\n        \"link_reference\": \"ORD-100245\",\n        \"link_type_label\": \"Shipfusion Order\",\n        \"link_id\": 101,\n        \"link_route\": \"/integrations/shipfusion/4/orders/101\"\n      },\n      \"submitted_at\": \"2026-05-26T09:45:00+00:00\",\n      \"accepted_at\": \"2026-05-26T09:46:00+00:00\",\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"rejection_reason\": null,\n      \"created_at\": \"2026-05-26T09:40:00+00:00\",\n      \"updated_at\": \"2026-05-26T09:46:00+00:00\",\n      \"has_channel_covered_units\": false,\n      \"lines\": [\n        {\n          \"id\": 905,\n          \"fulfillment_order_id\": 452,\n          \"sales_order_line_id\": 55349,\n          \"quantity\": 4,\n          \"remaining_quantity\": 4,\n          \"fulfillable_quantity\": 4,\n          \"unfulfillable_quantity\": 0,\n          \"executed_quantity\": 0,\n          \"sales_order_fulfillment_lines\": [],\n          \"lot_allocation\": null,\n          \"channel_covered\": false,\n          \"sku\": \"FBA-SKU\",\n          \"name\": \"FBA Item\",\n          \"product_id\": 90,\n          \"warehouse_id\": 9,\n          \"created_at\": \"2026-05-26T09:40:00+00:00\",\n          \"updated_at\": \"2026-05-26T09:46:00+00:00\"\n        }\n      ],\n      \"warehouse\": {\n        \"id\": 9,\n        \"name\": \"3PL Atlanta\",\n        \"type\": \"3pl\",\n        \"tracks_inventory\": true\n      }\n    }\n  ]\n}"}]},{"name":"Get Fulfillment Order Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Returns a single FulfillmentOrder with its lines and warehouse eager-loaded. Each line exposes its `quantity` (the original budget) and `remaining_quantity` (the over-fulfilment backstop — units still available to consume via a SalesOrderFulfillmentLine).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 404 if the feature flag is off or the FO does not exist.\n\n**Fulfillability:** each line carries `fulfillable_quantity` and `unfulfillable_quantity`, computed against the FulfillmentOrder's own (intent) warehouse — not the SalesOrderLine's warehouse_id. The warehouse block's `tracks_inventory` flag is false for externally-managed warehouses (Amazon FBA/AWD).\n\n**Line field `executed_quantity`** (per FO line): the physically-executed quantity — the sum of non-voided child SalesOrderFulfillmentLine quantities. Distinct from the accounting figure `quantity - remaining_quantity`; when the two disagree the line carries a masked shortfall (e.g. a bundle line grown to its component quantity with `remaining_quantity = 0` though fewer component units actually shipped).\n\n**`provider_order_link`** (object|null): INTERNAL cross-link to this FO's registered shipping-provider order detail page inside SKU — `{ link_reference, link_type_label, link_id, link_route }`. Distinct from the EXTERNAL `provider_order_url`. Populated for providers with an in-app per-order page (ShipStation, ShipHero, Starshipit, Trackstar, VeraCore, Shipfusion); `null` for providers with no detail page (ShipMyOrders), for pre-submit FOs, and for FBA/Manual FOs with no provider order. `link_route` is a application UI path, e.g. `/integrations/shipstation/4/orders/92532`.\n\n**Line field `sales_order_fulfillment_lines`** (per FO line): the child SalesOrderFulfillmentLine (execution) records for this FOL — a debug aid so support can trace SOL → FOL → SOFL on any line. Each entry is `{ id, sales_order_fulfillment_id, voided }`; `voided` reflects the parent SalesOrderFulfillment's `voided_at` (a voided SOFL can pin its FOL at quantity 0). Empty array until the FO is submitted into a carrier shipment. Example populated value: `[{ \"id\": 1194390, \"sales_order_fulfillment_id\": 685484, \"voided\": false }]`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"accepted\",\n    \"external_id\": \"92532\",\n    \"external_type\": \"shipstation_order\",\n    \"integration_instance_id\": 4,\n    \"effective_fulfillment_provider\": \"shipstation\",\n    \"effective_integration_instance_name\": \"ShipStation\",\n    \"provider_order_link\": {\n      \"link_reference\": \"O260613JZ3ECM.1\",\n      \"link_type_label\": \"ShipStation Order\",\n      \"link_id\": 92532,\n      \"link_route\": \"/integrations/shipstation/4/orders/92532\"\n    },\n    \"submitted_at\": \"2026-06-13T14:22:05.000000Z\",\n    \"accepted_at\": \"2026-06-13T14:22:09.000000Z\",\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"fulfillable_quantity\": 3,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-01\",\n        \"name\": \"Blue Widget\",\n        \"product_id\": 88,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      },\n      {\n        \"id\": 902,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55348,\n        \"quantity\": 2,\n        \"remaining_quantity\": 1,\n        \"fulfillable_quantity\": 1,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-02\",\n        \"name\": \"Red Widget\",\n        \"product_id\": 89,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:32:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"tracks_inventory\": true\n    }\n  }\n}"}]},{"name":"List Active Fulfillment Orders (Dispatch Feed, capped)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","fulfillment-orders"]},"description":"Cross-order **dispatch board** feed: every ACTIVE fulfillment order across all sales orders (excludes `closed` and `cancelled`), with `salesOrder` (for `sales_order_number`), `warehouse`, and `lines` eager-loaded. The frontend groups these into Kanban columns by `request_status` / `status` (Awaiting dispatch → Submitting → Submitted/Accepted → In progress → Needs attention).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Lazy-load per lifecycle:** pass `lifecycle` (manual|pickup|push|pull|channel) to load just that tab's lifecycle; the cap (most recent 500) then applies per lifecycle. Omit for all lifecycles. Pickup is request-status-driven (awaiting_pickup / picked_up) — an FO with a pickup fulfillment but no pickup method still lands under pickup, not its warehouse carrier. Use **Dispatch Board — Lifecycle Counts** for the tab badges.\n\nAuthenticate with a Personal Access Token.\n\n**Card detail fields:** each FO also returns sales_order_date, customer_name, sales_channel_name, and total_quantity (sum of line quantities). packing_slip_printed_at is included too (null until printed)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","fulfillment-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 451,\n      \"sales_order_id\": 123,\n      \"sales_order_number\": \"SO-0042\",\n      \"sales_order_date\": \"2026-06-15T00:00:00+00:00\",\n      \"customer_name\": \"Acme Retail Co.\",\n      \"customer_id\": 281384,\n      \"sales_channel_name\": \"Shopify\",\n      \"integration_name\": \"Curvy AU\",\n      \"total_quantity\": 5,\n      \"packing_slip_printed_at\": \"2026-06-16T14:32:10+00:00\",\n      \"warehouse_id\": 7,\n      \"status\": \"open\",\n      \"request_status\": \"unsubmitted\",\n      \"is_stuck_submitting\": false,\n      \"is_pickup\": false,\n      \"external_id\": null,\n      \"external_type\": null,\n      \"integration_instance_id\": null,\n      \"requested_shipping_method_id\": null,\n      \"requested_shipping_method\": null,\n      \"requested_ship_date\": null,\n      \"requested_metadata\": null,\n      \"submitted_at\": null,\n      \"accepted_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"rejection_reason\": null,\n      \"created_at\": \"2026-05-31T10:15:00+00:00\",\n      \"updated_at\": \"2026-05-31T10:15:00+00:00\",\n      \"lines\": [\n        {\n          \"id\": 901,\n          \"fulfillment_order_id\": 451,\n          \"sales_order_line_id\": 55347,\n          \"quantity\": 5,\n          \"remaining_quantity\": 5\n        }\n      ],\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Default Warehouse\",\n        \"type\": \"direct\",\n        \"order_fulfillment\": \"starshipit\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    },\n    {\n      \"id\": 452,\n      \"sales_order_id\": 124,\n      \"sales_order_number\": \"SO-0043\",\n      \"sales_order_date\": \"2026-06-15T00:00:00+00:00\",\n      \"customer_name\": \"Acme Retail Co.\",\n      \"customer_id\": 281384,\n      \"sales_channel_name\": \"Shopify\",\n      \"integration_name\": \"Curvy AU\",\n      \"total_quantity\": 5,\n      \"packing_slip_printed_at\": \"2026-06-16T14:32:10+00:00\",\n      \"warehouse_id\": 9,\n      \"status\": \"open\",\n      \"request_status\": \"rejected\",\n      \"is_stuck_submitting\": false,\n      \"is_pickup\": false,\n      \"rejection_reason\": \"Invalid postal code for service\",\n      \"created_at\": \"2026-05-31T10:20:00+00:00\",\n      \"updated_at\": \"2026-05-31T10:21:00+00:00\",\n      \"lines\": [\n        {\n          \"id\": 902,\n          \"fulfillment_order_id\": 452,\n          \"sales_order_line_id\": 55400,\n          \"quantity\": 4,\n          \"remaining_quantity\": 4\n        }\n      ],\n      \"warehouse\": {\n        \"id\": 9,\n        \"name\": \"West Coast WH\",\n        \"type\": \"direct\",\n        \"order_fulfillment\": \"starshipit\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    }\n  ]\n}"}]},{"name":"Create Fulfillment Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","fulfillment-orders"]},"description":"Creates a new FulfillmentOrder + its line budgets in a single transaction. Each line's `remaining_quantity` is initialized to `quantity`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Overfulfilment guard.** For every line, the manager row-locks the parent SalesOrderLine and validates that `SUM(quantity)` across all non-cancelled FOs for that SOL + the new requested quantity does not exceed `SalesOrderLine.quantity`. Violations return 422.\n\n**Request body fields:**\n- `sales_order_id` (required, integer, must exist) — parent SO.\n- `warehouse_id` (required, integer, must exist) — the warehouse this FO will be routed to. Cannot be changed once the FO leaves Open/Unsubmitted (see Move endpoint).\n- `lines` (required, array, min 1) — one entry per SOL being budgeted from this warehouse.\n- `lines.*.sales_order_line_id` (required, integer, must exist) — SOL ID.\n- `lines.*.quantity` (required, integer, min 1) — units to budget for this SOL from this warehouse.\n- `external_id` (nullable, string, max 128) — external provider's FO/shipment ID once submitted.\n- `external_type` (nullable, string, max 64) — provider type discriminator (e.g. \"shipfusion\", \"3pl\").\n- `integration_instance_id` (nullable, integer, must exist) — integration instance for the provider.\n\nReturns 201 with the eager-loaded FO + lines + warehouse on success, 422 on overfulfilment, 404 if the feature flag is off.","body":{"mode":"raw","raw":"{\n  \"sales_order_id\": 123,\n  \"warehouse_id\": 7,\n  \"lines\": [\n    {\n      \"sales_order_line_id\": 55347,\n      \"quantity\": 3\n    },\n    {\n      \"sales_order_line_id\": 55348,\n      \"quantity\": 2\n    }\n  ],\n  \"external_id\": null,\n  \"external_type\": null,\n  \"integration_instance_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","fulfillment-orders"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Preview Fulfillment Order Move (Coverage)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/move-preview?warehouse_id=9","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","move-preview"],"query":[{"key":"warehouse_id","value":"9","description":"Prospective destination warehouse (required, must exist).","disabled":true}],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Read-only coverage check for a prospective whole-FO move. Reports, per line that would move, whether the target warehouse can ship it from on-hand stock or would backorder it — so the UI can warn before committing. Mutates nothing.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse this to drive the move dialog's warning, then call `PATCH .../move` with `acknowledge_backorder: true` to commit.\n\n**Query params:**\n- `warehouse_id` (required, integer, must exist) — the prospective destination.\n\n**Per-line `outcome` values:** `covered` (ships in full), `partial` (some ships, the rest backorders), `backorder` (whole line backorders), `blemished_shortfall` (blemished line short on stock — can't backorder)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/move-preview?warehouse_id=9","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","move-preview"],"query":[{"key":"warehouse_id","value":"9","description":"Prospective destination warehouse (required, must exist).","disabled":true}],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouse_id\": 9,\n    \"warehouse_name\": \"3PL Atlanta\",\n    \"tracks_inventory\": true,\n    \"lines\": [\n      {\n        \"sales_order_line_id\": 55347,\n        \"fulfillment_order_line_id\": 901,\n        \"product_id\": 1088,\n        \"sku\": \"SHAVE-FIG\",\n        \"product_name\": \"Shave Soap Bar - Mediterranean Fig\",\n        \"requested_quantity\": 3,\n        \"coverable_quantity\": 1,\n        \"backorder_quantity\": 2,\n        \"is_blemished\": false,\n        \"outcome\": \"partial\"\n      }\n    ],\n    \"moving_line_count\": 1,\n    \"shortfall_line_count\": 1,\n    \"has_shortfall\": true,\n    \"has_blemished_shortfall\": false,\n    \"will_empty_fo\": false\n  }\n}"}]},{"name":"Move Fulfillment Order to Different Warehouse","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/move","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","move"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Pre-submit warehouse re-route. Relocates the WHOLE fulfillment order to a new warehouse: every line on the FO has its sales-order-line warehouse moved and its committed stock re-allocated at the target, and the FO itself is re-pointed there (the shipping provider follows the warehouse). It is the FO-level equivalent of moving each line individually. To move a single line instead, use the per-line move on the sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Mutability gate.** Allowed ONLY when the FO is `status=open` AND `request_status=unsubmitted`. Once the FO is handed to a provider (anything beyond unsubmitted) the warehouse decision is frozen — returns 409.\n\n**Backorder, warn-first.** A target short on stock does NOT block the move: the shortfall backorders (Planned) and is evicted off the FO so it holds only shippable lines (a wholly-uncovered FO is deleted). Because that quietly backorders, an un-acknowledged move that would backorder returns **409 with `requires_acknowledgement: true` and a `coverage` object** instead of committing — call `GET .../move-preview` (or read that coverage) to warn the user, then resend with `acknowledge_backorder: true`. Blemished products can't backorder; their shortfall is flagged as `blemished_shortfall` in the coverage.\n\n**Body fields:**\n- `warehouse_id` (required, integer, must exist) — new destination warehouse.\n- `acknowledge_backorder` (optional, boolean, default false) — set true to proceed when the move would backorder one or more lines.\n- `reason` (optional, string, max 1000) — free-text note for the audit trail.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 9,\n  \"acknowledge_backorder\": false,\n  \"reason\": \"Out of stock at original location\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/move","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","move"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 9,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:18:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 9,\n      \"name\": \"3PL Atlanta\",\n      \"type\": \"3pl\"\n    }\n  }\n}"}]},{"name":"Submit Fulfillment Order to Provider","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/submit","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","submit"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Transitions `request_status` from `unsubmitted` → `submitting` and stamps `submitted_at` to the moment of hand-off (NOT when the carrier confirms — see Stage 2 for the carrier-callback flow that flips `submitting` → `submitted`/`accepted`).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Mutability gate.** Allowed ONLY when `status=open` AND `request_status=unsubmitted`. Violations return 409.\n\n**Request body (all fields optional).** Submission acts on the WHOLE FO — there are no per-line quantities (split the FO first to dispatch part of it).\n\n- `acknowledge_open_channel_fulfillment` (boolean, default false) — double-fulfillment guardrail (F4a). When an still-open sales-channel (Shopify) fulfillment order may yet ship some of this FO's units, an omitted/false submit is refused with **409** carrying `requires_acknowledgement: true` and a `coverage` preview. Resubmit with this `true` to dispatch natively anyway.\n- `requested_integration_instance_id` (integer|null) — per-FO shipping-provider override; must be a SHIPPING_PROVIDER instance.\n- `requested_fulfillment_type` (string|null, only `manual`) — force Manual dispatch (no integration instance).\n- `requested_shipping_method_id` (integer|null) / `requested_shipping_method` (string|null) — requested carrier service.\n- `requested_ship_date` (date|null), `requested_metadata` (object|null) — optional ship intent bridged onto the SalesOrderFulfillment (`notes`, `fulfillment_sequence`, `signature_required`, `veracore_*`, `isInsured`, `instructionsForWarehouse`).\n- `lot_allocations` (array|null) — per-line FEFO override for lot-tracked lines: `[{ sales_order_line_id, lots: [{ fifo_layer_id, quantity }] }]`. Re-validated at dispatch; stale picks fall back to FEFO. Omit for automatic FEFO/FIFO.\n\nSet `override_partial_dispatch` to true to dispatch a sales order that is only partially fulfillable even when partial dispatch is disabled in fulfillment settings. When it is disabled and the order is not fully fulfillable, the request is refused with 409 and a body `code` of `partial_dispatch_disabled`.","body":{"mode":"raw","raw":"{\n  \"acknowledge_open_channel_fulfillment\": false,\n  \"override_partial_dispatch\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/submit","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","submit"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"submitting\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"effective_fulfillment_provider\": \"manual\",\n    \"effective_integration_instance_name\": null,\n    \"submitted_at\": \"2026-05-26T10:20:00+00:00\",\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:20:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Cancel Fulfillment Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/cancel","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","cancel"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Cancels the fulfillment order, releases its line budgets back to the parent sales-order lines (so a different fulfillment order can pick them up), and optionally records a reason. Sets `status=cancelled` + `cancelled_at`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Provider recall.** If the fulfillment order has already been submitted to a shipping provider, cancelling first attempts to recall (cancel) it at the provider, then cancels it in SKU. Set `local_only=true` to skip the provider recall and cancel only in SKU — leaving any live provider order in place (use this when the provider can't or won't recall the order).\n\n**Mutability gate.** Rejected if the fulfillment order is already terminal (`status=closed`/`cancelled`) or is currently in-flight with the provider (`request_status=submitting`/`cancellation_requested`).\n\n**Body fields:**\n- `reason` (optional, string, max 1000) — stored for audit.\n- `local_only` (optional, boolean, default false) — cancel only in SKU without recalling the provider order.\n\n**Recall failure (409).** When a provider recall fails, the response carries `needs_local_only: true` so you can retry with `local_only=true`. `provider_unsupported` is `true` when the provider has no cancel capability at all (the order can never be recalled automatically), and `false` when the order may already have shipped.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Customer requested change of address\",\n  \"local_only\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/cancel","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","cancel"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"cancelled\",\n    \"request_status\": \"unsubmitted\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": \"2026-05-26T10:25:00+00:00\",\n    \"rejection_reason\": \"Customer requested change of address\",\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:25:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Mark Fulfillment Order Picked Up","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/mark-picked-up","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","mark-picked-up"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Records an in-person Click & Collect collection. Creates the execution `SalesOrderFulfillment` (status=`fulfilled`) directly from the awaiting-pickup FulfillmentOrder — driving the inventory deduction at create-time — and advances the FO `request_status` to `picked_up`. No SalesOrderFulfillment exists before this point; the awaiting-pickup state lives entirely on the FO.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Gate.** 422 unless the FO is a Click & Collect order (`is_pickup`) currently at `request_status=awaiting_pickup`. 422 with `shortfalls` if `inventory_allocations` don't cover the FO's line quantities.\n\n**Body fields:**\n- `picked_up_at` (nullable, date) — collection timestamp; defaults to now.\n- `note` (nullable, string, max 1000) — recorded as a sales-order pickup note.","body":{"mode":"raw","raw":"{\n  \"picked_up_at\": \"2026-06-24T03:14:00Z\",\n  \"note\": \"Collected at front desk\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/mark-picked-up","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","mark-picked-up"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 1234,\n    \"warehouse_id\": 2,\n    \"status\": \"closed\",\n    \"request_status\": \"picked_up\",\n    \"is_pickup\": true,\n    \"expected_pickup_at\": \"2026-06-25T00:00:00+00:00\",\n    \"marked_for_pickup_at\": \"2026-06-24T03:14:00+00:00\",\n    \"marked_for_pickup_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Operator\"\n    }\n  }\n}"}]},{"name":"Unmark Fulfillment Order Picked Up","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/unmark-picked-up","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","unmark-picked-up"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Reverses a Click & Collect collection. Voids the collected pickup `SalesOrderFulfillment` (reversing its inventory movements + allocations and restoring the FulfillmentOrderLine budget) and returns the FO `request_status` to `awaiting_pickup`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Gate.** 422 unless the FO `request_status` is currently `picked_up`."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/unmark-picked-up","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","unmark-picked-up"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 1234,\n    \"warehouse_id\": 2,\n    \"status\": \"open\",\n    \"request_status\": \"awaiting_pickup\",\n    \"is_pickup\": true,\n    \"expected_pickup_at\": \"2026-06-25T00:00:00+00:00\",\n    \"marked_for_pickup_at\": \"2026-06-24T03:14:00+00:00\",\n    \"marked_for_pickup_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Operator\"\n    }\n  }\n}"}]},{"name":"Split Fulfillment Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/split","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","split"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID (the proforma to split — must be open + unsubmitted)"}]},"description":"Manually carve an **unsubmitted (proforma)** FulfillmentOrder into a NEW open/unsubmitted FO sized to the supplied per-line quantities. The original FO keeps the remainder. This is pure FulfillmentOrderLine budget redistribution — **neither FO is submitted** as a result (split and submit are separate concerns). To dispatch part of an order, split it then submit/hold each piece.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Only valid while the FO is `open` + `unsubmitted`.** Allocations are SOL-linked, so no allocation moves on a split.\n\n**Request body**\n- `lines` (required, array, min 1): the quantities to carve into the new FO.\n  - `lines[].sales_order_line_id` (required, integer, exists) — a SOL present on this FO.\n  - `lines[].quantity` (required, integer, min 1) — must not exceed the FOL's `remaining_quantity`, and must not carve the FO's entire remaining budget (that would leave nothing behind — submit/fulfill the whole FO instead).\n\n**Responses**\n- `201` — the NEW carved FO (open/unsubmitted).\n- `422` — a quantity exceeds the FOL remaining budget, or validation failed.\n- `409` — the FO is not open+unsubmitted, or the request would carve the entire FO (nothing left to split).","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"sales_order_line_id\": 55347,\n      \"quantity\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/split","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","split"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID (the proforma to split — must be open + unsubmitted)"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 452,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"requested_shipping_method_id\": null,\n    \"requested_shipping_method\": null,\n    \"requested_ship_date\": null,\n    \"requested_metadata\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-30T10:20:00+00:00\",\n    \"updated_at\": \"2026-05-30T10:20:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 902,\n        \"fulfillment_order_id\": 452,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 2,\n        \"remaining_quantity\": 2,\n        \"created_at\": \"2026-05-30T10:20:00+00:00\",\n        \"updated_at\": \"2026-05-30T10:20:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Retry Fulfillment Order Submission","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/retry-submission","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","retry-submission"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Operator recovery action for a FO that is **stuck submitting** — i.e. `request_status=submitting` for longer than the stuck threshold (`config('fulfillment.stuck_submitting_threshold_minutes')`, default 15) without the provider confirming. Resets `request_status` back to `unsubmitted` and clears `submitted_at`, so the operator (or the dispatcher) can re-attempt the hand-off.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe FO detail/list payloads expose `is_stuck_submitting` (boolean) so the UI can surface the amber 'stuck dispatch' banner that drives this action.\n\n**Mutability gate.** Allowed ONLY when `request_status=submitting` AND the FO is not terminal (`status` not closed/cancelled). Any other state returns 409.\n\nNo request body."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/retry-submission","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","retry-submission"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:42:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Force-Fail Fulfillment Order Submission","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/force-fail-submission","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","force-fail-submission"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Operator recovery action for a FO that is **stuck submitting** when retrying is not appropriate (e.g. confirmed provider/carrier outage). Transitions `request_status` to `rejected` and records the supplied reason on `rejection_reason`. The FO drops out of the in-flight set so it can be cancelled or re-routed.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe FO detail/list payloads expose `is_stuck_submitting` (boolean) so the UI can surface the amber 'stuck dispatch' banner that drives this action.\n\n**Mutability gate.** Allowed ONLY when `request_status=submitting` AND the FO is not terminal (`status` not closed/cancelled). Any other state returns 409.\n\n**Body fields:**\n- `reason` (nullable, string, max 1000) — stored on `rejection_reason` for audit. Defaults to 'Force-failed by operator (stuck dispatch).' when omitted.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Carrier outage — manual force-fail\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/force-fail-submission","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","force-fail-submission"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"rejected\",\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"submitted_at\": \"2026-05-26T10:20:00+00:00\",\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": \"Carrier outage — manual force-fail\",\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:45:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\"\n    }\n  }\n}"}]},{"name":"Get Dispatch Board Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/board-counts","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","board-counts"]},"description":"Active-FO counts per dispatch-board lifecycle (+ `all`) for the board tab badges. Computed from the FULL active set (not the per-tab capped feed), so a badge reflects the true total even when its tab's column list is capped. Uses the same lifecycle classification as the board feed's `lifecycle` filter + the FO-table lifecycle filter, so the badge count and the loaded tab agree.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthenticate with a Personal Access Token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/board-counts","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","board-counts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"all\": 116,\n    \"manual\": 4,\n    \"pickup\": 7,\n    \"push\": 98,\n    \"pull\": 5,\n    \"channel\": 2\n  }\n}"}]},{"name":"List Merge Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/merge-candidates","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","merge-candidates"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Anchor FulfillmentOrder ID — the FO to find cross-order merge candidates for."}]},"description":"Returns sibling pre-dispatch fulfillment orders on OTHER sales orders that could dispatch together with the anchor as ONE provider order (cross-order merge). Powers the \"Mergeable orders found\" nudge on the sales order fulfillment tab.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Eligibility** — a candidate is included only if it (and the anchor):\n- Is `status=open` and `request_status` in {`unsubmitted`, `rejected`} (pre-dispatch).\n- Belongs to a sales order that is NOT cancelled (a cancelled order's FOs are recalled; a stale Open FO is never offered).\n- Is at the SAME warehouse, resolves to the SAME provider type + requested integration instance, and is NOT FBA-routed.\n- Ships to the SAME shipping-address signature (name + company + address1 + address2 + city + province + zip + country_code) as the anchor.\n- Is on a DIFFERENT sales order, and is either ungrouped or already in the anchor's merge group.\n\nIf the anchor is itself ineligible (not pre-dispatch, FBA, cancelled order, or no shipping address) an empty list is returned.\n\n**Response shape** — `data[]` is an array of `FulfillmentOrderMergeCandidateData`:\n- `fulfillment_order_id` (int)\n- `sales_order_id` (int)\n- `sales_order_number` (string)\n- `customer_name` (string | null)\n- `integration_instance_name` (string | null)\n- `integration_instance_id` (int | null)\n- `line_count` (int)\n- `total_quantity` (int)\n- `requested_shipping_method` (string | null)\n- `integration_matches_anchor` (bool) — `false` when the candidate is from a different sales channel; the UI warns before merging.\n- `already_in_group` (bool) — `true` when the candidate is already a member of the anchor's merge group.\n- `ship_by_date` (string | null) — UTC ISO 8601; the candidate order's ship-by deadline, when set.\n- `hold_until_date` (string | null) — UTC ISO 8601; the candidate order's hold-until (\"do not ship before\") date, when set.\n- `deliver_by_date` (string | null) — UTC ISO 8601; the candidate order's deliver-by deadline, when set.\n\n**Auth:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/merge-candidates","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","merge-candidates"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Anchor FulfillmentOrder ID — the FO to find cross-order merge candidates for."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fulfillment_order_id\": 452,\n      \"sales_order_id\": 124,\n      \"sales_order_number\": \"GML430901\",\n      \"customer_name\": \"Jane Doe\",\n      \"integration_instance_name\": \"Acme Shopify\",\n      \"integration_instance_id\": 3,\n      \"line_count\": 2,\n      \"total_quantity\": 5,\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"integration_matches_anchor\": true,\n      \"already_in_group\": false,\n      \"ship_by_date\": \"2026-07-01T00:00:00.000000Z\",\n      \"hold_until_date\": \"2026-06-28T00:00:00.000000Z\",\n      \"deliver_by_date\": \"2026-07-05T00:00:00.000000Z\"\n    },\n    {\n      \"fulfillment_order_id\": 453,\n      \"sales_order_id\": 125,\n      \"sales_order_number\": \"GML430902\",\n      \"customer_name\": \"Jane Doe\",\n      \"integration_instance_name\": \"Acme Amazon US\",\n      \"integration_instance_id\": 7,\n      \"line_count\": 1,\n      \"total_quantity\": 1,\n      \"requested_shipping_method\": null,\n      \"integration_matches_anchor\": false,\n      \"already_in_group\": false,\n      \"ship_by_date\": null,\n      \"hold_until_date\": null,\n      \"deliver_by_date\": null\n    }\n  ]\n}"}]},{"name":"List Post-Submission Merge Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/post-submission-merge-candidates","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","post-submission-merge-candidates"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Anchor FulfillmentOrder ID — the already-dispatched FO to find post-submission merge candidates for."}]},"description":"Returns sibling fulfillment orders on OTHER sales orders that this ALREADY-DISPATCHED fulfillment order could still be merged with at the shipping provider (post-submission cross-order merge). Same customer/address/warehouse/provider consensus as the pre-dispatch merge candidates, but for the window after auto-dispatch has already sent the orders to the provider.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Eligibility** — a candidate is included only if it (and the anchor):\n- Is `status=open` and `request_status` in {`submitted`, `accepted`, `acknowledged`} (handed to the provider, awaiting tracking).\n- Belongs to a sales order that is NOT cancelled.\n- Is at the SAME warehouse, resolves to the SAME provider type + requested integration instance, and is NOT FBA-routed.\n- Ships to the SAME shipping-address signature as the anchor, and is on a DIFFERENT sales order (ungrouped or already in the anchor's merge group).\n\nIf the anchor is itself ineligible (not in the post-submission window, FBA, cancelled order, or no shipping address) an empty list is returned.\n\n**Response shape** — `data[]` is an array of merge candidates. Same fields as the pre-dispatch merge candidates, plus a provider-side verdict:\n- `provider_eligibility` (object) — whether the candidate can still be cancelled/merged at its provider:\n  - `eligible` (bool) — `false` when the provider order has already shipped or been cancelled.\n  - `reason` (string | null) — human-facing explanation shown when ineligible.\n  - `requires_label_void` (bool) — `true` when a shipping label must be voided before the order becomes mutable again.\n\nThis is a conservative list-level read of each candidate's locally-synced provider order; the precise, live per-provider \"too far gone\" check runs immediately before the merge is executed."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/post-submission-merge-candidates","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","post-submission-merge-candidates"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Anchor FulfillmentOrder ID — the already-dispatched FO to find post-submission merge candidates for."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fulfillment_order_id\": 462,\n      \"sales_order_id\": 1055,\n      \"sales_order_number\": \"SO-1055\",\n      \"customer_name\": \"Acme Retail\",\n      \"integration_instance_name\": \"Shopify — Main Store\",\n      \"integration_instance_id\": 12,\n      \"line_count\": 2,\n      \"total_quantity\": 5,\n      \"requested_shipping_method\": \"Standard\",\n      \"integration_matches_anchor\": true,\n      \"already_in_group\": false,\n      \"ship_by_date\": \"2026-07-09T00:00:00.000000Z\",\n      \"hold_until_date\": null,\n      \"deliver_by_date\": null,\n      \"provider_eligibility\": {\n        \"eligible\": true,\n        \"reason\": null,\n        \"requires_label_void\": false\n      }\n    }\n  ]\n}"}]},{"name":"Preflight Post-Submission Merge","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-provider/preflight","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-provider","preflight"]},"description":"Returns the read-only PLAN for merging two or more already-dispatched fulfillment orders into one provider order (post-submission cross-order merge). No provider call and no data is changed — this is the plan the operator confirms before the merge runs.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**\n- `fulfillment_order_ids` (int[], required, min 2) — the already-dispatched fulfillment orders to merge.\n- `primary_fulfillment_order_id` (int, optional) — the order to keep as the master (it receives the others' lines). Defaults to the order with the most lines.\n\n**Response** — a plan object:\n- `primary_fulfillment_order_id` (int) — the master.\n- `provider` (string | null) — the resolved shipping provider.\n- `warehouse_id` (int | null).\n- `can_execute` (bool) — true only when there are no blockers and at least two eligible members (including the master).\n- `blockers` (string[]) — whole-plan problems (different warehouses, providers, or addresses) that no per-order exclusion can fix.\n- `members[]` — one per order: `fulfillment_order_id`, `sales_order_id`, `sales_order_number`, `role` (`master` | `absorbed`), `action` (`receive_lines` | `cancel`), `line_count`, `eligible` (bool), `reason` (string | null), `requires_label_void` (bool), `provider_order_reference` (string | null), `provider_status` (string | null).","body":{"mode":"raw","raw":"{\n  \"fulfillment_order_ids\": [\n    451,\n    462\n  ],\n  \"primary_fulfillment_order_id\": 451\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-provider/preflight","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-provider","preflight"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"primary_fulfillment_order_id\": 451,\n    \"provider\": \"shipstation\",\n    \"warehouse_id\": 7,\n    \"can_execute\": true,\n    \"blockers\": [],\n    \"members\": [\n      {\n        \"fulfillment_order_id\": 451,\n        \"sales_order_id\": 1042,\n        \"sales_order_number\": \"SO-1042\",\n        \"role\": \"master\",\n        \"action\": \"receive_lines\",\n        \"line_count\": 3,\n        \"eligible\": true,\n        \"reason\": null,\n        \"requires_label_void\": false,\n        \"provider_order_reference\": \"SO-1042\",\n        \"provider_status\": \"Awaiting Shipment\"\n      },\n      {\n        \"fulfillment_order_id\": 462,\n        \"sales_order_id\": 1055,\n        \"sales_order_number\": \"SO-1055\",\n        \"role\": \"absorbed\",\n        \"action\": \"cancel\",\n        \"line_count\": 2,\n        \"eligible\": true,\n        \"reason\": null,\n        \"requires_label_void\": false,\n        \"provider_order_reference\": \"SO-1055\",\n        \"provider_status\": \"Awaiting Shipment\"\n      }\n    ]\n  }\n}"}]},{"name":"Execute Post-Submission Merge","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-provider/execute","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-provider","execute"]},"description":"Runs a post-submission cross-order merge for already-dispatched fulfillment orders. The plan is re-validated first; if it can still run, a background job cancels the absorbed orders at the shipping provider, adds their items to the master order, and then records the merge in SKU (each sales order keeps its own tracking). Returns a job handle to track progress.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body**\n- `fulfillment_order_ids` (int[], required, min 2) — the orders to merge.\n- `primary_fulfillment_order_id` (int, required) — the order that survives as the master (it receives the others' items).\n- `acknowledge_label_voids` (bool, optional) — set true to confirm any labels that must be voided first.\n\n**Responses**\n- `202 Accepted` — `data.tracked_job_log_id` to poll/subscribe on.\n- `422` — the merge can't run; `blockers` lists why.","body":{"mode":"raw","raw":"{\n  \"fulfillment_order_ids\": [\n    451,\n    462\n  ],\n  \"primary_fulfillment_order_id\": 451,\n  \"acknowledge_label_voids\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-provider/execute","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-provider","execute"]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90321\n  },\n  \"message\": \"Merge started\"\n}"}]},{"name":"Merge Fulfillment Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/merge","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","merge"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Target FulfillmentOrder ID — the FO the source is folded INTO (kept)."}]},"description":"Fold a sibling fulfillment order (`source_fulfillment_order_id`) INTO the route FO (the target). The source's lines are merged into the target per sales order line, the emptied source FO is deleted, and the target is returned. One fulfillment order → one submission → one shipment.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Mutability gate.** Both FOs must be `status=open` AND `request_status` in {`unsubmitted`, `rejected`}, at the SAME warehouse, on the SAME sales order. Violations return 409 (not mutable) or 422 (different warehouse / different sales order / self-merge).\n\n**Body fields:**\n- `source_fulfillment_order_id` (required, integer, must exist) — the FO to merge in and remove.\n- `requested_shipping_method_id` (optional, integer, nullable) — resolved shipping method id (overwrites the target's).\n- `requested_shipping_method` (optional, string, nullable) — resolved shipping method label.\n- `requested_ship_date` (optional, date, nullable) — resolved requested ship date.\n- `requested_metadata` (optional, object, nullable) — resolved provider metadata; REPLACES the target's metadata wholesale, so send the complete merged object. Allowed keys: `notes`, `fulfillment_sequence`, `signature_required`, `veracore_packing_slip_comments`, `veracore_shipping_comments`, `veracore_third_party_type` (1–3), `veracore_third_party_account_number`, `isInsured`, `instructionsForWarehouse`.\n\nThe resolved-shipping fields are the CONFLICT RESOLUTION chosen in the merge dialog — omit them entirely to keep the target's existing shipping details.","body":{"mode":"raw","raw":"{\n  \"source_fulfillment_order_id\": 452,\n  \"requested_shipping_method\": \"UPS Ground\",\n  \"requested_metadata\": {\n    \"signature_required\": true,\n    \"notes\": \"Combined into a single shipment\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/merge","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","merge"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Target FulfillmentOrder ID — the FO the source is folded INTO (kept)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 9,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"requested_shipping_method_id\": null,\n    \"requested_shipping_method\": \"UPS Ground\",\n    \"requested_ship_date\": null,\n    \"requested_metadata\": {\n      \"signature_required\": true,\n      \"notes\": \"Combined into a single shipment\"\n    },\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:22:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 5,\n        \"remaining_quantity\": 5,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:22:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 9,\n      \"name\": \"3PL Atlanta\",\n      \"type\": \"3pl\",\n      \"order_fulfillment\": \"starshipit\",\n      \"supplier_id\": null,\n      \"supplier_name\": null\n    }\n  }\n}"}]},{"name":"Get Fulfillment Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","activity-log"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Paginated audit trail for a single fulfillment order — created, warehouse move, shipping-method change, submit, merge, cancel — newest first. The same events also roll up onto the parent sales order's Activity tab (`GET /api/v2/sales-orders/{salesOrder}/activity-log`).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Query params (all optional):**\n- `per_page` (integer, default 15)\n- `filter[search]` (string) — searches causer name / event / property changes\n- `filter[event]` (string) — exact event match (created, updated, deleted)\n- `filter[source]` (string) — matches `properties.source`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","activity-log"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88231,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"FulfillmentOrder\",\n      \"subject_id\": 451,\n      \"properties\": {\n        \"attributes\": {\n          \"requested_shipping_method_id\": 9,\n          \"requested_shipping_method\": \"UPS Ground\"\n        },\n        \"old\": {\n          \"requested_shipping_method_id\": 4,\n          \"requested_shipping_method\": \"USPS Priority\"\n        }\n      },\n      \"causer_name\": \"Kalvin Mizzi\",\n      \"created_at\": \"2026-06-02T10:22:00+00:00\"\n    },\n    {\n      \"id\": 88210,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"FulfillmentOrder\",\n      \"subject_id\": 451,\n      \"properties\": {\n        \"attributes\": {\n          \"sales_order_id\": 123,\n          \"warehouse_id\": 9,\n          \"status\": \"open\",\n          \"request_status\": \"unsubmitted\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-02T10:15:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"last_page\": 1,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Edit Fulfillment Order Shipping Details","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/shipping","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","shipping"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]},"description":"Edit the **requested** shipping params on a proforma fulfillment order before it is submitted — the shipping method, requested ship date, and provider-specific metadata (e.g. notes). These travel with the FO into the submission payload.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Mutability gate.** Allowed ONLY while the FO is `status=open` AND `request_status` is `unsubmitted` or `rejected` (i.e. not yet successfully sent). Once submitting/accepted the carrier owns the values, so edits return **409**.\n\n**Body fields (all optional — `sometimes`; only the keys present are written):**\n- `requested_shipping_method_id` (nullable, integer, must exist in `shipping_methods`) — the chosen shipping method.\n- `requested_shipping_method` (nullable, string, max 255) — free-text method label (used when no method id applies / provider-specific).\n- `requested_ship_date` (nullable, date) — requested dispatch date.\n- `requested_metadata` (nullable, object) — free-form, provider-varying values. Only the keys the active provider owns are written; on submission they are bridged onto the SalesOrderFulfillment metadata the carrier dispatchers read.\n- `requested_metadata.notes` (nullable, string, max 2000) — fulfillment notes for the provider.\n- `requested_metadata.signature_required` (nullable, boolean) — signature on delivery (Starshipit / ShipHero / ShipMyOrders / ShipFusion). Aliased to `isSignatureRequired` for ShipHero & ShipMyOrders when bridged onto the fulfillment.\n- `requested_metadata.veracore_packing_slip_comments` (nullable, string, max 500) — Veracore packing-slip comments.\n- `requested_metadata.veracore_shipping_comments` (nullable, string, max 500) — Veracore shipping comments.\n- `requested_metadata.veracore_third_party_type` (nullable, integer, in 1,2,3) — Veracore third-party billing type.\n- `requested_metadata.veracore_third_party_account_number` (nullable, string, max 100) — Veracore third-party account number.\n- `requested_metadata.isInsured` (nullable, boolean) — ShipMyOrders insured flag.\n- `requested_metadata.instructionsForWarehouse` (nullable, string, max 500) — ShipMyOrders warehouse instructions.\n- `requested_metadata.fulfillment_sequence` (nullable, integer, min 1) — backup override for the postfix pushed to the provider as the order number (`{sales_order_number}.{sequence}`). Omit/null to auto-assign the next sequence at submit. The current default is exposed on the fulfillment order object as `next_fulfillment_sequence`.\n- `requested_integration_instance_id` (nullable, integer, must exist in `integration_instances` AND be a SHIPPING_PROVIDER instance) — per-FO shipping-provider override; null = use the warehouse default.\n- `requested_fulfillment_type` (nullable, string, in: `manual`) — per-FO \"force Manual\" override.\n\n**Click & Collect (pickup) lock.** When the order's effective shipping method is a pickup method (`is_pickup`), it is collected in person and is never dispatched — so a `requested_integration_instance_id` (carrier) or `requested_fulfillment_type=manual` override is **rejected with 422**. The lock is keyed on the RESULTING method: passing a non-pickup `requested_shipping_method_id` in the SAME request releases the lock (the resource then reports `is_pickup=false`).\n\nReturns the updated fulfillment order object (which includes `next_fulfillment_sequence` and `is_pickup`).","body":{"mode":"raw","raw":"{\n  \"requested_shipping_method_id\": 12,\n  \"requested_shipping_method\": \"Starshipit Express\",\n  \"requested_ship_date\": \"2026-06-02\",\n  \"requested_metadata\": {\n    \"notes\": \"Leave at the side door.\",\n    \"signature_required\": true,\n    \"veracore_packing_slip_comments\": \"Fragile\",\n    \"veracore_shipping_comments\": \"\",\n    \"veracore_third_party_type\": 2,\n    \"veracore_third_party_account_number\": \"ACME-123\",\n    \"isInsured\": true,\n    \"instructionsForWarehouse\": \"Gift wrap\",\n    \"fulfillment_sequence\": 2\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/shipping","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","shipping"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"FulfillmentOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"sales_order_number\": \"SO-0123\",\n    \"warehouse_id\": 9,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"requested_shipping_method_id\": 12,\n    \"requested_shipping_method\": \"Starshipit Express\",\n    \"requested_ship_date\": \"2026-06-02T00:00:00+00:00\",\n    \"requested_metadata\": {\n      \"notes\": \"Leave at the side door.\"\n    },\n    \"next_fulfillment_sequence\": 1,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-31T18:40:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 9,\n      \"name\": \"Default Warehouse\",\n      \"type\": \"standard\",\n      \"order_fulfillment\": \"starshipit\",\n      \"supplier_id\": null,\n      \"supplier_name\": null\n    }\n  }\n}"}]},{"name":"Record Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/record-shipment","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","record-shipment"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]},"description":"Record a REAL shipment (one SalesOrderFulfillment) against this fulfillment order — the operator fallback for the intent/execution split. A fulfillment order is the provider's order; shipments come back as 1..N SalesOrderFulfillments over time.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody:\n- `lines` (optional array): per-line shipped quantities `{sales_order_line_id, quantity}`. OMIT to ship the full remaining_quantity of every line. Each quantity is clamped to the line's remaining_quantity.\n- `tracking_number` (optional), `carrier` (optional), `shipping_method` (optional).\n- `shipped_at` (optional date, Y-m-d): the provider's actual shipped date — becomes the SOF fulfilled_at / COGS accounting date (defaults to today if omitted).\n- `provider_shipment_id` (optional): the provider's shipment identifier — idempotent dedup (a re-recorded id never duplicates the SOF).\n\nSide effects: creates the SalesOrderFulfillment (+ inventory movements, COGS, fulfilled_quantity), decrements each line's remaining_quantity, and advances the FO lifecycle: Open → Closed (fully shipped). A partially-shipped FO stays `open` with `remaining_quantity` > 0 on its lines — the separate in_progress / incomplete partial-shipped statuses were retired in rung 3.\n\nReturns the FO with its updated lines + shipments. 422 if there is nothing left to ship or the report exceeds remaining quantity.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"sales_order_line_id\": 14,\n      \"quantity\": 1\n    }\n  ],\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"carrier\": \"UPS\",\n  \"shipping_method\": \"UPS Ground\",\n  \"shipped_at\": \"2026-06-03\",\n  \"provider_shipment_id\": \"SHP-7781\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/record-shipment","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","record-shipment"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"sales_order_id\": 1,\n    \"sales_order_number\": \"SO-0001\",\n    \"warehouse_id\": 1,\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"request_status\": \"submitted\",\n    \"provider_order_link\": null,\n    \"is_stuck_submitting\": false,\n    \"is_pickup\": false,\n    \"requested_shipping_method\": \"UPS Ground\",\n    \"requested_shipping_method_id\": 12,\n    \"requested_ship_date\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-06-02T20:43:00+00:00\",\n    \"updated_at\": \"2026-06-03T14:10:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 9,\n        \"fulfillment_order_id\": 6,\n        \"sales_order_line_id\": 14,\n        \"quantity\": 2,\n        \"remaining_quantity\": 1,\n        \"sku\": \"abc\",\n        \"name\": \"abc desc\",\n        \"product_id\": 3\n      }\n    ],\n    \"fulfillments\": [\n      {\n        \"id\": 21,\n        \"number\": \"SO-0001.1\",\n        \"status\": \"fulfilled\",\n        \"fulfillment_sequence\": 1\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Default Warehouse\",\n      \"type\": \"direct\",\n      \"order_fulfillment\": \"starshipit\",\n      \"supplier_id\": null,\n      \"supplier_name\": null\n    }\n  }\n}"}]},{"name":"Accept Fulfillment Order Discrepancy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/accept-discrepancy","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","accept-discrepancy"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]},"description":"Self-heal a shipping-provider ↔ fulfillment-order line discrepancy. Use this when the shipping provider marked the order shipped but one line's product cannot be fulfilled (no on-hand to deduct) — a permanent mismatch between what the provider shipped and what can actually leave the warehouse.\n\nAccepting records a real shipment (with the provider's tracking) for the lines that DID ship and parks the discrepant line so it is never deducted from inventory. The provider's order record is left untouched (it stays the source of truth for what the provider believes shipped), and the open discrepancy alert is resolved.\n\nBody:\n- `acknowledged` (required, must be true): explicit confirmation that the discrepant line will NOT be deducted from inventory. Any other value returns 422.\n\nSide effects: records the SalesOrderFulfillment (+ tracking, inventory movements, COGS) for the fulfillable lines, marks the discrepant line out-of-sync (parked), stamps who/when accepted, advances the fulfillment order lifecycle, and resolves the discrepancy alert.\n\nReturns the fulfillment order with `discrepancy_accepted_at` / `discrepancy_accepted_by` set. 422 if there is no shipped provider order, nothing discrepant to accept, or the shipment cannot be recorded.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"acknowledged\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/accept-discrepancy","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","accept-discrepancy"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"sales_order_id\": 1,\n    \"sales_order_number\": \"SO-0001\",\n    \"warehouse_id\": 1,\n    \"status\": \"closed\",\n    \"status_label\": \"Closed\",\n    \"request_status\": \"submitted\",\n    \"provider_order_link\": {\n      \"link_reference\": \"C636160.1\",\n      \"link_type_label\": \"Starshipit Order\",\n      \"link_id\": 4821,\n      \"link_route\": \"/v2/integrations/starshipit/orders/4821\"\n    },\n    \"discrepancy_accepted_at\": \"2026-07-21T13:40:00+00:00\",\n    \"discrepancy_accepted_by\": {\n      \"id\": 3,\n      \"name\": \"Warehouse Manager\"\n    },\n    \"is_pickup\": false,\n    \"requested_shipping_method\": \"Standard\",\n    \"requested_ship_date\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-07-20T09:12:00+00:00\",\n    \"updated_at\": \"2026-07-21T13:40:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 9,\n        \"fulfillment_order_id\": 6,\n        \"sales_order_line_id\": 14,\n        \"quantity\": 1,\n        \"remaining_quantity\": 0,\n        \"sku\": \"abc\",\n        \"name\": \"In-stock item\",\n        \"product_id\": 3\n      },\n      {\n        \"id\": 10,\n        \"fulfillment_order_id\": 6,\n        \"sales_order_line_id\": 15,\n        \"quantity\": 1,\n        \"remaining_quantity\": 1,\n        \"sku\": \"195093200861\",\n        \"name\": \"Mis-tagged item (parked)\",\n        \"product_id\": 7\n      }\n    ],\n    \"fulfillments\": [\n      {\n        \"id\": 21,\n        \"number\": \"SO-0001.1\",\n        \"status\": \"fulfilled\",\n        \"fulfillment_sequence\": 1\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Default Warehouse\",\n      \"type\": \"direct\",\n      \"order_fulfillment\": \"starshipit\",\n      \"supplier_id\": null,\n      \"supplier_name\": null\n    }\n  },\n  \"message\": \"Discrepancy accepted; tracking processed for the shipped lines.\"\n}"}]},{"name":"Reopen Fulfillment Order Discrepancy","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/reopen-discrepancy","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","reopen-discrepancy"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]},"description":"Reverse a prior discrepancy acceptance and re-open the discrepancy alert for a fulfillment order. This clears the accepted stamp (`discrepancy_accepted_at` / `discrepancy_accepted_by`) and re-fires the discrepancy alert so the mismatch is surfaced again.\n\nThis does NOT reverse an already-recorded shipment — the lines that shipped genuinely shipped; it only re-opens the discrepancy state so it can be reviewed or accepted again.\n\nReturns the fulfillment order with the acceptance cleared.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/reopen-discrepancy","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","reopen-discrepancy"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 6,\n    \"sales_order_id\": 1,\n    \"sales_order_number\": \"SO-0001\",\n    \"warehouse_id\": 1,\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"request_status\": \"submitted\",\n    \"discrepancy_accepted_at\": null,\n    \"discrepancy_accepted_by\": null,\n    \"lines\": [\n      {\n        \"id\": 9,\n        \"fulfillment_order_id\": 6,\n        \"sales_order_line_id\": 14,\n        \"quantity\": 1,\n        \"remaining_quantity\": 0,\n        \"sku\": \"abc\",\n        \"name\": \"In-stock item\",\n        \"product_id\": 3\n      },\n      {\n        \"id\": 10,\n        \"fulfillment_order_id\": 6,\n        \"sales_order_line_id\": 15,\n        \"quantity\": 1,\n        \"remaining_quantity\": 1,\n        \"sku\": \"195093200861\",\n        \"name\": \"Mis-tagged item (parked)\",\n        \"product_id\": 7\n      }\n    ]\n  },\n  \"message\": \"Discrepancy re-opened.\"\n}"}]},{"name":"List Fulfillment Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/list","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","list"]},"description":"Paginated, filtered, sorted list of FulfillmentOrders across ALL sales orders — the data source for the top-level **Fulfillment Orders** list view (a sibling of the Fulfillments table). Distinct from `GET /api/fulfillment-orders` (the active dispatch board): this `list` endpoint includes closed/cancelled FOs and supports the full filter/sort/paginate surface.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach row eager-loads `warehouse`, `salesOrder` (for sales_order_number), `lines.salesOrderLine.product` (for the expandable line rows), and the requested shipping method.\n\nFilters also accept the Advanced-Filters base64 `filter_groups` tree (the chips/modal send operator-suffixed keys such as `status.is`, `created_at.between`); both flat `filter[col]` and `filter_groups` flow through the same Spatie QueryBuilder + GroupedFilterSupport pipeline.\n\nReturns standard Laravel pagination — items directly under `data[]` (NOT `data.data`). Authenticate with a Personal Access Token.\n\n**New columns (also returned by the dispatch board):** sales_order_date, customer_name, sales_channel_name, total_quantity (sum of line quantities), and packing_slip_printed_at (when the FO's packing slip was last printed; null until printed). The customer/sales-channel/sales-order-date columns are filterable via the filters above (customer_name / sales_channel_type_name already exist), and packing_slip_printed_at is sortable.\n\n**Shipping method filters:** `filter[shipping_method]` (structured/mapped method) and `filter[shipping_method_manual]` (free-text \"Manual\" method). The response exposes `shipping_method` and `shipping_method_manual` accordingly - exactly one is populated per FO.\n\nThe response is standard Laravel pagination (items under `data`, plus `current_page`, `last_page`, `per_page`, `total`) with one extra top-level key: `unfiltered_total` — the count of all fulfillment orders ignoring filters (used to label the \"All records\" option in the export modal)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/list","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 6,\n      \"sales_order_id\": 1,\n      \"sales_order_number\": \"SO-0001\",\n      \"sales_order_date\": \"2026-06-15T00:00:00+00:00\",\n      \"customer_name\": \"Acme Retail Co.\",\n      \"customer_id\": 281384,\n      \"sales_channel_name\": \"Shopify\",\n      \"integration_name\": \"Curvy AU\",\n      \"total_quantity\": 5,\n      \"packing_slip_printed_at\": \"2026-06-16T14:32:10+00:00\",\n      \"warehouse_id\": 1,\n      \"status\": \"open\",\n      \"request_status\": \"unsubmitted\",\n      \"status_label\": \"Open\",\n      \"is_stuck_submitting\": false,\n      \"is_pickup\": false,\n      \"external_id\": null,\n      \"external_type\": null,\n      \"integration_instance_id\": null,\n      \"requested_shipping_method_id\": 12,\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"shipping_method\": \"UPS Ground\",\n      \"shipping_method_manual\": null,\n      \"shipping_method_origin\": \"inherited\",\n      \"requested_ship_date\": null,\n      \"requested_metadata\": null,\n      \"next_fulfillment_sequence\": 2,\n      \"submitted_at\": null,\n      \"accepted_at\": null,\n      \"closed_at\": null,\n      \"cancelled_at\": null,\n      \"rejection_reason\": null,\n      \"created_at\": \"2026-06-02T20:43:00+00:00\",\n      \"updated_at\": \"2026-06-02T20:43:00+00:00\",\n      \"lines\": [\n        {\n          \"id\": 9,\n          \"fulfillment_order_id\": 6,\n          \"sales_order_line_id\": 14,\n          \"quantity\": 2,\n          \"remaining_quantity\": 2,\n          \"sku\": \"abc\",\n          \"name\": \"abc desc\",\n          \"product_id\": 3,\n          \"created_at\": \"2026-06-02T20:43:00+00:00\",\n          \"updated_at\": \"2026-06-02T20:43:00+00:00\"\n        }\n      ],\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Default Warehouse\",\n        \"type\": \"direct\",\n        \"order_fulfillment\": \"starshipit\",\n        \"supplier_id\": null,\n        \"supplier_name\": null\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 20,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/fulfillment-orders/list?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/fulfillment-orders/list?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/fulfillment-orders/list\",\n  \"links\": []\n}"}]},{"name":"Get Fulfillment Order Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/line-items","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","line-items"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]},"description":"The FO's lines (sku / name / product_id / quantity / remaining_quantity) for the list view's lazily-loaded expandable rows. Mirrors the SOF / PO line-items endpoints. `quantity` is the FOL budget; `remaining_quantity` is the amount still to be fulfilled.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthenticate with a Personal Access Token.\n\n**Fulfillability:** each line carries `fulfillable_quantity` and `unfulfillable_quantity`, computed against the FulfillmentOrder's own (intent) warehouse — not the SalesOrderLine's warehouse_id. The warehouse block's `tracks_inventory` flag is false for externally-managed warehouses (Amazon FBA/AWD)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/line-items","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","line-items"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9,\n      \"fulfillment_order_id\": 6,\n      \"sales_order_line_id\": 14,\n      \"quantity\": 2,\n      \"remaining_quantity\": 2,\n      \"fulfillable_quantity\": 2,\n      \"unfulfillable_quantity\": 0,\n      \"lot_allocation\": null,\n      \"sku\": \"abc\",\n      \"name\": \"abc desc\",\n      \"product_id\": 3,\n      \"warehouse_id\": 6,\n      \"created_at\": \"2026-06-02T20:43:00+00:00\",\n      \"updated_at\": \"2026-06-02T20:43:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Shipping Provider Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/shipping-provider-options","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","shipping-provider-options"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]},"description":"The shipping-provider options for the Edit Shipping Details picker (per-FO provider override). Lists the configured shipping-provider integration instances in the tenant PLUS a synthetic Manual option, each with whether it's mapped to this FO's warehouse (`is_mapped`) and whether it's the warehouse's preferred default (`is_warehouse_default`). The dialog pre-selects `default_integration_instance_id`.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe provider an FO dispatches to is normally the warehouse's preferred; this lets an operator override it per FO. ANY configured shipping provider is selectable AND submittable — `is_mapped` merely reflects whether an explicit ShippingProviderWarehouse mapping exists and never gates submission (the mapping only informs the default).\n\n**Click & Collect (pickup) lock.** When the FO's effective shipping method is a pickup method, the response collapses to a single locked option (`default_fulfillment_type = pickup`, one option named \"Pickup (Click & Collect)\") — a pickup order is collected in person and is never dispatched to a carrier. Pass `shipping_method_id` to preview the options against a not-yet-saved method so the lock engages/releases live.\n\n**Optional query param:** `shipping_method_id` — see above.\n\nAuthenticate with a Personal Access Token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/shipping-provider-options","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","shipping-provider-options"],"variable":[{"key":"fulfillmentOrder","value":"6","description":"Fulfillment order id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"options\": [\n      {\n        \"id\": null,\n        \"name\": \"Manual\",\n        \"integration_name\": null,\n        \"fulfillment_type\": \"manual\",\n        \"is_mapped\": true,\n        \"is_warehouse_default\": false\n      },\n      {\n        \"id\": 5,\n        \"name\": \"Starshipit — AU\",\n        \"integration_name\": \"Starshipit\",\n        \"fulfillment_type\": \"starshipit\",\n        \"is_mapped\": true,\n        \"is_warehouse_default\": true\n      },\n      {\n        \"id\": 8,\n        \"name\": \"ShipStation — Main\",\n        \"integration_name\": \"ShipStation\",\n        \"fulfillment_type\": \"shipstation\",\n        \"is_mapped\": false,\n        \"is_warehouse_default\": false\n      }\n    ],\n    \"default_integration_instance_id\": 5\n  }\n}"}]},{"name":"Bulk Submit Fulfillment Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-submit","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-submit"]},"description":"Bulk submitted many FulfillmentOrders at once. Accepts `ids[]` (required without apply_to_all; each must exist in fulfillment_orders) OR `apply_to_all=true`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWith `apply_to_all=true` the entire filtered set is resolved server-side from the table's current `filter[...]` / `filter_groups` **query-string** params (there is no body `filters` param). FOs not in a submittedable state are **skipped** (reported in `skipped[]`, not failed). Returns the acted ids, the skipped ids+reasons, and a summary message.\n\nAuthenticate with a Personal Access Token.\n\nSet `override_partial_dispatch` to true to submit orders that are only partially fulfillable even when partial dispatch is disabled. Otherwise such orders are returned in `skipped` with a `code` of `partial_dispatch_disabled`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6,\n    7\n  ],\n  \"override_partial_dispatch\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-submit","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-submit"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"submitted\": [\n      6\n    ],\n    \"skipped\": [\n      {\n        \"id\": 7,\n        \"reason\": \"Fulfillment order is not submitted.\"\n      }\n    ]\n  },\n  \"message\": \"1 fulfillment order(s) submitted. 1 skipped.\"\n}"}]},{"name":"Bulk Cancel Fulfillment Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-cancel","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-cancel"]},"description":"Bulk cancelled many FulfillmentOrders at once. Accepts `ids[]` (required without apply_to_all; each must exist in fulfillment_orders) OR `apply_to_all=true`, optional `reason` (string, max 1000) recorded on each cancelled FO.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWith `apply_to_all=true` the entire filtered set is resolved server-side from the table's current `filter[...]` / `filter_groups` **query-string** params (there is no body `filters` param). FOs not in a cancelledable state are **skipped** (reported in `skipped[]`, not failed). Returns the acted ids, the skipped ids+reasons, and a summary message.\n\nAuthenticate with a Personal Access Token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6,\n    7\n  ],\n  \"reason\": \"Customer cancelled\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-cancel","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-cancel"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"cancelled\": [\n      6\n    ],\n    \"skipped\": [\n      {\n        \"id\": 7,\n        \"reason\": \"Fulfillment order is not cancelled.\"\n      }\n    ]\n  },\n  \"message\": \"1 fulfillment order(s) cancelled. 1 skipped.\"\n}"}]},{"name":"Print Packing Slips","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/packing-slips?ids=6","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders","packing-slips"],"query":[{"key":"ids","value":"6","description":"Comma-separated FulfillmentOrder ids (required). Slips are rendered (and combined when several) and the resulting file URL is returned.","disabled":true}]},"description":"Render (and combine, when several) packing slips for the given FulfillmentOrders and return the resulting file URL. The FO is the warehouse work package, so its slip lists the FO's planned line quantities.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Query parameters:**\n- `ids` (required) — comma-separated FulfillmentOrder ids (e.g. `1,2,3`). Ids that no longer exist are skipped.\n- `engine` (optional, default `snappy`) — `snappy` renders through the NEW PdfTemplate-driven pipeline with fingerprinted `<fo_id>_<fp>.pdf` caching; `jasper` keeps the legacy Jasper flow with stable `<fo_id>.pdf` caching.\n\nPrinting stamps `packing_slip_printed_at` on each FO. When multiple slips render, they are combined into a single PDF and a `reports` disk URL is returned.\n\n**Errors:** If the selected engine's renderer fails, the endpoint returns HTTP 500 with a JSON `message` describing which engine failed (details are written to the application logs)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/packing-slips?ids=6","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders","packing-slips"],"query":[{"key":"ids","value":"6","description":"Comma-separated FulfillmentOrder ids (required). Slips are rendered (and combined when several) and the resulting file URL is returned.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"file\": \"https://{{domain}}/storage/fulfillment_order_packing_slips/6.pdf\"\n  },\n  \"status\": \"success\",\n  \"message\": null\n}"}]},{"name":"Get Fulfillment Order Packing Slip Cache Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/{fulfillmentOrder}/packing-slip/cache-status","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders",":fulfillmentOrder","packing-slip","cache-status"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]},"description":"Report whether a rendered packing-slip PDF is cached for this FulfillmentOrder (and when it was generated) so the UI can surface a \"cached\" indicator and offer a one-click clear. Reports the newer of the legacy Jasper (`<fo_id>.pdf`) and Snappy (fingerprinted `<fo_id>_<fp>.pdf`) cache entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/{fulfillmentOrder}/packing-slip/cache-status","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders",":fulfillmentOrder","packing-slip","cache-status"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"cached\": true,\n    \"generated_at\": \"2026-06-23T22:24:20+00:00\"\n  }\n}"}]},{"name":"Clear Fulfillment Order Packing Slip Cache","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/{fulfillmentOrder}/packing-slip/cache","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders",":fulfillmentOrder","packing-slip","cache"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]},"description":"Operator self-serve: drop the cached packing-slip PDF so the next print regenerates from current data. Wipes BOTH engines' caches — the legacy Jasper `<fo_id>.pdf` and every Snappy fingerprinted `<fo_id>_<fp>.pdf`. Idempotent — clearing a slip that was never cached is a no-op.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/export/fulfillment-orders/{fulfillmentOrder}/packing-slip/cache","host":["{{baseUrl}}"],"path":["api","export","fulfillment-orders",":fulfillmentOrder","packing-slip","cache"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cached packing slip cleared — the next print will regenerate from current data.\"\n}"}]},{"name":"Create Fulfillment Order Merge Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-group","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-group"]},"description":"Merge two or more pre-dispatch fulfillment orders from DIFFERENT sales orders into one merged shipment group. The group dispatches to the shipping provider as a single order keyed on the primary member; at ship time each member's sales order records its own fulfillment carrying the shared tracking. If one of the given fulfillment orders already belongs to a group, the others are added to that group.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEligibility is enforced server-side: every member must be pre-dispatch (`status=open`, `request_status` unsubmitted/rejected), at the same warehouse, for the same shipping provider and shipping address. Amazon FBA fulfillment orders can never be merged.\n\n**Body fields:**\n- `fulfillment_order_ids` (required, array of integers, min 2) — the fulfillment orders to merge.\n- `primary_fulfillment_order_id` (optional, integer, nullable) — which member's reference the provider order is keyed on; defaults to the first id.\n\nReturns 201 with the group and its member summaries. 409 when a member is no longer mutable (already dispatched); 422 for ineligible combinations.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"fulfillment_order_ids\": [\n    451,\n    468\n  ],\n  \"primary_fulfillment_order_id\": 451\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-group","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-group"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 31,\n    \"primary_fulfillment_order_id\": 451,\n    \"warehouse_id\": 7,\n    \"members\": [\n      {\n        \"id\": 451,\n        \"sales_order_id\": 123,\n        \"sales_order_number\": \"SO-000123\",\n        \"is_primary\": true,\n        \"status\": \"open\",\n        \"request_status\": \"unsubmitted\"\n      },\n      {\n        \"id\": 468,\n        \"sales_order_id\": 130,\n        \"sales_order_number\": \"SO-000130\",\n        \"is_primary\": false,\n        \"status\": \"open\",\n        \"request_status\": \"unsubmitted\"\n      }\n    ],\n    \"created_at\": \"2026-06-20T14:05:00+00:00\",\n    \"updated_at\": \"2026-06-20T14:05:00+00:00\"\n  }\n}"}]},{"name":"Delete Fulfillment Order Merge Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-group/{mergeGroup}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-group",":mergeGroup"],"variable":[{"key":"mergeGroup","value":"31","description":"Merge group ID"}]},"description":"Dissolve a merged shipment group entirely: every member fulfillment order reverts to an independent pre-dispatch fulfillment order. Only allowed while the group is still pre-dispatch — once dispatched to the provider the group can no longer be dissolved (409).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 204 No Content on success.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/merge-group/{mergeGroup}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","merge-group",":mergeGroup"],"variable":[{"key":"mergeGroup","value":"31","description":"Merge group ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Remove Fulfillment Order from Merge Group","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/unmerge","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","unmerge"],"variable":[{"key":"fulfillmentOrder","value":"468","description":"Fulfillment order ID to remove from its merge group"}]},"description":"Remove this fulfillment order from its merged shipment group (pre-dispatch only). If the removal leaves fewer than two members, the whole group dissolves automatically.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the fulfillment order with refreshed lines and warehouse. 409 when the group has already been dispatched; 422 when the fulfillment order is not in a merge group.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/unmerge","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","unmerge"],"variable":[{"key":"fulfillmentOrder","value":"468","description":"Fulfillment order ID to remove from its merge group"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 451,\n  \"sales_order_id\": 123,\n  \"warehouse_id\": 7,\n  \"status\": \"open\",\n  \"request_status\": \"unsubmitted\",\n  \"external_id\": null,\n  \"external_type\": null,\n  \"integration_instance_id\": null,\n  \"effective_fulfillment_provider\": \"manual\",\n  \"effective_integration_instance_name\": null,\n  \"provider_order_link\": null,\n  \"submitted_at\": null,\n  \"accepted_at\": null,\n  \"closed_at\": null,\n  \"cancelled_at\": null,\n  \"rejection_reason\": null,\n  \"created_at\": \"2026-05-26T10:15:00+00:00\",\n  \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n  \"lines\": [\n    {\n      \"id\": 901,\n      \"fulfillment_order_id\": 451,\n      \"sales_order_line_id\": 55347,\n      \"quantity\": 3,\n      \"remaining_quantity\": 3,\n      \"fulfillable_quantity\": 3,\n      \"unfulfillable_quantity\": 0,\n      \"executed_quantity\": 0,\n      \"sales_order_fulfillment_lines\": [],\n      \"lot_allocation\": null,\n      \"sku\": \"WIDGET-01\",\n      \"name\": \"Blue Widget\",\n      \"product_id\": 88,\n      \"warehouse_id\": 7,\n      \"created_at\": \"2026-05-26T10:15:00+00:00\",\n      \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n    },\n    {\n      \"id\": 902,\n      \"fulfillment_order_id\": 451,\n      \"sales_order_line_id\": 55348,\n      \"quantity\": 2,\n      \"remaining_quantity\": 1,\n      \"fulfillable_quantity\": 1,\n      \"unfulfillable_quantity\": 0,\n      \"executed_quantity\": 0,\n      \"sales_order_fulfillment_lines\": [],\n      \"lot_allocation\": null,\n      \"sku\": \"WIDGET-02\",\n      \"name\": \"Red Widget\",\n      \"product_id\": 89,\n      \"warehouse_id\": 7,\n      \"created_at\": \"2026-05-26T10:15:00+00:00\",\n      \"updated_at\": \"2026-05-26T10:32:00+00:00\"\n    }\n  ],\n  \"warehouse\": {\n    \"id\": 7,\n    \"name\": \"Main Warehouse\",\n    \"type\": \"standard\",\n    \"tracks_inventory\": true\n  }\n}"}]},{"name":"Sync Fulfillment Order from Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/sync-from-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","sync-from-provider"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]},"description":"Pull the shipping provider's latest data for the whole fulfillment order and reconcile the shipments it may have produced. An awaiting fulfillment order that the provider now reports shipped gets its shipment created; existing shipments have their tracking and status refreshed.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe fulfillment order must already have a registered provider order — 422 otherwise, and 422 on provider/transport failures.\n\n**Response fields:** `data` (the refreshed fulfillment order with lines and shipments), `message` (summary of what the sync did), `shipment_status` (the provider's reported shipment status), `tracking_pipeline_ran` (whether tracking updates were processed).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/sync-from-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","sync-from-provider"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"effective_fulfillment_provider\": \"manual\",\n    \"effective_integration_instance_name\": null,\n    \"provider_order_link\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"fulfillable_quantity\": 3,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-01\",\n        \"name\": \"Blue Widget\",\n        \"product_id\": 88,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      },\n      {\n        \"id\": 902,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55348,\n        \"quantity\": 2,\n        \"remaining_quantity\": 1,\n        \"fulfillable_quantity\": 1,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-02\",\n        \"name\": \"Red Widget\",\n        \"product_id\": 89,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:32:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"tracks_inventory\": true\n    }\n  },\n  \"message\": \"Provider order refreshed; 1 shipment updated.\",\n  \"shipment_status\": \"shipped\",\n  \"tracking_pipeline_ran\": true\n}"}]},{"name":"Sync Fulfillment Order to Provider","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/sync-to-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","sync-to-provider"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]},"description":"Push the fulfillment order's current order-level state (items, quantities, customer address) to the shipping provider. When shipments already exist each one is reconciled and re-sent; when none exist yet the registered provider order is updated in place — the primary use while the order is still awaiting fulfillment.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe fulfillment order must already have a registered provider order — 422 otherwise, and 422 on provider/transport failures.\n\n**Response fields:** `data` (the refreshed fulfillment order), `message` (summary), `shipments_pushed` (how many provider shipments were re-sent), `awaiting` (true when the provider order was updated in place because no shipments exist yet).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/sync-to-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","sync-to-provider"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"sales_order_id\": 123,\n    \"warehouse_id\": 7,\n    \"status\": \"open\",\n    \"request_status\": \"unsubmitted\",\n    \"external_id\": null,\n    \"external_type\": null,\n    \"integration_instance_id\": null,\n    \"effective_fulfillment_provider\": \"manual\",\n    \"effective_integration_instance_name\": null,\n    \"provider_order_link\": null,\n    \"submitted_at\": null,\n    \"accepted_at\": null,\n    \"closed_at\": null,\n    \"cancelled_at\": null,\n    \"rejection_reason\": null,\n    \"created_at\": \"2026-05-26T10:15:00+00:00\",\n    \"updated_at\": \"2026-05-26T10:15:00+00:00\",\n    \"lines\": [\n      {\n        \"id\": 901,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55347,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3,\n        \"fulfillable_quantity\": 3,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-01\",\n        \"name\": \"Blue Widget\",\n        \"product_id\": 88,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:15:00+00:00\"\n      },\n      {\n        \"id\": 902,\n        \"fulfillment_order_id\": 451,\n        \"sales_order_line_id\": 55348,\n        \"quantity\": 2,\n        \"remaining_quantity\": 1,\n        \"fulfillable_quantity\": 1,\n        \"unfulfillable_quantity\": 0,\n        \"executed_quantity\": 0,\n        \"sales_order_fulfillment_lines\": [],\n        \"lot_allocation\": null,\n        \"sku\": \"WIDGET-02\",\n        \"name\": \"Red Widget\",\n        \"product_id\": 89,\n        \"warehouse_id\": 7,\n        \"created_at\": \"2026-05-26T10:15:00+00:00\",\n        \"updated_at\": \"2026-05-26T10:32:00+00:00\"\n      }\n    ],\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"standard\",\n      \"tracks_inventory\": true\n    }\n  },\n  \"message\": \"Provider order updated in place.\",\n  \"shipments_pushed\": 0,\n  \"awaiting\": true\n}"}]},{"name":"Apply Fulfillment Order Line Update","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/apply-line-update","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","apply-line-update"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]},"description":"Apply a quantity change to a submitted fulfillment order in place. When a quantity increase created a separate fulfillment order for the extra units, this absorbs that fulfillment order back into this one and pushes the enlarged line set to the shipping provider as an update.\n\nThe provider update is attempted first: if the provider rejects it (for example, the order can no longer be edited), the change is rolled back and the response reports `provider_ineligible` so you can keep the separate fulfillment order instead.\n\nAlways returns 200 with an `outcome` of `success` (grown and confirmed by the provider), `provider_ineligible` (provider rejected the update; rolled back), or `not_update_capable` (no registered provider order, a shipment already exists, or the provider has no in-place update). `data` is the refreshed fulfillment order and `message` is a human-readable summary.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/apply-line-update","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","apply-line-update"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 451,\n    \"status\": \"open\",\n    \"request_status\": \"submitted\",\n    \"warehouse_id\": 12,\n    \"lines\": [\n      {\n        \"id\": 8801,\n        \"sales_order_line_id\": 33021,\n        \"quantity\": 3,\n        \"remaining_quantity\": 3\n      }\n    ]\n  },\n  \"outcome\": \"success\",\n  \"message\": \"Odoo 3PL order updated in place.\"\n}"}]},{"name":"Bulk Sync Fulfillment Orders from Provider","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-sync-from-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-sync-from-provider"]},"description":"Update tracking for many fulfillment orders at once by polling each one's registered provider order. Accepts an explicit `ids` selection, or `apply_to_all=true` — in which case the entire filtered set is resolved server-side from the request query string's current `filter[...]` / `filter_groups` parameters (the same filters as the fulfillment orders list endpoint). There is no body `filters` parameter.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**This endpoint is asynchronous**: it dispatches a background job and returns immediately with a `tracked_job_log_id` that can be used to monitor progress. Fulfillment orders with no registered provider order yet are skipped by the job rather than rejected here.\n\n**Body fields:**\n- `ids` (array of integers, required unless `apply_to_all` is true) — fulfillment order IDs to sync.\n- `apply_to_all` (optional, boolean) — sync every fulfillment order matching the current query-string filters.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    451,\n    468,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/bulk-sync-from-provider","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","bulk-sync-from-provider"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9182\n  },\n  \"message\": \"Updating tracking for 3 fulfillment order(s) — track progress in the job tray.\"\n}"}]},{"name":"Get FBA Fulfillment Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/fba-fulfillment-preview","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","fba-fulfillment-preview"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID (must be an Amazon FBA order)"}]},"description":"For a still-unsubmitted Amazon FBA fulfillment order, fetch Amazon's fulfillment preview: one estimate per available shipping speed (fulfillability, estimated fees, estimated shipping weight, and the ship/arrival window) WITHOUT creating a Multi-Channel Fulfillment order. Use it to compare speeds and costs before submitting.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the order cannot be previewed — not an FBA order, no shipping address, no Amazon marketplace configured for the destination country, or no items mapped to an active FBA listing — and when Amazon rejects the call.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/fba-fulfillment-preview","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","fba-fulfillment-preview"],"variable":[{"key":"fulfillmentOrder","value":"451","description":"Fulfillment order ID (must be an Amazon FBA order)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shipping_speed\": \"Standard\",\n      \"is_fulfillable\": true,\n      \"is_cod_capable\": false,\n      \"estimated_fee\": 12.47,\n      \"currency\": \"USD\",\n      \"fees\": [\n        {\n          \"name\": \"FBAPerUnitFulfillmentFee\",\n          \"amount\": 10.99,\n          \"currency\": \"USD\"\n        },\n        {\n          \"name\": \"FBATransportationFee\",\n          \"amount\": 1.48,\n          \"currency\": \"USD\"\n        }\n      ],\n      \"estimated_weight\": {\n        \"value\": 2.1,\n        \"unit\": \"LB\"\n      },\n      \"earliest_ship_date\": \"2026-06-21T07:00:00Z\",\n      \"latest_ship_date\": \"2026-06-22T07:00:00Z\",\n      \"earliest_arrival_date\": \"2026-06-25T07:00:00Z\",\n      \"latest_arrival_date\": \"2026-06-28T07:00:00Z\",\n      \"shipment_count\": 1,\n      \"unfulfillable_reasons\": []\n    },\n    {\n      \"shipping_speed\": \"Expedited\",\n      \"is_fulfillable\": true,\n      \"is_cod_capable\": false,\n      \"estimated_fee\": 15.32,\n      \"currency\": \"USD\",\n      \"fees\": [\n        {\n          \"name\": \"FBAPerUnitFulfillmentFee\",\n          \"amount\": 12.99,\n          \"currency\": \"USD\"\n        },\n        {\n          \"name\": \"FBATransportationFee\",\n          \"amount\": 2.33,\n          \"currency\": \"USD\"\n        }\n      ],\n      \"estimated_weight\": {\n        \"value\": 2.1,\n        \"unit\": \"LB\"\n      },\n      \"earliest_ship_date\": \"2026-06-21T07:00:00Z\",\n      \"latest_ship_date\": \"2026-06-21T19:00:00Z\",\n      \"earliest_arrival_date\": \"2026-06-23T07:00:00Z\",\n      \"latest_arrival_date\": \"2026-06-24T07:00:00Z\",\n      \"shipment_count\": 1,\n      \"unfulfillable_reasons\": []\n    }\n  ]\n}"}]},{"name":"Export Fulfillment Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/export?format=xlsx&content_mode=summary&scope=filtered","host":["{{baseUrl}}"],"path":["api","fulfillment-orders","export"],"query":[{"key":"format","value":"xlsx","description":"File format: xlsx (default) or csv.","disabled":true},{"key":"content_mode","value":"summary","description":"summary (one row per FO, default) or line_items (one row per FO line).","disabled":true},{"key":"scope","value":"filtered","description":"Which records to export: all | filtered (default) | current_page | selected.","disabled":true}]},"description":"Export the Fulfillment Orders list view as an XLSX or CSV file (sibling of the Fulfillments export). Requires a Bearer token.\n\nThe response is a binary file download (not JSON): `Content-Type` is `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for xlsx or `text/csv` for csv. The filename is `fulfillment-orders-<timestamp>.<ext>` (or `fulfillment-orders-detail-<timestamp>.<ext>` in line_items mode).\n\n**Scope** (`scope`): `all` exports every FO ignoring the table's filters; `filtered` honours the table's active filters/sort (pass the same `filter[...]` / `sort` / `filter[lifecycle]` / `filter[merged]` query params as the list endpoint); `current_page` exports just the current page; `selected` exports the ids passed in `ids`.\n\n**Content** (`content_mode`): `summary` = one row per fulfillment order; `line_items` = one row per FO line with the fulfillment-order columns repeated (item SKU / name / qty / remaining appended).\n\n**Columns** (`columns`): comma-separated visible list view column keys — only those columns are exported, in the given order. Omit to export all columns.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List Fulfillment Order Packing Slip Print Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]},"description":"Newest-first paginated history of every time this fulfillment order's packing slip was printed: who printed it, when, the render engine used, a print-time context snapshot (order reference, warehouse, line count), and whether an exact copy of the printed PDF is retained (`has_stored_copy`). Each event's exact printed PDF is retrievable via the download endpoint.\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9012,\n      \"printed_at\": \"2026-07-23T14:03:11+00:00\",\n      \"printed_by\": {\n        \"id\": 42,\n        \"name\": \"Warehouse Operator\"\n      },\n      \"printed_by_name\": \"Warehouse Operator\",\n      \"engine\": \"snappy\",\n      \"engine_label\": \"New\",\n      \"trigger\": \"single\",\n      \"capture_status\": \"stored\",\n      \"has_stored_copy\": true,\n      \"fingerprint\": \"a1b2c3d4\",\n      \"byte_count\": 48213,\n      \"page_count\": 1,\n      \"order_reference\": \"SO-10442\",\n      \"warehouse_id\": 9,\n      \"warehouse_name\": \"Main DC\",\n      \"line_count\": 3,\n      \"reprint_reason\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"...\"\n}"}]},{"name":"Download Fulfillment Order Packing Slip Print Copy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events/{packingSlipPrintEvent}/download","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events",":packingSlipPrintEvent","download"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"},{"key":"packingSlipPrintEvent","value":"9012","description":"Print event ID"}]},"description":"Return a signed URL to the byte-identical copy of the exact PDF that was printed for this event. The stored copy is never re-rendered, so it reflects the document exactly as it was printed even if the order has since changed. Returns 404 when the event does not belong to this fulfillment order, or when no copy was retained for it.\n\n**Authentication:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events/{packingSlipPrintEvent}/download","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events",":packingSlipPrintEvent","download"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"},{"key":"packingSlipPrintEvent","value":"9012","description":"Print event ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"file\": \"/tenant-asset/reports/packing_slip_audit/fo/123/02389e97035b.pdf?t=acme\"\n  }\n}"}]},{"name":"Update Packing Slip Print Event Reprint Reason","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events/{packingSlipPrintEvent}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events",":packingSlipPrintEvent"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"},{"key":"packingSlipPrintEvent","value":"9012","description":"Print event ID"}]},"description":"Set or clear an optional free-text reason on a packing-slip print event (for example, explaining why a slip was reprinted). Pass `reprint_reason` as a string (max 255 characters) or null to clear it.\n\n**Authentication:** Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"reprint_reason\": \"Printer jam — first copy smeared\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/fulfillment-orders/{fulfillmentOrder}/packing-slip-print-events/{packingSlipPrintEvent}","host":["{{baseUrl}}"],"path":["api","fulfillment-orders",":fulfillmentOrder","packing-slip-print-events",":packingSlipPrintEvent"],"variable":[{"key":"fulfillmentOrder","value":"123","description":"Fulfillment order ID"},{"key":"packingSlipPrintEvent","value":"9012","description":"Print event ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 9012,\n  \"printed_at\": \"2026-07-23T14:03:11+00:00\",\n  \"printed_by\": {\n    \"id\": 42,\n    \"name\": \"Warehouse Operator\"\n  },\n  \"printed_by_name\": \"Warehouse Operator\",\n  \"engine\": \"snappy\",\n  \"engine_label\": \"New\",\n  \"trigger\": \"single\",\n  \"capture_status\": \"stored\",\n  \"has_stored_copy\": true,\n  \"fingerprint\": \"a1b2c3d4\",\n  \"byte_count\": 48213,\n  \"page_count\": 1,\n  \"order_reference\": \"SO-10442\",\n  \"warehouse_id\": 9,\n  \"warehouse_name\": \"Main DC\",\n  \"line_count\": 3,\n  \"reprint_reason\": \"Printer jam — first copy smeared\"\n}"}]}]},{"name":"Line Decorations","item":[{"name":"List Line Decorations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]},"description":"List all decoration specs for a sales order line. Each spec includes the linked artwork summary (`artwork`) and the selected thread/ink colors (`colors`).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"sales_order_line_id\": 3001,\n      \"method\": \"embroidery\",\n      \"placement\": \"front_left_chest\",\n      \"placement_custom\": null,\n      \"blank_product_id\": 240,\n      \"artwork\": {\n        \"id\": 5,\n        \"name\": \"Acme Corp Logo\",\n        \"digitization_state\": \"digitized\"\n      },\n      \"colors\": [\n        {\n          \"product_id\": 88,\n          \"name\": \"Red Thread\"\n        }\n      ],\n      \"stitch_count\": 12000,\n      \"ink_colors_count\": null,\n      \"area_sq_in\": 12.5,\n      \"setup_type\": \"new_setup\",\n      \"digitization_required\": true,\n      \"quantity_multiplier\": 1,\n      \"estimated_cost\": \"4.50\",\n      \"estimated_cost_lines\": [\n        {\n          \"id\": 1,\n          \"sales_order_line_decoration_id\": 1,\n          \"decoration_cost_rule_id\": 7,\n          \"cost_category_id\": 42,\n          \"cost_category_name\": \"Decoration Labor\",\n          \"amount\": \"3.60\",\n          \"is_structural_loss_flag\": false\n        },\n        {\n          \"id\": 2,\n          \"sales_order_line_decoration_id\": 1,\n          \"decoration_cost_rule_id\": 8,\n          \"cost_category_id\": 43,\n          \"cost_category_name\": \"Decoration Consumables\",\n          \"amount\": \"0.90\",\n          \"is_structural_loss_flag\": false\n        }\n      ],\n      \"has_structural_loss_flag\": false,\n      \"manufacturing_order_id\": null,\n      \"notes\": \"Match thread to PMS 186 C\",\n      \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Add Line Decoration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]},"description":"Add a decoration spec to a sales order line.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired: `method`, `placement`, `setup_type`. `placement_custom` is required when `placement` is `custom`. `stitch_count` is required when `method` is `embroidery`; `ink_colors_count` is required when `method` is `screen_print`. `artwork_id` must reference an existing artwork; `color_product_ids[]` must reference existing products. `quantity_multiplier` defaults to 1.\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"method\": \"embroidery\",\n  \"placement\": \"front_left_chest\",\n  \"placement_custom\": null,\n  \"blank_product_id\": 240,\n  \"artwork_id\": 5,\n  \"color_product_ids\": [\n    88\n  ],\n  \"stitch_count\": 12000,\n  \"ink_colors_count\": null,\n  \"area_sq_in\": 12.5,\n  \"setup_type\": \"new_setup\",\n  \"digitization_required\": true,\n  \"quantity_multiplier\": 1,\n  \"estimated_cost\": 4.5,\n  \"notes\": \"Match thread to PMS 186 C\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sales_order_line_id\": 3001,\n    \"method\": \"embroidery\",\n    \"placement\": \"front_left_chest\",\n    \"placement_custom\": null,\n    \"blank_product_id\": 240,\n    \"artwork\": {\n      \"id\": 5,\n      \"name\": \"Acme Corp Logo\",\n      \"digitization_state\": \"digitized\"\n    },\n    \"colors\": [\n      {\n        \"product_id\": 88,\n        \"name\": \"Red Thread\"\n      }\n    ],\n    \"stitch_count\": 12000,\n    \"ink_colors_count\": null,\n    \"area_sq_in\": 12.5,\n    \"setup_type\": \"new_setup\",\n    \"digitization_required\": true,\n    \"quantity_multiplier\": 1,\n    \"estimated_cost\": \"4.50\",\n    \"estimated_cost_lines\": [\n      {\n        \"id\": 1,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 7,\n        \"cost_category_id\": 42,\n        \"cost_category_name\": \"Decoration Labor\",\n        \"amount\": \"3.60\",\n        \"is_structural_loss_flag\": false\n      },\n      {\n        \"id\": 2,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 8,\n        \"cost_category_id\": 43,\n        \"cost_category_name\": \"Decoration Consumables\",\n        \"amount\": \"0.90\",\n        \"is_structural_loss_flag\": false\n      }\n    ],\n    \"has_structural_loss_flag\": false,\n    \"manufacturing_order_id\": null,\n    \"notes\": \"Match thread to PMS 186 C\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Line Decoration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]},"description":"Update an existing decoration spec. All fields are optional (`sometimes`) — send only the fields you want to change. The same conditional rules apply when a field is present (e.g. `placement_custom` required if `placement` is `custom`).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"placement\": \"full_front\",\n  \"setup_type\": \"repeat\",\n  \"estimated_cost\": 3.25,\n  \"blank_product_id\": 240\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sales_order_line_id\": 3001,\n    \"method\": \"embroidery\",\n    \"placement\": \"full_front\",\n    \"placement_custom\": null,\n    \"blank_product_id\": 240,\n    \"artwork\": {\n      \"id\": 5,\n      \"name\": \"Acme Corp Logo\",\n      \"digitization_state\": \"digitized\"\n    },\n    \"colors\": [\n      {\n        \"product_id\": 88,\n        \"name\": \"Red Thread\"\n      }\n    ],\n    \"stitch_count\": 12000,\n    \"ink_colors_count\": null,\n    \"area_sq_in\": 12.5,\n    \"setup_type\": \"repeat\",\n    \"digitization_required\": true,\n    \"quantity_multiplier\": 1,\n    \"estimated_cost\": \"3.25\",\n    \"estimated_cost_lines\": [\n      {\n        \"id\": 1,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 7,\n        \"cost_category_id\": 42,\n        \"cost_category_name\": \"Decoration Labor\",\n        \"amount\": \"3.60\",\n        \"is_structural_loss_flag\": false\n      },\n      {\n        \"id\": 2,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 8,\n        \"cost_category_id\": 43,\n        \"cost_category_name\": \"Decoration Consumables\",\n        \"amount\": \"0.90\",\n        \"is_structural_loss_flag\": false\n      }\n    ],\n    \"has_structural_loss_flag\": false,\n    \"manufacturing_order_id\": null,\n    \"notes\": \"Match thread to PMS 186 C\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Remove Line Decoration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]},"description":"Remove a decoration spec from a sales order line.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Decoration removed successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Reprice Line Decoration","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}/reprice","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration","reprice"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]},"description":"Re-run the decoration cost-rule engine for a single decoration spec and refresh its pro-forma estimate. Matching `DecorationCostRule` records are re-evaluated by priority and the resulting `estimated_cost` and per-category estimated cost lines are recomputed. Takes no request body.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse this after editing cost rules or changing decoration attributes (method, stitch count, ink colors, placement) to recalculate the estimate without otherwise modifying the spec.\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decorations/{decoration}/reprice","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decorations",":decoration","reprice"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"},{"key":"decoration","value":"1","description":"Decoration spec ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sales_order_line_id\": 3001,\n    \"method\": \"embroidery\",\n    \"placement\": \"front_left_chest\",\n    \"placement_custom\": null,\n    \"blank_product_id\": 240,\n    \"artwork\": {\n      \"id\": 5,\n      \"name\": \"Acme Corp Logo\",\n      \"digitization_state\": \"digitized\"\n    },\n    \"colors\": [\n      {\n        \"product_id\": 88,\n        \"name\": \"Red Thread\"\n      }\n    ],\n    \"stitch_count\": 12000,\n    \"ink_colors_count\": null,\n    \"area_sq_in\": 12.5,\n    \"setup_type\": \"new_setup\",\n    \"digitization_required\": true,\n    \"quantity_multiplier\": 1,\n    \"estimated_cost\": \"5.10\",\n    \"estimated_cost_lines\": [\n      {\n        \"id\": 1,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 7,\n        \"cost_category_id\": 42,\n        \"cost_category_name\": \"Decoration Labor\",\n        \"amount\": \"3.60\",\n        \"is_structural_loss_flag\": false\n      },\n      {\n        \"id\": 2,\n        \"sales_order_line_decoration_id\": 1,\n        \"decoration_cost_rule_id\": 8,\n        \"cost_category_id\": 43,\n        \"cost_category_name\": \"Decoration Consumables\",\n        \"amount\": \"0.90\",\n        \"is_structural_loss_flag\": false\n      }\n    ],\n    \"has_structural_loss_flag\": false,\n    \"manufacturing_order_id\": null,\n    \"notes\": \"Match thread to PMS 186 C\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]}]},{"name":"Decoration Orders","item":[{"name":"List Decoration Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"}]},"description":"List the decoration manufacturing orders linked to a sales order, with their status and production method.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"decoration_id\": 12,\n      \"sales_order_line_id\": 3001,\n      \"method\": \"embroidery\",\n      \"placement\": \"front_left_chest\",\n      \"artwork_name\": \"Acme Corp Logo\",\n      \"manufacturing_order_id\": 880,\n      \"manufacturing_order\": {\n        \"id\": 880,\n        \"mo_number\": \"MO-000880\",\n        \"status\": \"draft\",\n        \"production_method\": \"in_house\",\n        \"planned_quantity\": 24,\n        \"completed_quantity\": 0\n      }\n    }\n  ]\n}"}]},{"name":"Create Decoration Orders (Bulk)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"}]},"description":"Bulk-create decoration manufacturing orders for every decorated line on the order via a tracked background job (global progress tray). One MO per decoration; already-linked decorations are skipped. Returns the tracked job log id to poll.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token and the sales_orders.update permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4521\n  },\n  \"message\": \"Decoration orders started — track progress in the job tray.\"\n}"}]},{"name":"Create Line Decoration Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]},"description":"Create decoration manufacturing orders for a single line synchronously. Returns the created manufacturing order ids. Returns 422 with an actionable message when no blank product can be resolved for a decoration.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token and the sales_orders.update permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-orders/{salesOrder}/lines/{salesOrderLine}/decoration-orders","host":["{{baseUrl}}"],"path":["api","sales-orders",":salesOrder","lines",":salesOrderLine","decoration-orders"],"variable":[{"key":"salesOrder","value":"501","description":"Sales order ID"},{"key":"salesOrderLine","value":"3001","description":"Sales order line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"manufacturing_order_ids\": [\n      880,\n      881\n    ]\n  },\n  \"message\": \"Decoration orders created.\"\n}"}]}]},{"name":"Artwork","item":[{"name":"List Artworks","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/artworks","host":["{{baseUrl}}"],"path":["api","artworks"]},"description":"List paginated artworks with optional filters and sorting.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/artworks","host":["{{baseUrl}}"],"path":["api","artworks"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"name\": \"Acme Corp Logo\",\n      \"customer_id\": 42,\n      \"type\": \"logo\",\n      \"digitization_state\": \"digitized\",\n      \"compatible_methods\": [\n        \"embroidery\",\n        \"screen_print\"\n      ],\n      \"stitch_count\": 12000,\n      \"ink_colors\": 3,\n      \"version\": 1,\n      \"preview_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo-preview.png\",\n      \"production_file_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo.emb\",\n      \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Artwork","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/artworks","host":["{{baseUrl}}"],"path":["api","artworks"]},"description":"Create a new artwork. Required: `name`, `type`. `digitization_state` defaults to `submitted` and `version` defaults to 1 when omitted. `customer_id` must reference an existing customer; `compatible_methods[]` must be valid decoration methods.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme Corp Logo\",\n  \"customer_id\": 42,\n  \"type\": \"logo\",\n  \"digitization_state\": \"submitted\",\n  \"compatible_methods\": [\n    \"embroidery\",\n    \"screen_print\"\n  ],\n  \"stitch_count\": 12000,\n  \"ink_colors\": 3,\n  \"version\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/artworks","host":["{{baseUrl}}"],"path":["api","artworks"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Acme Corp Logo\",\n    \"customer_id\": 42,\n    \"type\": \"logo\",\n    \"digitization_state\": \"submitted\",\n    \"compatible_methods\": [\n      \"embroidery\",\n      \"screen_print\"\n    ],\n    \"stitch_count\": 12000,\n    \"ink_colors\": 3,\n    \"version\": 1,\n    \"preview_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo-preview.png\",\n    \"production_file_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo.emb\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Get Artwork","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]},"description":"Get a single artwork by ID.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Acme Corp Logo\",\n    \"customer_id\": 42,\n    \"type\": \"logo\",\n    \"digitization_state\": \"digitized\",\n    \"compatible_methods\": [\n      \"embroidery\",\n      \"screen_print\"\n    ],\n    \"stitch_count\": 12000,\n    \"ink_colors\": 3,\n    \"version\": 1,\n    \"preview_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo-preview.png\",\n    \"production_file_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo.emb\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Artwork","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]},"description":"Update an existing artwork. All fields are optional (`sometimes`) — send only what changes.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"digitization_state\": \"digitized\",\n  \"stitch_count\": 12500\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Acme Corp Logo\",\n    \"customer_id\": 42,\n    \"type\": \"logo\",\n    \"digitization_state\": \"digitized\",\n    \"compatible_methods\": [\n      \"embroidery\",\n      \"screen_print\"\n    ],\n    \"stitch_count\": 12500,\n    \"ink_colors\": 3,\n    \"version\": 1,\n    \"preview_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo-preview.png\",\n    \"production_file_url\": \"https://cdn.example.com/tenant/images/artworks/acme-logo.emb\",\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Archive Artwork","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]},"description":"Archive an artwork (soft removal). The artwork is retained for historical decoration specs but no longer appears in active listings.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/artworks/{artwork}","host":["{{baseUrl}}"],"path":["api","artworks",":artwork"],"variable":[{"key":"artwork","value":"5","description":"Artwork ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Artwork archived successfully.\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Decoration Cost Rules","item":[{"name":"List Decoration Cost Rules","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-cost-rules","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules"]},"description":"List paginated decoration cost rules with optional filters and sorting.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires scope: `orders` (read).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/decoration-cost-rules","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"name\": \"Embroidery — per 1k stitches\",\n      \"priority\": 10,\n      \"is_active\": true,\n      \"conditions\": {\n        \"method\": \"embroidery\",\n        \"placement\": null,\n        \"setup_type\": null,\n        \"stitch_count_min\": null,\n        \"stitch_count_max\": null,\n        \"ink_colors_count\": null,\n        \"area_sq_in_min\": null,\n        \"area_sq_in_max\": null,\n        \"product_id\": null,\n        \"customer_id\": null\n      },\n      \"effect\": {\n        \"type\": \"rate_x_metric\",\n        \"cost_category_id\": 7,\n        \"amount\": null,\n        \"rate\": 0.35,\n        \"metric\": \"stitch_count\"\n      },\n      \"created_at\": \"2026-06-13T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-13T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Decoration Cost Rule","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-cost-rules","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules"]},"description":"Create a new decoration cost rule.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequired: `name`, `priority`, `is_active`, `conditions` (object), `effect` (object). `effect.type` must be one of `fixed`, `per_unit`, `rate_x_metric`, `minimum`, `flag_loss`. `effect.metric` (when present) must be one of `stitch_count`, `ink_colors_count`, `area_sq_in`. `conditions.method`, `conditions.placement`, `conditions.setup_type` must be valid enum values when present. `conditions.product_id` / `conditions.customer_id` and `effect.cost_category_id` must reference existing records.\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Embroidery — per 1k stitches\",\n  \"priority\": 10,\n  \"is_active\": true,\n  \"conditions\": {\n    \"method\": \"embroidery\",\n    \"placement\": null,\n    \"setup_type\": null,\n    \"stitch_count_min\": null,\n    \"stitch_count_max\": null,\n    \"ink_colors_count\": null,\n    \"area_sq_in_min\": null,\n    \"area_sq_in_max\": null,\n    \"product_id\": null,\n    \"customer_id\": null\n  },\n  \"effect\": {\n    \"type\": \"rate_x_metric\",\n    \"cost_category_id\": 7,\n    \"amount\": null,\n    \"rate\": 0.35,\n    \"metric\": \"stitch_count\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/decoration-cost-rules","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Embroidery — per 1k stitches\",\n    \"priority\": 10,\n    \"is_active\": true,\n    \"conditions\": {\n      \"method\": \"embroidery\",\n      \"placement\": null,\n      \"setup_type\": null,\n      \"stitch_count_min\": null,\n      \"stitch_count_max\": null,\n      \"ink_colors_count\": null,\n      \"area_sq_in_min\": null,\n      \"area_sq_in_max\": null,\n      \"product_id\": null,\n      \"customer_id\": null\n    },\n    \"effect\": {\n      \"type\": \"rate_x_metric\",\n      \"cost_category_id\": 7,\n      \"amount\": null,\n      \"rate\": 0.35,\n      \"metric\": \"stitch_count\"\n    },\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Get Decoration Cost Rule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]},"description":"Show a single decoration cost rule.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires scope: `orders` (read).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Embroidery — per 1k stitches\",\n    \"priority\": 10,\n    \"is_active\": true,\n    \"conditions\": {\n      \"method\": \"embroidery\",\n      \"placement\": null,\n      \"setup_type\": null,\n      \"stitch_count_min\": null,\n      \"stitch_count_max\": null,\n      \"ink_colors_count\": null,\n      \"area_sq_in_min\": null,\n      \"area_sq_in_max\": null,\n      \"product_id\": null,\n      \"customer_id\": null\n    },\n    \"effect\": {\n      \"type\": \"rate_x_metric\",\n      \"cost_category_id\": 7,\n      \"amount\": null,\n      \"rate\": 0.35,\n      \"metric\": \"stitch_count\"\n    },\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-13T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Decoration Cost Rule","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]},"description":"Update an existing decoration cost rule. `name`, `priority`, `is_active`, `conditions`, and `effect` are required (full replacement of the rule definition). Same enum / existence validation as create.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Embroidery — per 1k stitches\",\n  \"priority\": 5,\n  \"is_active\": true,\n  \"conditions\": {\n    \"method\": \"embroidery\",\n    \"placement\": null,\n    \"setup_type\": null,\n    \"stitch_count_min\": 5000,\n    \"stitch_count_max\": null,\n    \"ink_colors_count\": null,\n    \"area_sq_in_min\": null,\n    \"area_sq_in_max\": null,\n    \"product_id\": null,\n    \"customer_id\": null\n  },\n  \"effect\": {\n    \"type\": \"rate_x_metric\",\n    \"cost_category_id\": 7,\n    \"amount\": null,\n    \"rate\": 0.4,\n    \"metric\": \"stitch_count\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Embroidery — per 1k stitches\",\n    \"priority\": 5,\n    \"is_active\": true,\n    \"conditions\": {\n      \"method\": \"embroidery\",\n      \"placement\": null,\n      \"setup_type\": null,\n      \"stitch_count_min\": 5000,\n      \"stitch_count_max\": null,\n      \"ink_colors_count\": null,\n      \"area_sq_in_min\": null,\n      \"area_sq_in_max\": null,\n      \"product_id\": null,\n      \"customer_id\": null\n    },\n    \"effect\": {\n      \"type\": \"rate_x_metric\",\n      \"cost_category_id\": 7,\n      \"amount\": null,\n      \"rate\": 0.4,\n      \"metric\": \"stitch_count\"\n    },\n    \"created_at\": \"2026-06-13T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-13T11:30:00.000000Z\"\n  }\n}"}]},{"name":"Delete Decoration Cost Rule","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]},"description":"Delete a decoration cost rule. Existing decoration estimates already computed are not recalculated until their spec is repriced.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires permission: `sales_orders.update`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/decoration-cost-rules/{decoration_cost_rule}","host":["{{baseUrl}}"],"path":["api","decoration-cost-rules",":decoration_cost_rule"],"variable":[{"key":"decoration_cost_rule","value":"12","description":"Decoration cost rule ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Decoration cost rule deleted successfully.\",\n  \"status\": \"success\"\n}"}]}]},{"name":"Decoration Methods","item":[{"name":"List Decoration Methods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-methods","host":["{{baseUrl}}"],"path":["api","decoration-methods"]},"description":"Returns all decoration methods (active and inactive), ordered by sort_order then name.\n\nAuthentication: Requires Bearer token.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/decoration-methods","host":["{{baseUrl}}"],"path":["api","decoration-methods"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 11,\n      \"name\": \"Foil Stamp\",\n      \"slug\": \"foil_stamp\",\n      \"icon\": \"mdi-needle\",\n      \"is_active\": true,\n      \"sort_order\": 10\n    }\n  ]\n}"}]},{"name":"Create Decoration Method","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-methods","host":["{{baseUrl}}"],"path":["api","decoration-methods"]},"description":"Create a new decoration method. `name` is required; `slug` is auto-derived from the name when omitted. `icon` is an mdi icon name.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\\n  \\\"name\\\": \\\"Foil Stamp\\\",\\n  \\\"icon\\\": \\\"mdi-needle\\\",\\n  \\\"is_active\\\": true,\\n  \\\"sort_order\\\": 10\\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/decoration-methods","host":["{{baseUrl}}"],"path":["api","decoration-methods"]}},"status":"OK","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"name\": \"Foil Stamp\",\n    \"slug\": \"foil_stamp\",\n    \"icon\": \"mdi-needle\",\n    \"is_active\": true,\n    \"sort_order\": 10\n  }\n}"}]},{"name":"Update Decoration Method","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-methods/{decoration_method}","host":["{{baseUrl}}"],"path":["api","decoration-methods",":decoration_method"],"variable":[{"key":"decoration_method","value":"11","description":"Record ID"}]},"description":"Update a record. Same fields as create.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\\n  \\\"name\\\": \\\"Foil Stamp\\\",\\n  \\\"icon\\\": \\\"mdi-needle\\\",\\n  \\\"is_active\\\": true,\\n  \\\"sort_order\\\": 10\\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/decoration-methods/{decoration_method}","host":["{{baseUrl}}"],"path":["api","decoration-methods",":decoration_method"],"variable":[{"key":"decoration_method","value":"11","description":"Record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"name\": \"Foil Stamp\",\n    \"slug\": \"foil_stamp\",\n    \"icon\": \"mdi-needle\",\n    \"is_active\": true,\n    \"sort_order\": 10\n  }\n}"}]},{"name":"Delete Decoration Method","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-methods/{decoration_method}","host":["{{baseUrl}}"],"path":["api","decoration-methods",":decoration_method"],"variable":[{"key":"decoration_method","value":"11","description":"Record ID"}]},"description":"Delete a record from the registry.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/decoration-methods/{decoration_method}","host":["{{baseUrl}}"],"path":["api","decoration-methods",":decoration_method"],"variable":[{"key":"decoration_method","value":"11","description":"Record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted successfully.\"\n}"}]}]},{"name":"Decoration Placements","item":[{"name":"List Decoration Placements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-placements","host":["{{baseUrl}}"],"path":["api","decoration-placements"]},"description":"Returns all decoration placements (active and inactive), ordered by sort_order then name.\n\nAuthentication: Requires Bearer token.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/decoration-placements","host":["{{baseUrl}}"],"path":["api","decoration-placements"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 11,\n      \"name\": \"Foil Stamp\",\n      \"slug\": \"foil_stamp\",\n      \"is_active\": true,\n      \"sort_order\": 10\n    }\n  ]\n}"}]},{"name":"Create Decoration Placement","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-placements","host":["{{baseUrl}}"],"path":["api","decoration-placements"]},"description":"Create a new decoration placement. `name` is required; `slug` is auto-derived from the name when omitted.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\\n  \\\"name\\\": \\\"Foil Stamp\\\",\\n  \\\"is_active\\\": true,\\n  \\\"sort_order\\\": 10\\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/decoration-placements","host":["{{baseUrl}}"],"path":["api","decoration-placements"]}},"status":"OK","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"name\": \"Foil Stamp\",\n    \"slug\": \"foil_stamp\",\n    \"is_active\": true,\n    \"sort_order\": 10\n  }\n}"}]},{"name":"Update Decoration Placement","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/decoration-placements/{decoration_placement}","host":["{{baseUrl}}"],"path":["api","decoration-placements",":decoration_placement"],"variable":[{"key":"decoration_placement","value":"11","description":"Record ID"}]},"description":"Update a record. Same fields as create.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\\n  \\\"name\\\": \\\"Foil Stamp\\\",\\n  \\\"is_active\\\": true,\\n  \\\"sort_order\\\": 10\\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/decoration-placements/{decoration_placement}","host":["{{baseUrl}}"],"path":["api","decoration-placements",":decoration_placement"],"variable":[{"key":"decoration_placement","value":"11","description":"Record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"name\": \"Foil Stamp\",\n    \"slug\": \"foil_stamp\",\n    \"is_active\": true,\n    \"sort_order\": 10\n  }\n}"}]},{"name":"Delete Decoration Placement","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/decoration-placements/{decoration_placement}","host":["{{baseUrl}}"],"path":["api","decoration-placements",":decoration_placement"],"variable":[{"key":"decoration_placement","value":"11","description":"Record ID"}]},"description":"Delete a record from the registry.\n\nAuthentication: Requires Bearer token + `sales_orders.update` permission.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/decoration-placements/{decoration_placement}","host":["{{baseUrl}}"],"path":["api","decoration-placements",":decoration_placement"],"variable":[{"key":"decoration_placement","value":"11","description":"Record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted successfully.\"\n}"}]}]},{"name":"Quotes","item":[{"name":"List Quotes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/quotes","host":["{{baseUrl}}"],"path":["api","quotes"]},"description":"List quotes (paginated) using Spatie QueryBuilder.\n\nAuthentication: Requires Bearer token (PAT).\n\nFilters (all optional):\n- filter[search] — fuzzy LIKE across quote_number, reference, customer_po_number (customer name is encrypted, not searched)\n- filter[status] — exact status (draft, sent, viewed, accepted, declined, expired, revised, converted)\n- filter[origin] — exact origin (staff, rfq)\n- filter[customer_id] — exact customer id\n- filter_groups — base64-encoded advanced-filter tree over id, quote_number, reference, customer_po_number, status, origin, customer_id, total, valid_until, created_at, updated_at\n\nSort: sort=&lt;field>, prefix - for DESC. Allowed sorts: id, quote_number, status, total, valid_until, created_at. Default: -id.\n\nPagination: page (default 1), per_page (default 10). Returns a LengthAwarePaginator of quote object.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/quotes","host":["{{baseUrl}}"],"path":["api","quotes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"quote_number\": \"Q-000012\",\n      \"reference\": null,\n      \"status\": \"draft\",\n      \"origin\": \"staff\",\n      \"customer_id\": 88,\n      \"customer\": {\n        \"id\": 88,\n        \"name\": \"Acme Corp\",\n        \"company\": \"Acme Corp\"\n      },\n      \"sales_rep_id\": null,\n      \"store_id\": null,\n      \"sales_channel_id\": null,\n      \"currency_code\": \"USD\",\n      \"customer_po_number\": \"PO-9000\",\n      \"memo_for_customer\": \"Thanks for your business\",\n      \"cover_letter\": null,\n      \"terms\": \"Net 30\",\n      \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n      \"is_tax_included\": false,\n      \"tax_rate_id\": 3,\n      \"subtotal\": 200,\n      \"line_discount_total\": 20,\n      \"order_discount_total\": 0,\n      \"discount_total\": 20,\n      \"tax_total\": 18,\n      \"total\": 198,\n      \"deposit_type\": \"none\",\n      \"deposit_value\": null,\n      \"quote_token\": null,\n      \"accepted_version_id\": null,\n      \"sent_at\": null,\n      \"viewed_at\": null,\n      \"accepted_at\": null,\n      \"declined_at\": null,\n      \"declined_reason\": null,\n      \"expired_at\": null,\n      \"converted_at\": null,\n      \"lines\": [\n        {\n          \"id\": 1,\n          \"product_id\": 501,\n          \"sku\": \"WIDGET-1\",\n          \"description\": \"Widget\",\n          \"quantity\": 2,\n          \"unit_price\": 100,\n          \"unit_cost\": 60,\n          \"discount_type\": \"percentage\",\n          \"discount_value\": 10,\n          \"tax_rate_id\": 3,\n          \"line_type\": \"standard\",\n          \"select_group\": null,\n          \"is_selected\": true,\n          \"subtotal\": 200,\n          \"sort\": 0\n        }\n      ],\n      \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"last_page\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/quotes?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/quotes?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/quotes\",\n  \"links\": []\n}"}]},{"name":"Create Quote","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes","host":["{{baseUrl}}"],"path":["api","quotes"]},"description":"Creates a quote with lines. Prices are resolved from the customer's pricing tier when `unit_price` is omitted and a `product_id` is given; totals are computed server-side.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.create`.\n\nBody fields (all optional): `customer_id`, `reference`, `currency_code` (3-letter), `sales_rep_id`, `store_id`, `sales_channel_id`, `customer_po_number`, `memo_for_customer`, `cover_letter`, `terms`, `valid_until` (date), `is_tax_included` (bool), `tax_rate_id`, and `lines[]`.\n\nEach line: `product_id`, `sku`, `description`, `quantity`, `unit_price`, `discount_type` (none|percentage|fixed_amount), `discount_value`, `tax_rate_id`, `line_type` (standard|optional|single_select), `select_group`.","body":{"mode":"raw","raw":"{\n  \"customer_id\": 88,\n  \"currency_code\": \"USD\",\n  \"customer_po_number\": \"PO-9000\",\n  \"memo_for_customer\": \"Thanks for your business\",\n  \"terms\": \"Net 30\",\n  \"valid_until\": \"2026-06-25\",\n  \"is_tax_included\": false,\n  \"tax_rate_id\": 3,\n  \"lines\": [\n    {\n      \"product_id\": 501,\n      \"quantity\": 2,\n      \"unit_price\": 100,\n      \"discount_type\": \"percentage\",\n      \"discount_value\": 10,\n      \"tax_rate_id\": 3,\n      \"line_type\": \"standard\"\n    },\n    {\n      \"description\": \"Optional add-on\",\n      \"quantity\": 1,\n      \"unit_price\": 25,\n      \"line_type\": \"optional\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes","host":["{{baseUrl}}"],"path":["api","quotes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Get Quote","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Returns a single quote with its lines and customer summary.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Quote","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Updates a quote's header fields and recomputes totals. Partial payload — only provided fields are applied. The quote must be editable (status draft or revised).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.\n\nUpdatable fields: `customer_id`, `reference`, `currency_code`, `sales_rep_id`, `store_id`, `sales_channel_id`, `customer_po_number`, `memo_for_customer`, `cover_letter`, `terms`, `valid_until`, `is_tax_included`, `tax_rate_id`, `deposit_type` (none|percent|fixed), `deposit_value`.","body":{"mode":"raw","raw":"{\n  \"customer_po_number\": \"PO-9100\",\n  \"terms\": \"Net 45\",\n  \"valid_until\": \"2026-07-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Quote","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Soft-deletes a quote and cascades to its lines, versions, and events.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.delete`."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/quotes/{quote}","host":["{{baseUrl}}"],"path":["api","quotes",":quote"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Quote deleted.\"\n}"}]},{"name":"Add Quote Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Adds a line to an editable quote and recomputes totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.\n\nBody: `product_id`, `sku`, `description`, `quantity`, `unit_price`, `discount_type` (none|percentage|fixed_amount), `discount_value`, `tax_rate_id`, `line_type` (standard|optional|single_select), `select_group`.","body":{"mode":"raw","raw":"{\n  \"product_id\": 501,\n  \"quantity\": 3,\n  \"unit_price\": 30,\n  \"discount_type\": \"none\",\n  \"line_type\": \"standard\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Quote Line","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line"],"variable":[{"key":"quote","value":"12","description":"Quote ID"},{"key":"line","value":"1","description":"Quote line ID"}]},"description":"Update a single quote line. All fields optional — send only what changed. Editing quantity/unit_price/discount recalculates the quote totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: quantity (numeric), unit_price (numeric), description (string|null), warehouse_id (int|null), discount_type (none|percentage|fixed_amount), discount_value (numeric|null), tax_rate_id (int|null, exists:tax_rates — per-line tax override).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"quantity\": 5,\n  \"unit_price\": 20,\n  \"description\": \"Optional line description\",\n  \"warehouse_id\": 3,\n  \"discount_type\": \"percentage\",\n  \"discount_value\": 10,\n  \"tax_rate_id\": 2,\n  \"nominal_code_id\": 8,\n  \"financial_line_type_id\": 3,\n  \"proration_strategy\": \"revenue_based\",\n  \"allocate_to_products\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Remove Quote Line","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line"],"variable":[{"key":"quote","value":"12","description":"Quote ID"},{"key":"line","value":"1","description":"Quote line ID"}]},"description":"Removes a line from an editable quote and recomputes totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line"],"variable":[{"key":"quote","value":"12","description":"Quote ID"},{"key":"line","value":"1","description":"Quote line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Send Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/send","host":["{{baseUrl}}"],"path":["api","quotes",":quote","send"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Snapshots an immutable version, issues a public token, sets status to `sent`, and stamps `sent_at` / `valid_until`. The quote must be editable.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.send`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/send","host":["{{baseUrl}}"],"path":["api","quotes",":quote","send"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"sent\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": \"8f2c1a...64chars\",\n    \"accepted_version_id\": null,\n    \"sent_at\": \"2026-06-18T10:05:00.000000Z\",\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Accept Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/accept","host":["{{baseUrl}}"],"path":["api","quotes",":quote","accept"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Marks an issued quote `accepted` and pins the accepted version (price-lock source for conversion).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.accept`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/accept","host":["{{baseUrl}}"],"path":["api","quotes",":quote","accept"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"accepted\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": \"8f2c1a...64chars\",\n    \"accepted_version_id\": 1,\n    \"sent_at\": \"2026-06-18T10:05:00.000000Z\",\n    \"viewed_at\": null,\n    \"accepted_at\": \"2026-06-18T10:10:00.000000Z\",\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Decline Quote","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/decline","host":["{{baseUrl}}"],"path":["api","quotes",":quote","decline"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Marks a quote `declined` with an optional reason.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.decline`.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Budget\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/decline","host":["{{baseUrl}}"],"path":["api","quotes",":quote","decline"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"declined\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": \"8f2c1a...64chars\",\n    \"accepted_version_id\": null,\n    \"sent_at\": \"2026-06-18T10:05:00.000000Z\",\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": \"2026-06-18T10:10:00.000000Z\",\n    \"declined_reason\": \"Budget\",\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Expire Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/expire","host":["{{baseUrl}}"],"path":["api","quotes",":quote","expire"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Marks a quote `expired`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/expire","host":["{{baseUrl}}"],"path":["api","quotes",":quote","expire"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Revise Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/revise","host":["{{baseUrl}}"],"path":["api","quotes",":quote","revise"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Reopens an issued/expired quote as a new editable working copy (status `revised`).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/revise","host":["{{baseUrl}}"],"path":["api","quotes",":quote","revise"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-06-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Convert Quote","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/convert","host":["{{baseUrl}}"],"path":["api","quotes",":quote","convert"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Converts an accepted quote into a draft sales order with price-locked lines (line unit prices are copied verbatim from the frozen quote lines — never re-resolved against the catalog). The order is stamped with `quote_id` and the accepted `quote_version_id`.\n\nPass `line_ids` to convert a subset (partial/progressive conversion — one quote may yield several orders); omit it to convert all selected, not-yet-converted lines. Returns the quote plus the created `sales_order_id`/`sales_order_number`.\n\nAuthentication: Requires Bearer token. Permission: `quotes.convert`.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/convert","host":["{{baseUrl}}"],"path":["api","quotes",":quote","convert"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"status\": \"converted\"\n  },\n  \"sales_order_id\": 7788,\n  \"sales_order_number\": \"SO-7788\"\n}"}]},{"name":"Create Sales Order from Quote","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/create-order","host":["{{baseUrl}}"],"path":["api","quotes",":quote","create-order"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Creates a draft sales order from an accepted quote with price-locked lines (line unit prices are copied verbatim from the frozen quote lines — never re-resolved against the catalog). The quote is the independent source record and is never consumed; the order is stamped with quote_id + the accepted quote_version_id for provenance. Pass line_ids to order a subset (partial/progressive ordering — one quote may yield several orders). Requires Bearer token + the quotes.create-order permission. The quote must be in accepted status.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/create-order","host":["{{baseUrl}}"],"path":["api","quotes",":quote","create-order"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"status\": \"converted\"\n  },\n  \"sales_order_id\": 7788,\n  \"sales_order_number\": \"SO-7788\"\n}"}]},{"name":"Bulk Set Line Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/bulk-warehouse","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","bulk-warehouse"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Set the allocation warehouse on many product lines at once — the \"send the whole order from one warehouse\" convenience for large quotes.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody:\n- `warehouse_id` (int|null, exists:warehouses) — the target warehouse (null to clear).\n- `line_ids` (int[], optional) — the lines to update. **Omit `line_ids` to apply to every product line on the quote.** Revenue (product-less) lines are never affected.\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"line_ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/bulk-warehouse","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","bulk-warehouse"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"lines\": [],\n    \"sales_orders\": [\n      {\n        \"id\": 20,\n        \"sales_order_number\": \"SO-0002\"\n      }\n    ]\n  }\n}"}]},{"name":"Set Quote Inventory Allocation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/allocation","host":["{{baseUrl}}"],"path":["api","quotes",":quote","allocation"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Toggle whether the quote holds inventory, applying the side effect immediately so this is the single control for allocation:\n- `allocate=false` always RELEASES any stock the quote is currently holding.\n- `allocate=true` re-allocates now if the quote is already issued (sent/viewed); for a draft it only records intent, since allocation otherwise happens on send.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 (InvalidQuoteTransition) when the quote is in a terminal state (ordered/declined/expired).\n\nBody: `allocate` (boolean, required).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"allocate\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/allocation","host":["{{baseUrl}}"],"path":["api","quotes",":quote","allocation"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"status\": \"sent\",\n    \"allocate_inventory\": false,\n    \"lines\": [],\n    \"sales_orders\": [\n      {\n        \"id\": 20,\n        \"sales_order_number\": \"SO-0002\"\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Archive Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/bulk-archive","host":["{{baseUrl}}"],"path":["api","quotes","bulk-archive"]},"description":"Archives multiple quotes (sets `archived_at`). Archived quotes are hidden from the default list and reappear under `?archived=only`.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargets either an explicit list of quote IDs or every quote matching the current filters.\n\n**Two request-body modes:**\n- `{ \"ids\": [12, 13, 14] }` — act on these specific quotes.\n- `{ \"apply_to_all\": true, \"filters\": { \"status\": \"draft\" } }` — act on every quote matching the given filters (same filter keys as `GET /api/quotes`: `search`, `status`, `origin`, `customer_id`, `archived`, `filter_groups`, etc.).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/bulk-archive","host":["{{baseUrl}}"],"path":["api","quotes","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Archived 3 quote(s).\"\n}"}]},{"name":"Bulk Unarchive Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","quotes","bulk-unarchive"]},"description":"Restores multiple archived quotes (clears `archived_at`).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargets either an explicit list of quote IDs or every quote matching the current filters.\n\n**Two request-body modes:**\n- `{ \"ids\": [12, 13, 14] }` — act on these specific quotes.\n- `{ \"apply_to_all\": true, \"filters\": { \"status\": \"draft\" } }` — act on every quote matching the given filters (same filter keys as `GET /api/quotes`: `search`, `status`, `origin`, `customer_id`, `archived`, `filter_groups`, etc.).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","quotes","bulk-unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unarchived 3 quote(s).\"\n}"}]},{"name":"Bulk Delete Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/bulk-delete","host":["{{baseUrl}}"],"path":["api","quotes","bulk-delete"]},"description":"Soft-deletes multiple quotes. Releases any allocated inventory for quotes that opted into allocation.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargets either an explicit list of quote IDs or every quote matching the current filters.\n\n**Two request-body modes:**\n- `{ \"ids\": [12, 13, 14] }` — act on these specific quotes.\n- `{ \"apply_to_all\": true, \"filters\": { \"status\": \"draft\" } }` — act on every quote matching the given filters (same filter keys as `GET /api/quotes`: `search`, `status`, `origin`, `customer_id`, `archived`, `filter_groups`, etc.).\n\nAuthentication: Requires Bearer token. Permission: `quotes.delete`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/bulk-delete","host":["{{baseUrl}}"],"path":["api","quotes","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 3 quote(s).\"\n}"}]},{"name":"Bulk Send Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/bulk-send","host":["{{baseUrl}}"],"path":["api","quotes","bulk-send"]},"description":"Sends multiple quotes to their customers. Only quotes in a sendable (draft/revised) state are sent; the rest are skipped. Inventory is allocated for quotes that opted in. The response reports how many were sent vs. skipped.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargets either an explicit list of quote IDs or every quote matching the current filters.\n\n**Two request-body modes:**\n- `{ \"ids\": [12, 13, 14] }` — act on these specific quotes.\n- `{ \"apply_to_all\": true, \"filters\": { \"status\": \"draft\" } }` — act on every quote matching the given filters (same filter keys as `GET /api/quotes`: `search`, `status`, `origin`, `customer_id`, `archived`, `filter_groups`, etc.).\n\nAuthentication: Requires Bearer token. Permission: `quotes.send`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/bulk-send","host":["{{baseUrl}}"],"path":["api","quotes","bulk-send"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sent 2 quote(s), skipped 1.\",\n  \"data\": {\n    \"sent\": 2,\n    \"skipped\": 1\n  }\n}"}]},{"name":"Bulk Expire Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/bulk-expire","host":["{{baseUrl}}"],"path":["api","quotes","bulk-expire"]},"description":"Expires multiple quotes. Only issued (sent/viewed) quotes are expired; the rest are skipped. Allocated inventory is released. The response reports how many were expired vs. skipped.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nTargets either an explicit list of quote IDs or every quote matching the current filters.\n\n**Two request-body modes:**\n- `{ \"ids\": [12, 13, 14] }` — act on these specific quotes.\n- `{ \"apply_to_all\": true, \"filters\": { \"status\": \"draft\" } }` — act on every quote matching the given filters (same filter keys as `GET /api/quotes`: `search`, `status`, `origin`, `customer_id`, `archived`, `filter_groups`, etc.).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/bulk-expire","host":["{{baseUrl}}"],"path":["api","quotes","bulk-expire"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Expired 2 quote(s), skipped 1.\",\n  \"data\": {\n    \"expired\": 2,\n    \"skipped\": 1\n  }\n}"}]},{"name":"Bulk Update Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/bulk-update","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","bulk-update"],"variable":[{"key":"quote","value":"12","description":"The quote ID."}]},"description":"Apply the same field changes to many lines at once (bulk-edit). Body: line_ids (int[], required) and any of discount_type (none|percentage|fixed_amount), discount_value (numeric|null), tax_rate_id (int|null). Recalculates totals.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"line_ids\": [\n    101,\n    102\n  ],\n  \"discount_type\": \"percentage\",\n  \"discount_value\": 10,\n  \"tax_rate_id\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/bulk-update","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","bulk-update"],"variable":[{"key":"quote","value":"12","description":"The quote ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"lines\": []\n  }\n}"}]},{"name":"Convert Line to Revenue","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}/convert-to-revenue","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line","convert-to-revenue"],"variable":[{"key":"quote","value":"12","description":"The quote ID."},{"key":"line","value":"101","description":"The line ID."}]},"description":"Strip the product from a line so it becomes a revenue (product-less) line, releasing any inventory it held. Description, quantity and price are preserved.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}/convert-to-revenue","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line","convert-to-revenue"],"variable":[{"key":"quote","value":"12","description":"The quote ID."},{"key":"line","value":"101","description":"The line ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"lines\": []\n  }\n}"}]},{"name":"Reorder Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/reorder","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","reorder"],"variable":[{"key":"quote","value":"12","description":"The quote ID."}]},"description":"Persist a new line ordering. Body: ordered_ids (int[], required) — line ids in the desired order. Lines not listed keep their relative order after the listed set.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token. Permission: `quotes.update`.","body":{"mode":"raw","raw":"{\n  \"ordered_ids\": [\n    103,\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/reorder","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines","reorder"],"variable":[{"key":"quote","value":"12","description":"The quote ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"lines\": []\n  }\n}"}]},{"name":"Get Quote Analytics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/analytics","host":["{{baseUrl}}"],"path":["api","quotes","analytics"]},"description":"Aggregate quote analytics for a date range: status counts, issued count, win rate, quote-to-order conversion rate, average quote value, average discount percentage, average days to acceptance, and the number of issued quotes expiring within the next 7 days.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n`win_rate` is the percentage of decided quotes (accepted + declined + expired + ordered) that were won (accepted or ordered). `conversion_rate` is the percentage of issued quotes that converted to a sales order.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/quotes/analytics","host":["{{baseUrl}}"],"path":["api","quotes","analytics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 148,\n    \"by_status\": {\n      \"draft\": 22,\n      \"sent\": 41,\n      \"viewed\": 18,\n      \"accepted\": 30,\n      \"declined\": 12,\n      \"expired\": 9,\n      \"revised\": 4,\n      \"ordered\": 12\n    },\n    \"issued\": 122,\n    \"win_rate\": 66.67,\n    \"conversion_rate\": 9.84,\n    \"average_quote_value\": 1245.5,\n    \"average_discount_percent\": 7.25,\n    \"average_days_to_accept\": 3.4,\n    \"expiring_soon\": 6\n  }\n}"}]},{"name":"Duplicate Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/duplicate","host":["{{baseUrl}}"],"path":["api","quotes",":quote","duplicate"],"variable":[{"key":"quote","value":"12","description":"Quote ID to duplicate"}]},"description":"Clone a quote into a fresh editable draft. The duplicate gets a new quote number, `draft` status, and copies of the customer, addresses, terms, discounts, deposit settings, and every line. Lifecycle fields (sent/viewed/accepted timestamps, versions, acceptance records) are NOT copied.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the new draft quote.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/duplicate","host":["{{baseUrl}}"],"path":["api","quotes",":quote","duplicate"],"variable":[{"key":"quote","value":"12","description":"Quote ID to duplicate"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 13,\n    \"quote_number\": \"Q-000013\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-08-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Get Quote PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/pdf","host":["{{baseUrl}}"],"path":["api","quotes",":quote","pdf"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Render the quote as a PDF document using the tenant's quote template and return the file inline.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe response is binary PDF content (`Content-Type: application/pdf`, `Content-Disposition: inline; filename=\"quote-Q-000012.pdf\"`), not JSON.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/pdf","host":["{{baseUrl}}"],"path":["api","quotes",":quote","pdf"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.7 … binary PDF bytes …"}]},{"name":"Select Quote Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}/select","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line","select"],"variable":[{"key":"quote","value":"12","description":"Quote ID"},{"key":"line","value":"1","description":"Quote line ID"}]},"description":"Mark an optional or single-select quote line as selected or deselected. Selection controls which lines the customer is accepting and which lines convert to the sales order.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `is_selected` (required, boolean) — true to select the line, false to deselect it.\n\nReturns the full quote with recalculated totals. 404 when the line does not belong to the quote.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"is_selected\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/lines/{line}/select","host":["{{baseUrl}}"],"path":["api","quotes",":quote","lines",":line","select"],"variable":[{"key":"quote","value":"12","description":"Quote ID"},{"key":"line","value":"1","description":"Quote line ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-08-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"List Quote Comments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/comments","host":["{{baseUrl}}"],"path":["api","quotes",":quote","comments"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"List the quote's negotiation thread — comments left by staff and by the customer, oldest first. System entries (e.g. automatic status notes) are flagged with `is_system`.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/comments","host":["{{baseUrl}}"],"path":["api","quotes",":quote","comments"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41,\n      \"author_type\": \"staff\",\n      \"author_id\": 5,\n      \"body\": \"Updated the pricing on line 2 per our call.\",\n      \"attachment_path\": null,\n      \"is_system\": false,\n      \"created_at\": \"2026-06-19T09:12:00.000000Z\"\n    },\n    {\n      \"id\": 42,\n      \"author_type\": \"customer\",\n      \"author_id\": null,\n      \"body\": \"Looks good — can you extend the validity to end of month?\",\n      \"attachment_path\": null,\n      \"is_system\": false,\n      \"created_at\": \"2026-06-19T15:40:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Add Quote Comment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/comments","host":["{{baseUrl}}"],"path":["api","quotes",":quote","comments"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Add a staff comment to the quote's negotiation thread. The comment is attributed to the authenticated user.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `body` (required, string, max 5000) — the comment text.\n- `attachment_path` (optional, string, nullable) — path of a previously uploaded attachment to link to the comment.\n\nReturns 201 with the created comment.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"body\": \"Updated the pricing on line 2 per our call.\",\n  \"attachment_path\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/comments","host":["{{baseUrl}}"],"path":["api","quotes",":quote","comments"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 43,\n    \"author_type\": \"staff\",\n    \"author_id\": 5,\n    \"body\": \"Updated the pricing on line 2 per our call.\",\n    \"attachment_path\": null,\n    \"is_system\": false,\n    \"created_at\": \"2026-06-20T10:02:00.000000Z\"\n  }\n}"}]},{"name":"Record Quote Acceptance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/record-acceptance","host":["{{baseUrl}}"],"path":["api","quotes",":quote","record-acceptance"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Record the customer's acceptance of an issued quote (sent or viewed status) together with the signer's details, and transition the quote to `accepted`. The signer's IP address and user agent are captured automatically from the request.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nWhen the quote has optional or single-select lines, `selected_line_ids` pins exactly which lines were accepted — an explicit empty array means \"no optional add-ons\" and deselects previously selected optional lines. Omit the field to keep the current selection.\n\n**Body fields:**\n- `signer_name` (required, string, max 255) — name of the person accepting.\n- `signature_data` (optional, string, nullable) — captured signature image data.\n- `selected_line_ids` (optional, array of integers, nullable) — the accepted optional/single-select line IDs.\n\nReturns the accepted quote. 422 when the quote is not in an accepting state.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"signer_name\": \"Jane Doe\",\n  \"signature_data\": null,\n  \"selected_line_ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/record-acceptance","host":["{{baseUrl}}"],"path":["api","quotes",":quote","record-acceptance"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"accepted\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-08-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": 3,\n    \"sent_at\": \"2026-06-18T12:00:00.000000Z\",\n    \"viewed_at\": null,\n    \"accepted_at\": \"2026-06-20T16:30:00.000000Z\",\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Record Quote Deposit Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/deposit-payment","host":["{{baseUrl}}"],"path":["api","quotes",":quote","deposit-payment"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Record a deposit payment against the quote — used for manual/offline payments taken by staff. Payment gateway webhooks record their own payments through the same mechanism.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `amount` (optional, numeric, min 0) — payment amount; defaults to the quote's calculated deposit amount.\n- `reference` (optional, string, max 255) — external payment reference.\n- `provider` (optional, string, max 64) — payment provider label; defaults to `manual`.\n\nReturns 201 with the recorded payment's id, amount, and status.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"amount\": 99,\n  \"reference\": \"CHK-2201\",\n  \"provider\": \"manual\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/deposit-payment","host":["{{baseUrl}}"],"path":["api","quotes",":quote","deposit-payment"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"payment_id\": 77,\n    \"amount\": 99,\n    \"status\": \"paid\"\n  }\n}"}]},{"name":"Sync Quote to Accounting","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/sync-accounting","host":["{{baseUrl}}"],"path":["api","quotes",":quote","sync-accounting"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Push the quote to the connected accounting integration (e.g. as an estimate) and return the accounting reference. When no accounting integration is connected or the sync is skipped, `synced` is false and `reference` is null.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/sync-accounting","host":["{{baseUrl}}"],"path":["api","quotes",":quote","sync-accounting"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"synced\": true,\n    \"reference\": \"EST-1042\"\n  }\n}"}]},{"name":"Request Quote Discount Approval","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/request-approval","host":["{{baseUrl}}"],"path":["api","quotes",":quote","request-approval"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Request managerial approval for the quote's current discount level. The quote's totals are recalculated, the effective discount percentage is captured, and a pending approval is created attributed to the authenticated user.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nA quote can only have one pending approval at a time — requesting again while one is pending returns an error. Resolve it with Approve Quote Discount or Reject Quote Discount.\n\n**Response fields:** `approval_id`, `status` (`pending`), `discount_percent` (the discount level captured for review).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/request-approval","host":["{{baseUrl}}"],"path":["api","quotes",":quote","request-approval"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"approval_id\": 9,\n    \"status\": \"pending\",\n    \"discount_percent\": 12.5\n  }\n}"}]},{"name":"Approve Quote Discount","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/approve-discount","host":["{{baseUrl}}"],"path":["api","quotes",":quote","approve-discount"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Approve the quote's pending discount approval. The approval is marked approved and attributed to the authenticated user, and the refreshed quote is returned.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n404 when the quote has no pending approval.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/approve-discount","host":["{{baseUrl}}"],"path":["api","quotes",":quote","approve-discount"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-08-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Reject Quote Discount","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/quotes/{quote}/reject-discount","host":["{{baseUrl}}"],"path":["api","quotes",":quote","reject-discount"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]},"description":"Reject the quote's pending discount approval, optionally recording a reason. The approval is marked rejected and the refreshed quote is returned.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `reason` (optional, string, max 1000, nullable) — why the discount was rejected.\n\n404 when the quote has no pending approval.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Discount exceeds the allowed margin for this customer tier.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/quotes/{quote}/reject-discount","host":["{{baseUrl}}"],"path":["api","quotes",":quote","reject-discount"],"variable":[{"key":"quote","value":"12","description":"Quote ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"quote_number\": \"Q-000012\",\n    \"reference\": null,\n    \"status\": \"draft\",\n    \"origin\": \"staff\",\n    \"customer_id\": 88,\n    \"customer\": {\n      \"id\": 88,\n      \"name\": \"Acme Corp\",\n      \"company\": \"Acme Corp\"\n    },\n    \"sales_rep_id\": null,\n    \"store_id\": null,\n    \"sales_channel_id\": null,\n    \"currency_code\": \"USD\",\n    \"customer_po_number\": \"PO-9000\",\n    \"memo_for_customer\": \"Thanks for your business\",\n    \"cover_letter\": null,\n    \"terms\": \"Net 30\",\n    \"valid_until\": \"2026-08-25T00:00:00.000000Z\",\n    \"is_tax_included\": false,\n    \"tax_rate_id\": 3,\n    \"subtotal\": 200,\n    \"line_discount_total\": 20,\n    \"order_discount_total\": 0,\n    \"discount_total\": 20,\n    \"tax_total\": 18,\n    \"total\": 198,\n    \"deposit_type\": \"none\",\n    \"deposit_value\": null,\n    \"quote_token\": null,\n    \"accepted_version_id\": null,\n    \"sent_at\": null,\n    \"viewed_at\": null,\n    \"accepted_at\": null,\n    \"declined_at\": null,\n    \"declined_reason\": null,\n    \"expired_at\": null,\n    \"converted_at\": null,\n    \"lines\": [\n      {\n        \"id\": 1,\n        \"product_id\": 501,\n        \"sku\": \"WIDGET-1\",\n        \"description\": \"Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 100,\n        \"unit_cost\": 60,\n        \"discount_type\": \"percentage\",\n        \"discount_value\": 10,\n        \"tax_rate_id\": 3,\n        \"line_type\": \"standard\",\n        \"select_group\": null,\n        \"is_selected\": true,\n        \"subtotal\": 200,\n        \"sort\": 0\n      }\n    ],\n    \"created_at\": \"2026-06-18T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T10:00:00.000000Z\"\n  }\n}"}]}]},{"name":"POS / Register","item":[{"name":"Get Current Register Session","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/register-session/current","host":["{{baseUrl}}"],"path":["api","pos","register-session","current"]},"description":"Returns the authenticated user's currently OPEN register session, or `null` if they have none. Use this on POS load to resume an in-progress shift.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token (PAT).\n\nRequires permission: pos.operate (when granular permissions are enabled)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/register-session/current","host":["{{baseUrl}}"],"path":["api","pos","register-session","current"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"Downtown Flagship\",\n    \"opened_by_user_id\": 1,\n    \"opened_by_name\": \"Jane Cashier\",\n    \"opened_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"opening_float\": \"150.0000\",\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"closed_by_user_id\": null,\n    \"closed_at\": null,\n    \"cash_sales_total\": \"0.0000\",\n    \"expected_cash\": null,\n    \"counted_cash\": null,\n    \"cash_variance\": null,\n    \"notes\": null,\n    \"created_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"updated_at\": \"2026-06-19T14:02:11.000000Z\"\n  }\n}"}]},{"name":"Open Register Session","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/register-sessions","host":["{{baseUrl}}"],"path":["api","pos","register-sessions"]},"description":"Opens a register session (shift) for the authenticated user, tied to a warehouse (the register's stock location). The opening float is the starting cash in the drawer.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nA user may only have ONE open session at a time — opening a second returns 422.\n\nBody fields:\n- `warehouse_id` (integer, required) — the register's warehouse (must exist).\n- `opening_float` (numeric, required, min 0) — starting cash in the drawer.\n\nAuthentication: Requires Bearer token (PAT).\n\nRequires permission: pos.operate (when granular permissions are enabled).","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"opening_float\": 150\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pos/register-sessions","host":["{{baseUrl}}"],"path":["api","pos","register-sessions"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"Downtown Flagship\",\n    \"opened_by_user_id\": 1,\n    \"opened_by_name\": \"Jane Cashier\",\n    \"opened_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"opening_float\": \"150.0000\",\n    \"status\": \"open\",\n    \"status_label\": \"Open\",\n    \"closed_by_user_id\": null,\n    \"closed_at\": null,\n    \"cash_sales_total\": \"0.0000\",\n    \"expected_cash\": null,\n    \"counted_cash\": null,\n    \"cash_variance\": null,\n    \"notes\": null,\n    \"created_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"updated_at\": \"2026-06-19T14:02:11.000000Z\"\n  }\n}"}]},{"name":"Close Register Session","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/register-sessions/{registerSession}/close","host":["{{baseUrl}}"],"path":["api","pos","register-sessions",":registerSession","close"],"variable":[{"key":"registerSession","value":"12","description":"Register session ID"}]},"description":"Closes a register session and performs cash reconciliation.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nExpected cash = opening float + cash takings for the shift. Variance = counted cash − expected cash (positive = over, negative = short). The response returns the computed `expected_cash`, `counted_cash` and `cash_variance` for the X/Z report.\n\nBody fields:\n- `counted_cash` (numeric, required, min 0) — cash counted in the drawer at close.\n- `notes` (string, optional, max 1000).\n\nReturns 422 if the session is already closed.\n\nAuthentication: Requires Bearer token (PAT).\n\nRequires permission: pos.operate (when granular permissions are enabled).","body":{"mode":"raw","raw":"{\n  \"counted_cash\": 575,\n  \"notes\": \"End of day — over by 5.02\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pos/register-sessions/{registerSession}/close","host":["{{baseUrl}}"],"path":["api","pos","register-sessions",":registerSession","close"],"variable":[{"key":"registerSession","value":"12","description":"Register session ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"Downtown Flagship\",\n    \"opened_by_user_id\": 1,\n    \"opened_by_name\": \"Jane Cashier\",\n    \"opened_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"opening_float\": \"150.0000\",\n    \"status\": \"closed\",\n    \"status_label\": \"Closed\",\n    \"closed_by_user_id\": 1,\n    \"closed_at\": \"2026-06-19T22:10:00.000000Z\",\n    \"cash_sales_total\": \"419.9800\",\n    \"expected_cash\": \"569.9800\",\n    \"counted_cash\": \"575.0000\",\n    \"cash_variance\": \"5.0200\",\n    \"notes\": \"End of day — over by 5.02\",\n    \"created_at\": \"2026-06-19T14:02:11.000000Z\",\n    \"updated_at\": \"2026-06-19T14:02:11.000000Z\"\n  }\n}"}]},{"name":"Ring Up Sale (Checkout)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/checkout","host":["{{baseUrl}}"],"path":["api","pos","checkout"]},"description":"Ring up a sale: cart lines + tender(s) become a paid, fully-fulfilled sales order plus a POS transaction.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nRequest body fields:\n- `pos_register_session_id` (integer, required) — the open session to ring against (must exist in `pos_register_sessions`).\n- `tender_type` (enum, required) — one of `cash`, `card`, `store_credit`, `split`.\n- `amount_tendered` (numeric, required, min 0) — amount the customer handed over (for a single tender; may exceed the total for cash, yielding change).\n- `customer_id` (integer, nullable) — attached customer; REQUIRED when `tender_type` is `store_credit` (store credit debits the customer's wallet).\n- `payment_source_id` (string, nullable, max 255) — tokenized card source (Web Payments SDK nonce / Terminal ref); REQUIRED when `tender_type` is `card`.\n- `tax_rate_id` (integer, nullable) — optional tax rate applied to every line (must exist in `tax_rates`).\n- `apply_customer_pricing_tier` (boolean, nullable) — opt-in: re-price each line from the customer's assigned pricing tier instead of the register-submitted `unit_price`. Defaults to false.\n- `idempotency_key` (string, nullable, max 255) — client-supplied stable token; a retried checkout re-uses the same processor idempotency key so a timed-out sale never double-charges.\n- `tenders` (array, nullable) — optional split tender; when present, overrides the single `tender_type`/`amount_tendered` and each entry is settled independently.\n  - `tenders.*.type` (enum, required with `tenders`) — `cash`, `card`, `store_credit`, or `split`.\n  - `tenders.*.amount` (numeric, required with `tenders`, min 0) — amount for this tender.\n  - `tenders.*.payment_source_id` (string, nullable, max 255) — tokenized card source for a card tender.\n- `lines` (array, required, min 1) — the cart.\n  - `lines.*.product_id` (integer, required) — must exist in `products`.\n  - `lines.*.quantity` (numeric, required, > 0).\n  - `lines.*.unit_price` (numeric, required, min 0).\n\nFor a simple single-tender sale, omit `tenders`, set `tender_type` to `cash`/`card`/`store_credit`, and set `amount_tendered`.\n\nReturns 201 with the created POS transaction.\n\n**Gift card tender:** set `tender_type` to `gift_card` with a top-level `gift_card_code`, or include a split tender `{\"type\":\"gift_card\",\"amount\":..,\"gift_card_code\":\"..\"}`. One gift card per sale; the card is validated and debited atomically inside the sale (rolls back on a concurrent drain). Store-credit and gift-card tenders settle exactly (no change).\n\n**On-account tender:** set `tender_type` to `on_account` (or add a split tender `{\"type\":\"on_account\",\"amount\":..}`) to charge the sale to the attached customer's house account. Requires a customer with a house account enabled and enough credit-limit headroom; the sale is recorded as PAID (settled on account) and the customer's house-account balance increases.\n\n**Selling gift cards (gift_cards_to_sell):** Each entry SELLS a new gift card to the customer. It is added to the order as a non-product line posted to the Gift Card Liability nominal (Dr Cash / Cr Liability — never revenue, never taxed) and the card is activated for the paid amount on checkout. `amount` is required; `code` auto-generates when omitted. Requires the Gift Card Liability nominal to be configured (422 otherwise). `lines` is OPTIONAL when the sale is purely gift-card sales.","body":{"mode":"raw","raw":"{\n  \"pos_register_session_id\": 42,\n  \"tender_type\": \"cash\",\n  \"amount_tendered\": 75,\n  \"customer_id\": 88,\n  \"payment_source_id\": null,\n  \"saved_payment_method_id\": null,\n  \"tax_rate_id\": 5,\n  \"apply_customer_pricing_tier\": false,\n  \"idempotency_key\": \"cart-6f1e9c2a-3b7d-4a1e-9f0c-2d5b8e4a7c11\",\n  \"gift_card_code\": null,\n  \"loyalty_points_to_redeem\": 200,\n  \"gift_cards_to_sell\": [\n    {\n      \"amount\": 50,\n      \"code\": \"GIFT-2026-0007\",\n      \"security_code\": null,\n      \"is_digital\": false,\n      \"recipient_name\": \"Jane Doe\",\n      \"recipient_email\": \"jane@example.com\",\n      \"expires_at\": null\n    }\n  ],\n  \"lines\": [\n    {\n      \"product_id\": 1201,\n      \"quantity\": 1,\n      \"unit_price\": 25\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pos/checkout","host":["{{baseUrl}}"],"path":["api","pos","checkout"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1001,\n    \"pos_register_session_id\": 42,\n    \"sales_order_id\": 55231,\n    \"sales_order_number\": \"POS-1001\",\n    \"customer_id\": 88,\n    \"customer_name\": \"Walk-in Customer\",\n    \"cashier_user_id\": 7,\n    \"cashier_name\": \"Jane Cashier\",\n    \"tender_type\": \"cash\",\n    \"tender_type_label\": \"Cash\",\n    \"subtotal\": 100,\n    \"tax_total\": 8.25,\n    \"discount_total\": 0,\n    \"total\": 108.25,\n    \"amount_tendered\": 120,\n    \"change_due\": 11.75,\n    \"is_refunded\": false,\n    \"refunded_at\": null,\n    \"refund_amount\": null,\n    \"refund_reference\": null,\n    \"created_at\": \"2026-07-06T14:22:00.000000Z\"\n  }\n}"}]},{"name":"Refund Transaction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/refund","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","refund"],"variable":[{"key":"posTransaction","value":"1000","description":"The POS transaction (sale) id to refund."}]},"description":"Refund a completed POS sale in full — credit and restock the items, then either refund the original tenders (card via processor, cash at the drawer) or top up the customer's store-credit wallet.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.refund`.\n\nRequest body fields:\n- `refund_to` (enum, nullable) — `original` (default; back to the original tenders) or `store_credit` (top up the attached customer's wallet). Store credit requires a customer on the sale (enforced server-side). Omitting the field defaults to `original`.\n\nRefunds are serialized under a row lock so a duplicate refund aborts. Returns 200 with the updated transaction (`is_refunded` true) and a message.","body":{"mode":"raw","raw":"{\n  \"refund_to\": \"original\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/refund","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","refund"],"variable":[{"key":"posTransaction","value":"1000","description":"The POS transaction (sale) id to refund."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1000,\n    \"pos_register_session_id\": 42,\n    \"sales_order_id\": 55230,\n    \"sales_order_number\": \"POS-1000\",\n    \"customer_id\": 88,\n    \"customer_name\": \"Walk-in Customer\",\n    \"cashier_user_id\": 7,\n    \"cashier_name\": \"Jane Cashier\",\n    \"tender_type\": \"card\",\n    \"tender_type_label\": \"Card\",\n    \"subtotal\": 45,\n    \"tax_total\": 3.71,\n    \"discount_total\": 0,\n    \"total\": 48.71,\n    \"amount_tendered\": 48.71,\n    \"change_due\": 0,\n    \"is_refunded\": true,\n    \"refunded_at\": \"2026-07-06T15:10:00.000000Z\",\n    \"refund_amount\": 48.71,\n    \"refund_reference\": \"re_3Pabc1EF\",\n    \"created_at\": \"2026-07-06T13:05:00.000000Z\"\n  },\n  \"message\": \"Sale refunded — credited and restocked.\"\n}"}]},{"name":"Get Receipt","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/receipt","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","receipt"],"variable":[{"key":"posTransaction","value":"1001","description":"The POS transaction (sale) id."}]},"description":"Return the printable receipt for a POS sale — assembled from the transaction, its sales order lines, and the register session.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nResponse `data` includes business/register/cashier info, customer contact, line items (sku, name, quantity, unit_price, line_total), monetary totals, tax-exemption flags, tender info, and refund status."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/receipt","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","receipt"],"variable":[{"key":"posTransaction","value":"1001","description":"The POS transaction (sale) id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"transaction_id\": 1001,\n    \"business_name\": \"Acme Retail\",\n    \"register\": \"Downtown Store\",\n    \"cashier\": \"Jane Cashier\",\n    \"sales_order_number\": \"POS-1001\",\n    \"customer_id\": 88,\n    \"customer_name\": \"Walk-in Customer\",\n    \"customer_email\": \"customer@example.com\",\n    \"customer_phone\": \"+1-555-0100\",\n    \"sold_at\": \"2026-07-06T14:22:00.000000Z\",\n    \"lines\": [\n      {\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 25,\n        \"line_total\": 50\n      },\n      {\n        \"sku\": \"GADGET-050\",\n        \"name\": \"Deluxe Gadget\",\n        \"quantity\": 1,\n        \"unit_price\": 50,\n        \"line_total\": 50\n      }\n    ],\n    \"subtotal\": 100,\n    \"tax_total\": 8.25,\n    \"discount_total\": 0,\n    \"tax_exempt\": false,\n    \"tax_exemption_reference\": null,\n    \"total\": 108.25,\n    \"tender_type\": \"cash\",\n    \"tender_type_label\": \"Cash\",\n    \"amount_tendered\": 120,\n    \"change_due\": 11.75,\n    \"is_refunded\": false,\n    \"refunded_at\": null,\n    \"refund_amount\": null\n  }\n}"}]},{"name":"List Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/transactions","host":["{{baseUrl}}"],"path":["api","pos","transactions"]},"description":"Paginated POS transaction (sales) history.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nFilters (Spatie QueryBuilder, all optional):\n- `filter[pos_register_session_id]` — exact register session id.\n- `filter[tender_type]` — exact tender type (cash, card, store_credit, split).\n- `filter[refunded]` — boolean; true = refunded only, false = non-refunded only.\n- `filter[date_from]` / `filter[date_to]` — created_at date range (Y-m-d).\n\nSorts: `id`, `total`, `created_at` (prefix `-` for DESC). Default sort: `-created_at`.\nPagination: `page` (default 1), `per_page` (default 15). Response includes standard Laravel pagination metadata."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/transactions","host":["{{baseUrl}}"],"path":["api","pos","transactions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"pos_register_session_id\": 42,\n      \"sales_order_id\": 55231,\n      \"sales_order_number\": \"POS-1001\",\n      \"customer_id\": null,\n      \"customer_name\": null,\n      \"cashier_user_id\": 7,\n      \"cashier_name\": \"Jane Cashier\",\n      \"tender_type\": \"cash\",\n      \"tender_type_label\": \"Cash\",\n      \"subtotal\": 100,\n      \"tax_total\": 8.25,\n      \"discount_total\": 0,\n      \"total\": 108.25,\n      \"amount_tendered\": 120,\n      \"change_due\": 11.75,\n      \"is_refunded\": false,\n      \"refunded_at\": null,\n      \"refund_amount\": null,\n      \"refund_reference\": null,\n      \"created_at\": \"2026-07-06T14:22:00.000000Z\"\n    },\n    {\n      \"id\": 1000,\n      \"pos_register_session_id\": 42,\n      \"sales_order_id\": 55230,\n      \"sales_order_number\": \"POS-1000\",\n      \"customer_id\": null,\n      \"customer_name\": null,\n      \"cashier_user_id\": 7,\n      \"cashier_name\": \"Jane Cashier\",\n      \"tender_type\": \"card\",\n      \"tender_type_label\": \"Card\",\n      \"subtotal\": 45,\n      \"tax_total\": 3.71,\n      \"discount_total\": 0,\n      \"total\": 48.71,\n      \"amount_tendered\": 48.71,\n      \"change_due\": 0,\n      \"is_refunded\": true,\n      \"refunded_at\": \"2026-07-06T15:10:00.000000Z\",\n      \"refund_amount\": 48.71,\n      \"refund_reference\": \"re_3Pabc0EF\",\n      \"created_at\": \"2026-07-06T13:05:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/pos/transactions?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/pos/transactions?page=4\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/pos/transactions?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/pos/transactions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 52\n}"}]},{"name":"Get POS Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/settings","host":["{{baseUrl}}"],"path":["api","pos","settings"]},"description":"Return the register's operational settings. Requires a Bearer token with `pos.operate`.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nIncludes the master `enabled` flag, the `require_customer` and `auto_print_receipt` behaviour toggles, the active card `payment_processor` (square|stripe), the Square `square_location_id`, and the list of `available_processors`. The admin-facing toggles are also editable via `PUT /api/v2/settings/pos`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/settings","host":["{{baseUrl}}"],"path":["api","pos","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"require_customer\": false,\n    \"auto_print_receipt\": false,\n    \"payment_processor\": \"square\",\n    \"square_location_id\": \"L7X8Y9Z0ABCDE\",\n    \"available_processors\": [\n      {\n        \"value\": \"square\",\n        \"label\": \"Square\"\n      },\n      {\n        \"value\": \"stripe\",\n        \"label\": \"Stripe\"\n      }\n    ]\n  }\n}"}]},{"name":"Update POS Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/settings","host":["{{baseUrl}}"],"path":["api","pos","settings"]},"description":"Update the register settings. Requires a Bearer token with `pos.manage`.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\n- `payment_processor` (required) — `square` or `stripe`.\n- `square_location_id` (optional, nullable) — the Square location the Web Payments SDK initialises against.\n\nThe admin toggles (`enabled`, `require_customer`, `auto_print_receipt`) are managed via `PUT /api/v2/settings/pos`; this endpoint focuses on the operational card-processor config.","body":{"mode":"raw","raw":"{\n  \"enabled\": true,\n  \"require_customer\": false,\n  \"auto_print_receipt\": true,\n  \"payment_processor\": \"square\",\n  \"square_location_id\": \"L7X8Y9Z0ABCDE\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/pos/settings","host":["{{baseUrl}}"],"path":["api","pos","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"require_customer\": false,\n    \"auto_print_receipt\": true,\n    \"payment_processor\": \"square\",\n    \"square_location_id\": \"L7X8Y9Z0ABCDE\",\n    \"available_processors\": [\n      {\n        \"value\": \"square\",\n        \"label\": \"Square\"\n      },\n      {\n        \"value\": \"stripe\",\n        \"label\": \"Stripe\"\n      }\n    ]\n  },\n  \"message\": \"POS settings updated.\"\n}"}]},{"name":"Get Payment Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/payment-config","host":["{{baseUrl}}"],"path":["api","pos","payment-config"]},"description":"Return the active processor's public web-payments config that the in-browser SDK needs to render a card form. No secrets are returned.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.operate`.\n\nFor Square: `processor`, `application_id`, `location_id`, `environment` (so the register can load the Web Payments SDK and tokenize a card client-side).\nFor Stripe: `processor`, `publishable_key`, `stripe_account` (Stripe.js Elements uses both, since card payments are direct charges on the tenant's connected account)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/payment-config","host":["{{baseUrl}}"],"path":["api","pos","payment-config"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processor\": \"square\",\n    \"application_id\": \"sandbox-sq0idb-Ab12Cd34Ef56Gh78Ij90Kl\",\n    \"location_id\": \"L7X8Y9Z0ABCDE\",\n    \"environment\": \"sandbox\"\n  }\n}"}]},{"name":"List Square Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/pos/square/locations","host":["{{baseUrl}}"],"path":["api","pos","square","locations"]},"description":"List the merchant's Square locations, for the settings location picker. Returns an empty array if Square is unreachable or not configured.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\nPermission: `pos.manage`.\n\nEach location: `id`, `name`, `status`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/pos/square/locations","host":["{{baseUrl}}"],"path":["api","pos","square","locations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"L7X8Y9Z0ABCDE\",\n      \"name\": \"Downtown Store\",\n      \"status\": \"ACTIVE\"\n    },\n    {\n      \"id\": \"LMNOP1234567Q\",\n      \"name\": \"Warehouse Outlet\",\n      \"status\": \"ACTIVE\"\n    }\n  ]\n}"}]},{"name":"Send POS Receipt (E-Receipt)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/receipt/send","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","receipt","send"],"variable":[{"key":"posTransaction","value":"88","description":"POS transaction ID"}]},"description":"Delivers the POS sale's e-receipt to an ad-hoc email and/or phone target and records the marketing opt-in captured at the register. Requires permission: pos.operate.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nThe target is captured ad-hoc — it is NOT read from the customer's CRM record — so a walk-in can get an e-receipt without becoming a customer, and an attached customer can have it sent to a different address than the one on file.\n\nChannels: `email` is sent synchronously (the response reflects sent/failed immediately); `phone` is recorded as a `pending` SMS delivery because no SMS provider is wired yet — the intent is stored and can be fulfilled once an SMS channel exists.\n\nMarketing opt-in (tri-state): `true` opts the attached customer into email marketing, `false` opts them out, and omitting the field leaves their existing preference unchanged. It is only applied when a customer is attached to the sale (guest checkouts skip it).\n\nRequest body:\n- `email` (string, nullable) — email address to send the receipt to. Required when `phone` is absent.\n- `phone` (string, nullable, max 32) — phone number for an SMS receipt (captured as pending). Required when `email` is absent.\n- `marketing_opt_in` (boolean, nullable) — marketing consent captured at send time.\n\nReturns one delivery record per channel used (201 Created).\n\nAuthentication: Requires Bearer token (PAT).","body":{"mode":"raw","raw":"{\n  \"email\": \"jane@acme.test\",\n  \"phone\": \"+1 555-0142\",\n  \"marketing_opt_in\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/pos/transactions/{posTransaction}/receipt/send","host":["{{baseUrl}}"],"path":["api","pos","transactions",":posTransaction","receipt","send"],"variable":[{"key":"posTransaction","value":"88","description":"POS transaction ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 141,\n      \"pos_transaction_id\": 88,\n      \"channel\": \"email\",\n      \"channel_label\": \"Email\",\n      \"target\": \"jane@acme.test\",\n      \"status\": \"sent\",\n      \"status_label\": \"Sent\",\n      \"marketing_opt_in\": true,\n      \"sent_by_user_id\": 12,\n      \"error\": null,\n      \"sent_at\": \"2026-07-06T14:22:10.000000Z\",\n      \"created_at\": \"2026-07-06T14:22:10.000000Z\"\n    },\n    {\n      \"id\": 142,\n      \"pos_transaction_id\": 88,\n      \"channel\": \"sms\",\n      \"channel_label\": \"SMS\",\n      \"target\": \"+15550142\",\n      \"status\": \"pending\",\n      \"status_label\": \"Pending\",\n      \"marketing_opt_in\": true,\n      \"sent_by_user_id\": 12,\n      \"error\": null,\n      \"sent_at\": null,\n      \"created_at\": \"2026-07-06T14:22:10.000000Z\"\n    }\n  ]\n}"}]}]},{"name":"Pick Lists","item":[{"name":"List Pick Lists","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists","host":["{{baseUrl}}"],"path":["api","v2","pick-lists"]},"description":"Paginated pick lists with per-status line counts for a progress bar.\n\nAuthentication: Requires Bearer token. Scope: warehouses.\nSearch (filter[search]) spans pick list number, order number, item SKU, bin code, and id. Filters: status, warehouse_id, assigned_to_user_id, created_at, started_at, completed_at (plain filter[...] or the filter_groups advanced tree). Sorts: id, number, status, created_at, started_at, completed_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pick-lists","host":["{{baseUrl}}"],"path":["api","v2","pick-lists"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"number\": \"PL-000007\",\n      \"warehouse_id\": 1,\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"status\": \"pending\",\n      \"status_label\": \"Pending\",\n      \"assigned_to\": {\n        \"id\": 3,\n        \"name\": \"Casey Picker\"\n      },\n      \"notes\": null,\n      \"lines_count\": 2,\n      \"resolved_lines_count\": 0,\n      \"started_at\": null,\n      \"completed_at\": null,\n      \"created_at\": \"2026-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Pick List","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists","host":["{{baseUrl}}"],"path":["api","v2","pick-lists"]},"description":"Create a pick list from fulfillment orders at one warehouse. Each order line is allocated to bins (split across bins as needed) and sequenced into a walk path; order lines already on an open pick list are skipped.\n\nBody fields:\n- warehouse_id (required) — all orders must be at this warehouse.\n- fulfillment_order_ids (required, array) — the orders to pick.\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission. Returns 422 when the orders have nothing left to pick or no lines match the warehouse.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1,\n  \"fulfillment_order_ids\": [\n    812,\n    815\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pick-lists","host":["{{baseUrl}}"],"path":["api","v2","pick-lists"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"number\": \"PL-000007\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"status\": \"pending\",\n    \"status_label\": \"Pending\",\n    \"assigned_to\": {\n      \"id\": 3,\n      \"name\": \"Casey Picker\"\n    },\n    \"notes\": null,\n    \"lines_count\": 2,\n    \"resolved_lines_count\": 0,\n    \"started_at\": null,\n    \"completed_at\": null,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": 55,\n        \"sequence\": 1,\n        \"fulfillment_order_line_id\": 812,\n        \"product_id\": 42,\n        \"warehouse_location_id\": 12,\n        \"quantity\": 5,\n        \"quantity_picked\": 0,\n        \"status\": \"pending\",\n        \"status_label\": \"Pending\",\n        \"has_bin\": true,\n        \"picked_at\": null,\n        \"location\": {\n          \"id\": 12,\n          \"code\": \"A-01\",\n          \"name\": \"Aisle A\",\n          \"type\": \"primary_pick\",\n          \"type_label\": \"Primary Pick\",\n          \"barcode\": \"A-01\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Premium Widget\",\n          \"barcode\": \"4006381333931\",\n          \"image_url\": null\n        },\n        \"order_number\": \"SO-00123\"\n      },\n      {\n        \"id\": 56,\n        \"sequence\": 2,\n        \"fulfillment_order_line_id\": 813,\n        \"product_id\": 42,\n        \"warehouse_location_id\": 12,\n        \"quantity\": 3,\n        \"quantity_picked\": 0,\n        \"status\": \"pending\",\n        \"status_label\": \"Pending\",\n        \"has_bin\": true,\n        \"picked_at\": null,\n        \"location\": {\n          \"id\": 14,\n          \"code\": \"B-14\",\n          \"name\": null,\n          \"type\": \"reserve\",\n          \"type_label\": \"Reserve\",\n          \"barcode\": \"B-14\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Premium Widget\",\n          \"barcode\": \"4006381333931\",\n          \"image_url\": null\n        },\n        \"order_number\": \"SO-00123\"\n      }\n    ]\n  },\n  \"message\": \"Pick list created.\"\n}"}]},{"name":"Export Pick Lists","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/export","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","export"]},"description":"Download the pick list results as an Excel/CSV file.\n\nAuthentication: Requires Bearer token. Scope: warehouses.\ncontent_mode=summary yields one row per pick list (Pick List #, Warehouse, Status, Lines, Resolved, Orders, Assignee, Created, Started, Completed). content_mode=line_items yields one row per pick line (Pick List #, Warehouse, Seq, Bin, SKU, Product, Order #, Qty, Qty Picked, Line Status).\nscope=filtered honours the active filters; scope=all ignores them; scope=selected restricts to the ids param.\n\nReturns a binary file download (Content-Type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for xlsx, text/csv for csv), not JSON."}},{"name":"Get Pick List","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList"],"variable":[{"key":"pickList","value":"7","description":"Pick list id"}]},"description":"A pick list with its ordered lines (bin, product, quantity, per-line status) — the payload the scan-to-pick screen drives from.\n\nAuthentication: Requires Bearer token. Scope: warehouses."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList"],"variable":[{"key":"pickList","value":"7","description":"Pick list id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"number\": \"PL-000007\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"status\": \"pending\",\n    \"status_label\": \"Pending\",\n    \"assigned_to\": {\n      \"id\": 3,\n      \"name\": \"Casey Picker\"\n    },\n    \"notes\": null,\n    \"lines_count\": 2,\n    \"resolved_lines_count\": 0,\n    \"started_at\": null,\n    \"completed_at\": null,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\",\n    \"lines\": [\n      {\n        \"id\": 55,\n        \"sequence\": 1,\n        \"fulfillment_order_line_id\": 812,\n        \"product_id\": 42,\n        \"warehouse_location_id\": 12,\n        \"quantity\": 5,\n        \"quantity_picked\": 0,\n        \"status\": \"pending\",\n        \"status_label\": \"Pending\",\n        \"has_bin\": true,\n        \"picked_at\": null,\n        \"location\": {\n          \"id\": 12,\n          \"code\": \"A-01\",\n          \"name\": \"Aisle A\",\n          \"type\": \"primary_pick\",\n          \"type_label\": \"Primary Pick\",\n          \"barcode\": \"A-01\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Premium Widget\",\n          \"barcode\": \"4006381333931\",\n          \"image_url\": null\n        },\n        \"order_number\": \"SO-00123\"\n      },\n      {\n        \"id\": 56,\n        \"sequence\": 2,\n        \"fulfillment_order_line_id\": 813,\n        \"product_id\": 42,\n        \"warehouse_location_id\": 12,\n        \"quantity\": 3,\n        \"quantity_picked\": 0,\n        \"status\": \"pending\",\n        \"status_label\": \"Pending\",\n        \"has_bin\": true,\n        \"picked_at\": null,\n        \"location\": {\n          \"id\": 14,\n          \"code\": \"B-14\",\n          \"name\": null,\n          \"type\": \"reserve\",\n          \"type_label\": \"Reserve\",\n          \"barcode\": \"B-14\"\n        },\n        \"product\": {\n          \"id\": 42,\n          \"sku\": \"WIDGET-001\",\n          \"name\": \"Premium Widget\",\n          \"barcode\": \"4006381333931\",\n          \"image_url\": null\n        },\n        \"order_number\": \"SO-00123\"\n      }\n    ]\n  }\n}"}]},{"name":"Delete Pick List","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]},"description":"Permanently delete a pick list and its lines. Does not reverse any fulfillment already recorded.\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Pick list deleted.\"\n}"}]},{"name":"Start Pick List","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/start","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","start"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]},"description":"Move a pending pick list to in_progress and stamp the start time. (The first pick also starts the list automatically.)\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission. Returns 422 on an invalid status transition."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/start","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","start"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"number\": \"PL-000007\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"status\": \"in_progress\",\n    \"status_label\": \"In Progress\",\n    \"assigned_to\": {\n      \"id\": 3,\n      \"name\": \"Casey Picker\"\n    },\n    \"notes\": null,\n    \"lines_count\": 2,\n    \"resolved_lines_count\": 0,\n    \"started_at\": \"2026-01-15T10:05:00.000000Z\",\n    \"completed_at\": null,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Pick list started.\"\n}"}]},{"name":"Complete Pick List","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/complete","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","complete"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]},"description":"Complete an in-progress pick list (all lines should be resolved first).\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission. Returns 422 on an invalid status transition."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/complete","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","complete"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"number\": \"PL-000007\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"status\": \"completed\",\n    \"status_label\": \"Completed\",\n    \"assigned_to\": {\n      \"id\": 3,\n      \"name\": \"Casey Picker\"\n    },\n    \"notes\": null,\n    \"lines_count\": 2,\n    \"resolved_lines_count\": 0,\n    \"started_at\": null,\n    \"completed_at\": \"2026-01-15T10:20:00.000000Z\",\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Pick list completed.\"\n}"}]},{"name":"Cancel Pick List","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/cancel","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","cancel"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]},"description":"Cancel an open pick list. The orders can be picked again via a new pick list.\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/cancel","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","cancel"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"number\": \"PL-000007\",\n    \"warehouse_id\": 1,\n    \"warehouse\": {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\"\n    },\n    \"status\": \"cancelled\",\n    \"status_label\": \"Cancelled\",\n    \"assigned_to\": {\n      \"id\": 3,\n      \"name\": \"Casey Picker\"\n    },\n    \"notes\": null,\n    \"lines_count\": 2,\n    \"resolved_lines_count\": 0,\n    \"started_at\": null,\n    \"completed_at\": null,\n    \"created_at\": \"2026-01-15T10:00:00.000000Z\"\n  },\n  \"message\": \"Pick list cancelled.\"\n}"}]},{"name":"Fulfill Pick List","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/fulfill","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","fulfill"],"variable":[{"key":"pickList","value":"3","description":"Pick list id"}]},"description":"Fulfill a completed pick list — ship each picked / short-picked line from the exact bin it was pulled from, creating one fulfillment per sales order. Skipped and unpicked units stay open for a later pick.\n\nAuthentication: Requires Bearer token. Scope: warehouses. Permission: sales_orders.fulfill.\n\nThe pick list must be Completed and not already fulfilled (idempotent — a 422 is returned otherwise). Returns the updated pick list plus a summary of fulfilled and failed orders."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/fulfill","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","fulfill"],"variable":[{"key":"pickList","value":"3","description":"Pick list id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"PL-000003\",\n    \"status\": \"completed\",\n    \"status_label\": \"Completed\",\n    \"completed_at\": \"2026-07-10T01:05:00.000000Z\",\n    \"fulfilled_at\": \"2026-07-10T01:12:00.000000Z\"\n  },\n  \"summary\": {\n    \"fulfilled\": [\n      {\n        \"sales_order_id\": 3050,\n        \"sales_order_number\": \"SO-3050\",\n        \"units\": 5,\n        \"fulfillment_id\": 8123\n      }\n    ],\n    \"failed\": [],\n    \"total_units\": 5\n  },\n  \"message\": \"Fulfilled 1 order from the picked bins.\"\n}"}]},{"name":"Pick Pick List Line","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pick-list-lines/{pickListLine}/pick","host":["{{baseUrl}}"],"path":["api","v2","pick-list-lines",":pickListLine","pick"],"variable":[{"key":"pickListLine","value":"55","description":"Pick list line id"}]},"description":"Record a pick against a line. A quantity equal to the line quantity marks it picked; less marks it short_picked (clamped to [0, line quantity]). The first pick auto-starts the pick list.\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission.","body":{"mode":"raw","raw":"{\n  \"quantity\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-list-lines/{pickListLine}/pick","host":["{{baseUrl}}"],"path":["api","v2","pick-list-lines",":pickListLine","pick"],"variable":[{"key":"pickListLine","value":"55","description":"Pick list line id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sequence\": 1,\n    \"fulfillment_order_line_id\": 812,\n    \"product_id\": 42,\n    \"warehouse_location_id\": 12,\n    \"quantity\": 5,\n    \"quantity_picked\": 5,\n    \"status\": \"picked\",\n    \"status_label\": \"Picked\",\n    \"has_bin\": true,\n    \"picked_at\": \"2026-01-15T10:06:00.000000Z\",\n    \"location\": {\n      \"id\": 12,\n      \"code\": \"A-01\",\n      \"name\": \"Aisle A\",\n      \"type\": \"primary_pick\",\n      \"type_label\": \"Primary Pick\",\n      \"barcode\": \"A-01\"\n    },\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\",\n      \"barcode\": \"4006381333931\",\n      \"image_url\": null\n    },\n    \"order_number\": \"SO-00123\"\n  }\n}"}]},{"name":"Skip Pick List Line","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-list-lines/{pickListLine}/skip","host":["{{baseUrl}}"],"path":["api","v2","pick-list-lines",":pickListLine","skip"],"variable":[{"key":"pickListLine","value":"55","description":"The pick list line ID."}]},"description":"Skip a line (e.g. the stock isn't in the bin). The first action auto-starts the pick list.\n\nAuthentication: Requires Bearer token. Requires the sales_orders.fulfill permission."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-list-lines/{pickListLine}/skip","host":["{{baseUrl}}"],"path":["api","v2","pick-list-lines",":pickListLine","skip"],"variable":[{"key":"pickListLine","value":"55","description":"The pick list line ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"sequence\": 1,\n    \"fulfillment_order_line_id\": 812,\n    \"product_id\": 42,\n    \"warehouse_location_id\": 12,\n    \"quantity\": 5,\n    \"quantity_picked\": 0,\n    \"status\": \"skipped\",\n    \"status_label\": \"Skipped\",\n    \"has_bin\": true,\n    \"picked_at\": \"2026-01-15T10:07:00.000000Z\",\n    \"location\": {\n      \"id\": 12,\n      \"code\": \"A-01\",\n      \"name\": \"Aisle A\",\n      \"type\": \"primary_pick\",\n      \"type_label\": \"Primary Pick\",\n      \"barcode\": \"A-01\"\n    },\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Premium Widget\",\n      \"barcode\": \"4006381333931\",\n      \"image_url\": null\n    },\n    \"order_number\": \"SO-00123\"\n  }\n}"}]},{"name":"Download Pick List PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/export/pick-lists/{pickList}/pdf","host":["{{baseUrl}}"],"path":["api","export","pick-lists",":pickList","pdf"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]},"description":"Stream the pick list as a printable PDF (inline), rendered from its stored lines in walk-path order. Rendered from the configurable Pick List template.\n\nAuthentication: Requires Bearer token. Returns 422 when the pick list has no lines or no pick list template is configured."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/export/pick-lists/{pickList}/pdf","host":["{{baseUrl}}"],"path":["api","export","pick-lists",":pickList","pdf"],"variable":[{"key":"pickList","value":"7","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 … binary PDF stream (the rendered pick list)"}]},{"name":"Archive Pick List","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/archive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","archive"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]},"description":"Archive a pick list (soft — hidden from the default list, restorable).\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/archive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","archive"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"PL-000003\",\n    \"status\": \"completed\",\n    \"archived_at\": \"2026-07-10T10:00:00.000000Z\"\n  },\n  \"message\": \"Pick list archived.\"\n}"}]},{"name":"Unarchive Pick List","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/unarchive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","unarchive"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]},"description":"Restore an archived pick list.\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/{pickList}/unarchive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists",":pickList","unarchive"],"variable":[{"key":"pickList","value":"3","description":"The pick list ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"number\": \"PL-000003\",\n    \"archived_at\": null\n  },\n  \"message\": \"Pick list restored.\"\n}"}]},{"name":"Bulk Archive Pick Lists","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-archive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-archive"]},"description":"Archive many pick lists. Send explicit ids, or omit ids to target every pick list matching the current filters.\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-archive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"count\": 3\n  },\n  \"message\": \"3 pick list(s) archived.\"\n}"}]},{"name":"Bulk Unarchive Pick Lists","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-unarchive"]},"description":"Restore many archived pick lists. Send explicit ids, or omit ids to target the current filters.\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"count\": 2\n  },\n  \"message\": \"2 pick list(s) restored.\"\n}"}]},{"name":"Bulk Delete Pick Lists","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-delete","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-delete"]},"description":"Permanently delete many pick lists (and their lines). Send explicit ids, or omit ids to target the current filters.\n\nAuthentication: Requires Bearer token. Permission: sales_orders.fulfill.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/pick-lists/bulk-delete","host":["{{baseUrl}}"],"path":["api","v2","pick-lists","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"count\": 1\n  },\n  \"message\": \"1 pick list(s) deleted.\"\n}"}]}]},{"name":"Movement Composer","item":[{"name":"Preview Release Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/movements/preview-release-impact","host":["{{baseUrl}}"],"path":["api","v2","inventory","movements","preview-release-impact"]},"description":"Dry-run preview: given a receipt payload, compute which pending backorder allocations would be released once the movement is committed.\n\n**Named route:** `v2.inventory.movements.preview-release-impact`\n\n**When to call:** UI should invoke this BEFORE committing a `direction=receive` movement so the operator can confirm how incoming stock will be consumed by existing backorders.\n\n**Request body:** Same shape as the commit endpoint (see `Commit Movement`). Only `direction`, `warehouse_id`, `movement_date`, and `lines[*].product_id` + `lines[*].quantity` are required for preview.\n\n**Response shape:**\n```\n{\n  \"data\": {\n    \"total_units_receiving\": 50,\n    \"total_allocations_released\": 2,\n    \"releases\": [ { fulfillment_id, product_id, quantity_released, ... } ],\n    \"held_back\": [ ... ]\n  }\n}\n```","body":{"mode":"raw","raw":"{\n  \"direction\": \"receive\",\n  \"warehouse_id\": 1,\n  \"movement_date\": \"2026-04-19\",\n  \"against_type\": \"purchase_order\",\n  \"against_id\": 4521,\n  \"reason\": \"PO receipt\",\n  \"lines\": [\n    {\n      \"product_id\": 123,\n      \"quantity\": 50,\n      \"unit_cost\": 12.5\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Preview Demotion Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/movements/preview-demotion-impact","host":["{{baseUrl}}"],"path":["api","v2","inventory","movements","preview-demotion-impact"]},"description":"Dry-run preview: given an outbound/adjust-down payload, compute which allocations (unallocated, soft-allocated, hard-allocated) would be consumed, and whether any hard-allocated fulfillments will require an explicit void confirmation before commit.\n\n**Named route:** `v2.inventory.movements.preview-demotion-impact`\n\n**When to call:** UI should invoke this BEFORE committing `direction=ship` or `direction=adjust_down` to surface any allocations that would be demoted, including hard-allocated fulfillments whose shipping labels may need to be voided.\n\n**Key response field:** `requires_void_confirmation` (bool) — when true, the caller MUST include a matching `void_confirmations[]` entry in the commit payload for every hard-allocated fulfillment listed in `lines[*].buckets.hard_allocated.fulfillments`.\n\n**Response shape:**\n```\n{\n  \"data\": {\n    \"requires_void_confirmation\": true,\n    \"lines\": [\n      {\n        \"product_id\": 123,\n        \"product_sku\": \"SKU-ABC\",\n        \"product_name\": \"Widget\",\n        \"quantity_requested\": 10,\n        \"buckets\": {\n          \"unallocated\": { quantity, ... },\n          \"soft_allocated\": { quantity, fulfillments: [...] },\n          \"hard_allocated\": { quantity, fulfillments: [ { fulfillment_id, provider, ... } ] }\n        }\n      }\n    ]\n  }\n}\n```","body":{"mode":"raw","raw":"{\n  \"direction\": \"ship\",\n  \"warehouse_id\": 1,\n  \"movement_date\": \"2026-04-19\",\n  \"against_type\": \"none\",\n  \"reason\": \"Manual shipment\",\n  \"lines\": [\n    {\n      \"product_id\": 123,\n      \"quantity\": -10\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Commit Movement","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/inventory/movements/composer","host":["{{baseUrl}}"],"path":["api","v2","inventory","movements","composer"]},"description":"Atomic commit of a composed movement: creates inventory adjustments, persists lot/serial detail, and triggers allocation release or demotion — all inside one DB transaction. When an outbound demotion consumes hard-allocated stock, each confirmed shipping label is voided in the same transaction (the fulfillment's inventory is reversed back to on-hand, its FulfillmentOrder budget reopened, and the shipment marked canceled).\n\n**Named route:** `v2.inventory.movements.composer`\n\n**Request fields:**\n- `direction` (required) — one of: `receive`, `ship`, `adjust_up`, `adjust_down`\n- `warehouse_id` (required) — must exist in `warehouses`\n- `movement_date` (required) — ISO date\n- `against_type` (optional) — `purchase_order`, `transfer`, or `none`\n- `against_id` (optional) — ID of the source doc when `against_type` is set\n- `reason` (optional, max 1000 chars)\n- `lines[]` (required, min 1):\n    - `product_id` (required)\n    - `quantity` (required, non-zero — positive for inbound, negative for outbound)\n    - `unit_cost` (optional, >= 0)\n    - `serials[]` (optional, each max 100 chars)\n    - `lot` (optional): `lot_number`, `expires_at`, `manufactured_at`\n    - `override_reason` (optional, max 500 chars)\n- `void_confirmations[]` (required when preview-demotion returned `requires_void_confirmation=true`):\n    - `fulfillment_id` (required)\n    - `attempt_void` (required bool)\n    - `reason` (optional, max 500 chars)\n\n**Response shape (200):**\n```\n{\n  \"data\": {\n    \"adjustment_ids\": [101, 102],\n    \"voided_fulfillment_ids\": [9001],\n    \"skipped_fulfillments\": []\n  },\n  \"message\": \"Receipt committed — 1 line(s).\"\n}\n```\n\n`voided_fulfillment_ids` lists the fulfillments whose labels were voided. `skipped_fulfillments` lists any confirmed fulfillment that could not be voided (already voided, or part of a multi-shipment merge group) as `{ fulfillment_id, kind, reason }` — these are skipped, not fatal.\n\n**Error (422):** Returned when hard-allocated fulfillments are missing from `void_confirmations` or any other `\\InvalidArgumentException` is thrown by the manager.\n```\n{ \"error\": \"Hard-allocated fulfillment #9001 requires an explicit void confirmation before committing.\" }\n```\n\n`release_backorders` (boolean, inbound only, default true): when true, the received stock is applied to any waiting back-orders (promoting them to allocated); when false, the stock is received as free inventory and the back-orders keep waiting.\n\n`release_sales_order_ids` (array of ints, inbound only, optional): granular release. Omit or null to release ALL waiting back-orders; pass a list of sales order ids to release only those orders' back-orders. Requires `release_backorders` = true.","body":{"mode":"raw","raw":"{\n  \"direction\": \"receive\",\n  \"warehouse_id\": 1,\n  \"movement_date\": \"2026-04-19\",\n  \"against_type\": \"purchase_order\",\n  \"against_id\": 4521,\n  \"reason\": \"PO receipt — truck 8821\",\n  \"release_backorders\": true,\n  \"release_sales_order_ids\": null,\n  \"lines\": [\n    {\n      \"product_id\": 123,\n      \"quantity\": 50,\n      \"unit_cost\": 12.5,\n      \"serials\": [\n        \"SN-0001\",\n        \"SN-0002\"\n      ],\n      \"lot\": {\n        \"lot_number\": \"LOT-2026-04\",\n        \"expires_at\": \"2027-04-19\",\n        \"manufactured_at\": \"2026-03-15\"\n      }\n    }\n  ],\n  \"void_confirmations\": [\n    {\n      \"fulfillment_id\": 9001,\n      \"attempt_void\": true,\n      \"reason\": \"Operator override — customer cancelled\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Vendor Credits","item":[{"name":"List Vendor Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","vendor-credits"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}]},"description":"Returns a paginated list of vendor credits. Supports Spatie QueryBuilder filters, sorting, and search. Each row is transformed via vendor credit object.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nThe response also includes `unfiltered_total`, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals.\n\n**Search** (`filter[search]`) matches across: ID, Credit Number (vendor_credit_number), Additional Reference (supplier_reference), Supplier PO # (supplier_po_number), Supplier Name, Supplier Email, line item SKU, and Purchase Order #."}},{"name":"Create Vendor Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits","host":["{{baseUrl}}"],"path":["api","vendor-credits"]},"description":"Create a new vendor credit.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\n**Required fields:**\n- `supplier_id` (int) — Supplier the credit is from.\n\n**Optional top-level fields:**\n- `purchase_order_id`, `purchase_invoice_id` — Links to the source PO / bill.\n- `warehouse_id`, `store_id` — For restock-type credits.\n- `credit_type` — One of: restock, unstock, service, overpayment, rebate.\n- `refund_method` — One of: applied_to_bill, cash_refund, retained_credit.\n- `currency_id` OR `currency_code` — Pick the credit's currency. If omitted, defaults are resolved in this order: (1) linked PO's currency if `purchase_order_id` is set, (2) the supplier's default pricing tier currency, (3) the tenant default currency. When a `purchase_order_id` is supplied, the currency MUST match the PO's currency.\n- `tax_rate_id` — Default tax rate for lines.\n- `credit_date` — ISO date (defaults to today).\n- `supplier_reference` — External RMA / credit reference from supplier.\n- `vendor_credit_number` — Auto-generated if omitted.\n- `is_tax_included`, `is_for_overpayment` — Booleans.\n- `vendor_credit_note` — Free-text note.\n- `tax_lines`, `metadata` — Optional arrays.\n\n**Lines (array, required for most credit types):**\nEach line is either:\n1. A PO-line-linked line: `purchase_order_line_id` + `quantity` + optional `unit_cost`/`amount`/`restock_inventory`.\n2. A description-only line (service/rebate): `description` + `quantity` + `amount` (+ optional `nominal_code_id`).\n\nValidation enforces that the requested `quantity` on any PO-line-linked line does not exceed `(received_quantity - already_credited_quantity)` for that PO line.\n\n**Reference fields:**\n- `vendor_credit_number` (string, max 255, unique) — The supplier's **credit memo number** as printed on their document (e.g. \"Credit Memo 0001669\"). This becomes the credit's number in SKU. Leave blank/omit to auto-generate a local number (`VC-00001`, `VC-00002`, …). Supplying a number already used by another credit returns a 422 with a `vendor_credit_number` validation error.\n- `supplier_reference` (string, max 255) — Any **additional reference** on the supplier's document, e.g. their internal order number (\"Credit Order 0010764\"). The credit-memo OCR pipeline's duplicate detection matches an extracted memo number against BOTH `supplier_reference` and `vendor_credit_number`.\n- `supplier_po_number` (string, max 255) — The **PO number printed on the supplier's memo**, recorded as text for reference only. It does NOT link to a purchase order in SKU (use `purchase_order_id` for an actual link).\n- `purchase_order_id` (int) — Link the credit to an actual PO in SKU (return/damage credits). When linked, the credit's currency must match the PO's currency.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 1,\n  \"warehouse_id\": 2,\n  \"store_id\": 1,\n  \"credit_type\": \"restock\",\n  \"refund_method\": \"applied_to_bill\",\n  \"currency_code\": \"USD\",\n  \"tax_rate_id\": 3,\n  \"credit_date\": \"2026-04-11\",\n  \"supplier_reference\": \"Credit Order 0010764\",\n  \"supplier_po_number\": \"001\",\n  \"vendor_credit_number\": 1669,\n  \"is_tax_included\": false,\n  \"is_for_overpayment\": false,\n  \"vendor_credit_note\": \"Credit for 5 defective units returned to supplier.\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"product_id\": 555,\n      \"quantity\": 5,\n      \"unit_cost\": 12.5,\n      \"amount\": 62.5,\n      \"tax_allocation\": 0,\n      \"tax_rate_id\": 3,\n      \"is_product\": true,\n      \"restock_inventory\": true\n    },\n    {\n      \"description\": \"Freight rebate\",\n      \"nominal_code_id\": 27,\n      \"quantity\": 1,\n      \"amount\": 15,\n      \"tax_allocation\": 0,\n      \"is_product\": false,\n      \"restock_inventory\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits","host":["{{baseUrl}}"],"path":["api","vendor-credits"]}},"status":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unauthenticated.\"\n}"}]},{"name":"Bulk Delete Vendor Credits","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits","host":["{{baseUrl}}"],"path":["api","vendor-credits"]},"description":"Bulk delete vendor credits. Same body shape as Bulk Archive.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Note:** The route is `DELETE /api/vendor-credits` (the resource root). Laravel's router resolves this before the `Route::resource` destroy route, which binds a `{vendor_credit}` parameter."}},{"name":"Get Vendor Credit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Show a single vendor credit with all eager-loaded relations: supplier, purchase order, purchase invoice, warehouse, store, currency, tax rate, vendor credit lines (with product, PO line, nominal code, tax rate), allocations (with purchase invoice and allocator), payments, tags, and the linked accounting transaction.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."}},{"name":"Update Vendor Credit","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Update an existing vendor credit. Accepts the same fields as Create.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\n**Currency rules:**\n- `currency_id` (or `currency_code`) can be updated ONLY while the credit has no activity.\n- If the credit has any allocations (applied to bills) or payments, attempting to change the currency returns a 422 with a `currency_id` validation error.\n- If the credit is linked to a purchase order, the currency MUST match the PO's currency — any mismatch returns a 422.\n\n**Line replacement semantics:** supplying `lines` replaces the existing line set (use with care). Closed or voided credits may be blocked from editing — check the manager.\n\n**Reference fields:**\n- `vendor_credit_number` (string, max 255, unique) — The supplier's **credit memo number** as printed on their document (e.g. \"Credit Memo 0001669\"). This becomes the credit's number in SKU. Leave blank/omit to auto-generate a local number (`VC-00001`, `VC-00002`, …). Supplying a number already used by another credit returns a 422 with a `vendor_credit_number` validation error.\n- `supplier_reference` (string, max 255) — Any **additional reference** on the supplier's document, e.g. their internal order number (\"Credit Order 0010764\"). The credit-memo OCR pipeline's duplicate detection matches an extracted memo number against BOTH `supplier_reference` and `vendor_credit_number`.\n- `supplier_po_number` (string, max 255) — The **PO number printed on the supplier's memo**, recorded as text for reference only. It does NOT link to a purchase order in SKU (use `purchase_order_id` for an actual link).\n- `purchase_order_id` (int) — Link the credit to an actual PO in SKU (return/damage credits). When linked, the credit's currency must match the PO's currency.\n\nThis endpoint also accepts the PATCH method with identical behavior.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 1,\n  \"credit_type\": \"restock\",\n  \"refund_method\": \"applied_to_bill\",\n  \"credit_date\": \"2026-04-11\",\n  \"supplier_reference\": \"Credit Order 0010764\",\n  \"supplier_po_number\": \"001\",\n  \"vendor_credit_note\": \"Updated note — replaced 2 lines with an adjusted quantity.\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"product_id\": 555,\n      \"quantity\": 4,\n      \"unit_cost\": 12.5,\n      \"amount\": 50,\n      \"is_product\": true,\n      \"restock_inventory\": true\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Vendor Credit","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Delete a vendor credit and cascade-delete its related lines, allocations, accounting transaction, and any inventory movements restored by the manager. Will fail for credits that are referenced by posted / synced accounting data if business rules prevent deletion.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."}},{"name":"Get Vendor Credit Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/stats","host":["{{baseUrl}}"],"path":["api","vendor-credits","stats"]},"description":"Aggregate statistics for vendor credits: the number and remaining balance of open credits, the subset that is still fully unapplied, and the total amount ever allocated to purchase invoices.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBalances are summed in each credit's original currency; currency_code is the tenant's default currency and is intended for display formatting. On multi-currency tenants treat these totals as an indicator rather than an exact figure."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/stats","host":["{{baseUrl}}"],"path":["api","vendor-credits","stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"open_count\": 4,\n    \"open_balance\": 1230.5,\n    \"unapplied_count\": 2,\n    \"unapplied_balance\": 730.5,\n    \"total_allocated\": 8250,\n    \"currency_code\": \"USD\"\n  }\n}"}]},{"name":"List Open Vendor Credits for Supplier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/for-supplier/{supplier}","host":["{{baseUrl}}"],"path":["api","vendor-credits","for-supplier",":supplier"],"variable":[{"key":"supplier","value":"7","description":"Supplier ID"}]},"description":"List open, non-archived vendor credits for a supplier that still have balance available to apply (payment status unapplied or partially applied), sorted by credit date descending. Useful for finding credits that can be allocated against the supplier's outstanding bills.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/for-supplier/{supplier}","host":["{{baseUrl}}"],"path":["api","vendor-credits","for-supplier",":supplier"],"variable":[{"key":"supplier","value":"7","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 17,\n      \"vendor_credit_number\": \"VC-000017\",\n      \"supplier_reference\": \"CM-88213\",\n      \"supplier_po_number\": \"PO-000310\",\n      \"credit_date\": \"2026-06-20\",\n      \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n      \"metadata\": null,\n      \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n      \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n      \"archived_at\": null,\n      \"fully_allocated_at\": null,\n      \"fully_refunded_at\": null,\n      \"is_settled\": false,\n      \"settlement_breakdown\": {\n        \"allocated\": 0,\n        \"refunded\": 0,\n        \"remaining\": 250,\n        \"total\": 250\n      },\n      \"credit_status\": \"open\",\n      \"credit_status_label\": \"Open\",\n      \"payment_status\": \"unapplied\",\n      \"payment_status_label\": \"Unapplied\",\n      \"is_for_overpayment\": false,\n      \"supplier_id\": 7,\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Components Ltd\",\n        \"email\": \"accounts@acme-components.com\"\n      },\n      \"purchase_order_id\": 310,\n      \"purchase_order\": {\n        \"id\": 310,\n        \"purchase_order_number\": \"PO-000310\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"store_id\": null,\n      \"store\": null,\n      \"currency_id\": 1,\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"is_tax_included\": false,\n      \"tax_rate_id\": null,\n      \"tax_rate\": null,\n      \"tax_lines\": null,\n      \"tax_total\": 0,\n      \"tax_credit\": 0,\n      \"product_total\": 250,\n      \"total_credit\": 250,\n      \"total\": 250,\n      \"allocated_amount\": 0,\n      \"planned_allocation_amount\": 0,\n      \"available_to_allocate\": 250,\n      \"refunded_amount\": 0,\n      \"remaining_amount\": 250,\n      \"lines\": [\n        {\n          \"id\": 31,\n          \"vendor_credit_id\": 17,\n          \"purchase_order_line_id\": 771,\n          \"financial_line_id\": null,\n          \"product_id\": 55,\n          \"quantity\": 5,\n          \"amount\": 250,\n          \"unit_cost\": 50,\n          \"description\": \"Blue Widget (Medium)\",\n          \"tax_allocation\": 0,\n          \"tax_rate_id\": null,\n          \"tax_rate\": null,\n          \"nominal_code_id\": null,\n          \"nominal_code\": null,\n          \"is_product\": true,\n          \"restock_inventory\": false,\n          \"proration\": null,\n          \"subtotal\": 250,\n          \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n          \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n          \"product\": {\n            \"id\": 55,\n            \"sku\": \"WID-BLU-M\",\n            \"name\": \"Blue Widget (Medium)\",\n            \"barcode\": 123456789012,\n            \"image\": null,\n            \"is_lot_tracked\": false,\n            \"lot_tracking_method\": null,\n            \"shelf_life_days\": null,\n            \"near_expiry_threshold_days\": null,\n            \"min_remaining_shelf_life_days\": null\n          },\n          \"purchase_order_line\": {\n            \"id\": 771,\n            \"purchase_order_id\": 310,\n            \"product_id\": 55,\n            \"quantity\": 20,\n            \"unit_price\": 50,\n            \"purchase_order_number\": \"PO-000310\"\n          }\n        }\n      ],\n      \"line_item_count\": 1,\n      \"total_quantity\": 5,\n      \"first_line_sku\": \"WID-BLU-M\",\n      \"has_products\": true,\n      \"allocations\": [],\n      \"payments\": [],\n      \"shipments_count\": 0,\n      \"tags\": [\n        \"damaged-goods\"\n      ],\n      \"inventory_movements\": [],\n      \"link_reference\": \"VC-000017\",\n      \"link_type_label\": \"Vendor Credit\",\n      \"link_route\": \"/purchases/vendor-credits/17\"\n    }\n  ]\n}"}]},{"name":"List Applicable Vendor Credits for Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/for-invoice/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","vendor-credits","for-invoice",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"88","description":"Purchase invoice (bill) ID"}]},"description":"List open vendor credits that can be applied to a specific purchase invoice (bill): credits from the same supplier, in the same currency as the invoice, that are not archived and still have a remaining balance. Sorted by credit date descending.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/for-invoice/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","vendor-credits","for-invoice",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"88","description":"Purchase invoice (bill) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 17,\n      \"vendor_credit_number\": \"VC-000017\",\n      \"supplier_reference\": \"CM-88213\",\n      \"supplier_po_number\": \"PO-000310\",\n      \"credit_date\": \"2026-06-20\",\n      \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n      \"metadata\": null,\n      \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n      \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n      \"archived_at\": null,\n      \"fully_allocated_at\": null,\n      \"fully_refunded_at\": null,\n      \"is_settled\": false,\n      \"settlement_breakdown\": {\n        \"allocated\": 0,\n        \"refunded\": 0,\n        \"remaining\": 250,\n        \"total\": 250\n      },\n      \"credit_status\": \"open\",\n      \"credit_status_label\": \"Open\",\n      \"payment_status\": \"unapplied\",\n      \"payment_status_label\": \"Unapplied\",\n      \"is_for_overpayment\": false,\n      \"supplier_id\": 7,\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Components Ltd\",\n        \"email\": \"accounts@acme-components.com\"\n      },\n      \"purchase_order_id\": 310,\n      \"purchase_order\": {\n        \"id\": 310,\n        \"purchase_order_number\": \"PO-000310\"\n      },\n      \"warehouse_id\": 2,\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"store_id\": null,\n      \"store\": null,\n      \"currency_id\": 1,\n      \"currency_code\": \"USD\",\n      \"currency_rate\": 1,\n      \"is_tax_included\": false,\n      \"tax_rate_id\": null,\n      \"tax_rate\": null,\n      \"tax_lines\": null,\n      \"tax_total\": 0,\n      \"tax_credit\": 0,\n      \"product_total\": 250,\n      \"total_credit\": 250,\n      \"total\": 250,\n      \"allocated_amount\": 0,\n      \"planned_allocation_amount\": 0,\n      \"available_to_allocate\": 250,\n      \"refunded_amount\": 0,\n      \"remaining_amount\": 250,\n      \"lines\": [\n        {\n          \"id\": 31,\n          \"vendor_credit_id\": 17,\n          \"purchase_order_line_id\": 771,\n          \"financial_line_id\": null,\n          \"product_id\": 55,\n          \"quantity\": 5,\n          \"amount\": 250,\n          \"unit_cost\": 50,\n          \"description\": \"Blue Widget (Medium)\",\n          \"tax_allocation\": 0,\n          \"tax_rate_id\": null,\n          \"tax_rate\": null,\n          \"nominal_code_id\": null,\n          \"nominal_code\": null,\n          \"is_product\": true,\n          \"restock_inventory\": false,\n          \"proration\": null,\n          \"subtotal\": 250,\n          \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n          \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n          \"product\": {\n            \"id\": 55,\n            \"sku\": \"WID-BLU-M\",\n            \"name\": \"Blue Widget (Medium)\",\n            \"barcode\": 123456789012,\n            \"image\": null,\n            \"is_lot_tracked\": false,\n            \"lot_tracking_method\": null,\n            \"shelf_life_days\": null,\n            \"near_expiry_threshold_days\": null,\n            \"min_remaining_shelf_life_days\": null\n          },\n          \"purchase_order_line\": {\n            \"id\": 771,\n            \"purchase_order_id\": 310,\n            \"product_id\": 55,\n            \"quantity\": 20,\n            \"unit_price\": 50,\n            \"purchase_order_number\": \"PO-000310\"\n          }\n        }\n      ],\n      \"line_item_count\": 1,\n      \"total_quantity\": 5,\n      \"first_line_sku\": \"WID-BLU-M\",\n      \"has_products\": true,\n      \"allocations\": [],\n      \"payments\": [],\n      \"shipments_count\": 0,\n      \"tags\": [\n        \"damaged-goods\"\n      ],\n      \"inventory_movements\": [],\n      \"link_reference\": \"VC-000017\",\n      \"link_type_label\": \"Vendor Credit\",\n      \"link_route\": \"/purchases/vendor-credits/17\"\n    }\n  ]\n}"}]},{"name":"Create Vendor Credit from Invoice","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/from-invoice/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","vendor-credits","from-invoice",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"88","description":"Purchase invoice (bill) ID"}]},"description":"Create a vendor credit pre-populated from a purchase invoice (bill): the invoice's lines are copied onto the credit, the credit is opened immediately, and its full balance is applied against the source invoice. No request body is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when a credit cannot be created from the invoice (e.g. the invoice has no outstanding balance)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/from-invoice/{purchase_invoice}","host":["{{baseUrl}}"],"path":["api","vendor-credits","from-invoice",":purchase_invoice"],"variable":[{"key":"purchase_invoice","value":"88","description":"Purchase invoice (bill) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit created successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"fully_applied\",\n    \"payment_status_label\": \"Fully Applied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 250,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 0,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 0,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Update Vendor Credit Tags","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/tags","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","tags"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Replace the full set of tags on a vendor credit. The tags array is required (send an empty array to remove all tags); each tag is a string of up to 64 characters. Tags that do not exist yet are created automatically.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated vendor credit.","body":{"mode":"raw","raw":"{\n  \"tags\": [\n    \"damaged-goods\",\n    \"q3-review\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/tags","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","tags"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit tags VC-000017 updated successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"unapplied\",\n    \"payment_status_label\": \"Unapplied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\",\n      \"q3-review\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Archive Vendor Credit","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/archive","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","archive"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Archive (soft-hide) a vendor credit. Returns a warning if it is already archived.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Unarchive Vendor Credit","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/unarchive","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","unarchive"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Unarchive a previously archived vendor credit. Returns a warning if it was not archived.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Void Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/void","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","void"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Void a vendor credit. This reverses any inventory movements created by the credit (e.g. restock reversals) and reverses the linked accounting transaction. Idempotent: voiding an already-voided credit is a no-op.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Close Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/close","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","close"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Close a vendor credit — marks it as fully settled so no further allocations or edits are allowed. Typically called after the credit has been fully allocated or refunded.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Authorize Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/authorize","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","authorize"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Authorize a draft vendor credit, transitioning it to open. Authorization posts the credit's accounting transaction, records the FIFO cost layers consumed by the credited quantities, and creates planned inventory allocations for lines marked for restock.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the credit is not in a state that can be authorized."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/authorize","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","authorize"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit VC-000017 updated successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"unapplied\",\n    \"payment_status_label\": \"Unapplied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Unauthorize Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/unauthorize","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","unauthorize"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Revert an open vendor credit back to draft. This reverses everything authorization created: planned inventory allocations, write-off inventory movements, FIFO layer usages, and the accounting transaction.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the credit cannot be reverted (e.g. it already has applied allocations, refund payments, or return shipments)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/unauthorize","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","unauthorize"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit VC-000017 updated successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"draft\",\n    \"credit_status_label\": \"Draft\",\n    \"payment_status\": \"unapplied\",\n    \"payment_status_label\": \"Unapplied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Reopen Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/reopen","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","reopen"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Reopen a closed vendor credit, making its remaining balance available to allocate or refund again. No request body is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated vendor credit."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/reopen","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","reopen"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit VC-000017 updated successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"unapplied\",\n    \"payment_status_label\": \"Unapplied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Preview Vendor Credit Write-Off Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/write-off-impact","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","write-off-impact"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Get a read-only preview of the order allocations that authorizing this vendor credit would consume when its write-off lines post their outbound decrement. Each row is one product whose stock the write-off would remove, split into free, soft-reserved and hard-allocated quantities, and lists the affected sales-order allocations highest-priority first so you can see which orders — and which printed shipping labels — would be demoted or voided before you authorize the credit.\n\nThis endpoint makes no changes.\n\nResponse fields:\n- `data[].product_id` / `product_sku` / `product_name` — the product the action would consume stock for.\n- `data[].shortfall_quantity` — how much more than the available quantity the action removes; stock goes negative when greater than 0.\n- `data[].unallocated_quantity` / `soft_allocated_quantity` / `hard_allocated_quantity` — the free / soft-reserved / hard-allocated (label-printed) split of the consumed quantity.\n- `data[].affected_allocations[]` — the order allocations that would be consumed, highest priority first. `allocation_type` is `soft` or `hard`. For hard rows, `fulfillment_id` and `carrier` identify the printed label and `carrier_void_supported` / `voidable_status` (`voidable` or otherwise) indicate whether the label can be voided through the API.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/write-off-impact","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","write-off-impact"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 4,\n      \"soft_allocated_quantity\": 3,\n      \"hard_allocated_quantity\": 2,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88213,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 4521,\n          \"order_number\": \"SO-10442\",\n          \"customer_name\": \"Acme Retail\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 3\n        },\n        {\n          \"allocation_id\": 88240,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 4530,\n          \"order_number\": \"SO-10450\",\n          \"customer_name\": \"Beta Wholesale\",\n          \"fulfillment_id\": 77120,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Allocate to Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/allocate","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","allocate"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Allocate part or all of the vendor credit's remaining balance to a purchase invoice (bill).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Required fields:**\n- `purchase_invoice_id` (int) — Must exist.\n- `amount` (float, >= 0.01) — Amount to allocate. Cannot exceed the credit's remaining balance or the bill's outstanding balance.\n\n**Optional fields:**\n- `allocated_at` (date) — Defaults to now.\n- `notes` (string)\n\nThe allocation is recorded on `vendor_credit_allocations` and reduces the bill's outstanding amount. The response includes the new allocation with its purchase invoice and allocator user.","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_id\": 17,\n  \"amount\": 75.5,\n  \"allocated_at\": \"2026-04-11\",\n  \"notes\": \"Applied against bill BILL-2026-0017\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Batch Allocate to Purchase Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/allocate-batch","host":["{{baseUrl}}"],"path":["api","vendor-credits","allocate-batch"]},"description":"Apply several vendor credits to a single purchase invoice (bill) in one atomic batch. Powers the \"Credit this bill\" allocation flow, where a buyer distributes multiple outstanding credits from the same supplier against one bill at once. The whole batch is all-or-nothing: if any single allocation fails validation or over-allocates, none of them are saved.\n\n**Required fields:**\n- `purchase_invoice_id` (int) — The bill to credit. Must exist.\n- `allocations` (array, min 1) — One entry per credit to apply.\n  - `allocations[].vendor_credit_id` (int) — Must exist and belong to the same supplier and currency as the bill. Cannot be repeated within one request.\n  - `allocations[].amount` (float, >= 0.01) — Amount to allocate from that credit. Cannot exceed the credit's remaining balance.\n\n**Optional fields:**\n- `allocated_at` (date) — Applied to every allocation in the batch. Defaults to now.\n- `notes` (string, max 1000) — Applied to every allocation in the batch.\n\n**Validation:** the sum of all `amount` values cannot exceed the bill's outstanding balance (gross total less cash paid, applied deposits, and already-applied credits). A violation returns 422 with no allocations saved.","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_id\": 17,\n  \"allocations\": [\n    {\n      \"vendor_credit_id\": 1,\n      \"amount\": 600\n    },\n    {\n      \"vendor_credit_id\": 2,\n      \"amount\": 150.5\n    }\n  ],\n  \"allocated_at\": \"2026-04-11\",\n  \"notes\": \"Applied TecMATE credits against bill BILL-2026-0017\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/allocate-batch","host":["{{baseUrl}}"],"path":["api","vendor-credits","allocate-batch"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Applied 2 vendor credit(s) to the bill.\",\n  \"data\": [\n    {\n      \"id\": 41,\n      \"vendor_credit_id\": 1,\n      \"purchase_invoice_id\": 17,\n      \"amount\": 600,\n      \"currency_rate\": 1,\n      \"fx_gain_loss\": 0,\n      \"allocated_at\": \"2026-04-11 00:00:00\",\n      \"applied_at\": \"2026-04-11 14:22:07\",\n      \"is_planned\": false,\n      \"notes\": \"Applied TecMATE credits against bill BILL-2026-0017\",\n      \"created_at\": \"2026-04-11 14:22:07\",\n      \"updated_at\": \"2026-04-11 14:22:07\",\n      \"purchase_invoice\": {\n        \"id\": 17,\n        \"supplier_invoice_number\": \"BILL-2026-0017\",\n        \"purchase_invoice_date\": \"2026-04-01\",\n        \"purchase_order_id\": 9\n      },\n      \"allocated_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Buyer\",\n        \"email\": \"jane@acme.test\"\n      }\n    },\n    {\n      \"id\": 42,\n      \"vendor_credit_id\": 2,\n      \"purchase_invoice_id\": 17,\n      \"amount\": 150.5,\n      \"currency_rate\": 1,\n      \"fx_gain_loss\": 0,\n      \"allocated_at\": \"2026-04-11 00:00:00\",\n      \"applied_at\": \"2026-04-11 14:22:07\",\n      \"is_planned\": false,\n      \"notes\": \"Applied TecMATE credits against bill BILL-2026-0017\",\n      \"created_at\": \"2026-04-11 14:22:07\",\n      \"updated_at\": \"2026-04-11 14:22:07\",\n      \"purchase_invoice\": {\n        \"id\": 17,\n        \"supplier_invoice_number\": \"BILL-2026-0017\",\n        \"purchase_invoice_date\": \"2026-04-01\",\n        \"purchase_order_id\": 9\n      },\n      \"allocated_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Buyer\",\n        \"email\": \"jane@acme.test\"\n      }\n    }\n  ]\n}"}]},{"name":"Unallocate (Delete Allocation)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/allocations/{vendor_credit_allocation}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","allocations",":vendor_credit_allocation"],"variable":[{"key":"vendor_credit","value":"1","description":"Parent vendor credit ID"},{"key":"vendor_credit_allocation","value":"1","description":"Allocation ID to remove"}]},"description":"Remove an allocation from a vendor credit. Returns 404-style error if the allocation does not belong to the specified vendor credit. Restores the vendor credit's remaining balance and the purchase invoice's outstanding amount.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Auto-Apply Vendor Credit","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/auto-apply","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","auto-apply"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Automatically apply the credit's remaining balance to the supplier's oldest open purchase invoices (bills), oldest first, until the balance is exhausted or no eligible bills remain. No request body is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the allocations that were created. Returns 422 when nothing can be applied (e.g. no remaining balance or no open bills for the supplier)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/auto-apply","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","auto-apply"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Applied credit to 1 invoice(s).\",\n  \"data\": [\n    {\n      \"id\": 61,\n      \"vendor_credit_id\": 17,\n      \"purchase_invoice_id\": 88,\n      \"amount\": 250,\n      \"currency_rate\": 1,\n      \"fx_gain_loss\": 0,\n      \"allocated_at\": \"2026-07-07T09:00:00.000000Z\",\n      \"applied_at\": \"2026-07-07T09:00:00.000000Z\",\n      \"is_planned\": false,\n      \"notes\": null,\n      \"created_at\": \"2026-07-07T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-07T09:00:00.000000Z\",\n      \"purchase_invoice\": {\n        \"id\": 88,\n        \"supplier_invoice_number\": \"INV-2026-0088\",\n        \"purchase_invoice_date\": \"2026-06-28\",\n        \"purchase_order_id\": 310\n      },\n      \"allocated_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Operator\",\n        \"email\": \"jane@example.com\"\n      }\n    }\n  ]\n}"}]},{"name":"Record Vendor Credit Refund Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/paid","host":["{{baseUrl}}"],"path":["api","vendor-credits","paid"]},"description":"Record a refund payment against a vendor credit — money the supplier paid back instead of the credit being applied to bills.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFields: vendor_credit_id, payment_type_id, and amount are required; payment_date, external_reference (max 255 characters), and currency_id are optional. The amount must be positive and cannot exceed the credit's remaining balance; when currency_id is sent it must match the credit's currency. Negative amounts are stored as their absolute value.\n\nReturns the updated vendor credit including its payments.","body":{"mode":"raw","raw":"{\n  \"vendor_credit_id\": 17,\n  \"payment_type_id\": 2,\n  \"amount\": 100,\n  \"payment_date\": \"2026-07-07\",\n  \"external_reference\": \"REF-20260707\",\n  \"currency_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/paid","host":["{{baseUrl}}"],"path":["api","vendor-credits","paid"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 100,\n      \"remaining\": 150,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"partially_applied\",\n    \"payment_status_label\": \"Partially Applied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 150,\n    \"refunded_amount\": 100,\n    \"remaining_amount\": 150,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [\n      {\n        \"id\": 205,\n        \"amount\": 100,\n        \"cost\": null,\n        \"payment_date\": \"2026-07-07\",\n        \"payment_type\": {\n          \"id\": 2,\n          \"name\": \"Wire Transfer\"\n        },\n        \"external_reference\": \"REF-20260707\",\n        \"type\": \"Payment\",\n        \"currency_code\": \"USD\",\n        \"sales_credit_allocation\": null\n      }\n    ],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  },\n  \"message\": \"Payment created successfully.\"\n}"}]},{"name":"Update Vendor Credit Refund Payment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","payments",":payment"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"},{"key":"payment","value":"205","description":"Payment ID"}]},"description":"Update a refund payment previously recorded on a vendor credit. All fields are optional on update: payment_type_id, amount, payment_date, external_reference, currency_id. The updated amount cannot exceed the credit's remaining balance (the current payment's amount is excluded from that check), and currency_id must match the credit's currency.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe credit's payment status is recalculated after the update. Returns an error when the payment does not belong to the vendor credit.","body":{"mode":"raw","raw":"{\n  \"amount\": 150,\n  \"payment_date\": \"2026-07-08\",\n  \"external_reference\": \"REF-20260708\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","payments",":payment"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"},{"key":"payment","value":"205","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payment updated successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 150,\n      \"remaining\": 100,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"partially_applied\",\n    \"payment_status_label\": \"Partially Applied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 100,\n    \"refunded_amount\": 150,\n    \"remaining_amount\": 100,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [\n      {\n        \"id\": 205,\n        \"amount\": 150,\n        \"cost\": null,\n        \"payment_date\": \"2026-07-08\",\n        \"payment_type\": {\n          \"id\": 2,\n          \"name\": \"Wire Transfer\"\n        },\n        \"external_reference\": \"REF-20260708\",\n        \"type\": \"Payment\",\n        \"currency_code\": \"USD\",\n        \"sales_credit_allocation\": null\n      }\n    ],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"Delete Vendor Credit Refund Payment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","payments",":payment"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"},{"key":"payment","value":"205","description":"Payment ID"}]},"description":"Delete a refund payment from a vendor credit. The deleted amount becomes available on the credit again and the credit's payment status is recalculated.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated vendor credit. Returns an error when the payment does not belong to the vendor credit."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/payments/{payment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","payments",":payment"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"},{"key":"payment","value":"205","description":"Payment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payment 205 deleted successfully.\",\n  \"data\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"supplier_reference\": \"CM-88213\",\n    \"supplier_po_number\": \"PO-000310\",\n    \"credit_date\": \"2026-06-20\",\n    \"vendor_credit_note\": \"Credit for damaged goods on PO-000310\",\n    \"metadata\": null,\n    \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:00:00.000000Z\",\n    \"archived_at\": null,\n    \"fully_allocated_at\": null,\n    \"fully_refunded_at\": null,\n    \"is_settled\": false,\n    \"settlement_breakdown\": {\n      \"allocated\": 0,\n      \"refunded\": 0,\n      \"remaining\": 250,\n      \"total\": 250\n    },\n    \"credit_status\": \"open\",\n    \"credit_status_label\": \"Open\",\n    \"payment_status\": \"unapplied\",\n    \"payment_status_label\": \"Unapplied\",\n    \"is_for_overpayment\": false,\n    \"supplier_id\": 7,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\",\n      \"email\": \"accounts@acme-components.com\"\n    },\n    \"purchase_order_id\": 310,\n    \"purchase_order\": {\n      \"id\": 310,\n      \"purchase_order_number\": \"PO-000310\"\n    },\n    \"warehouse_id\": 2,\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"store_id\": null,\n    \"store\": null,\n    \"currency_id\": 1,\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"is_tax_included\": false,\n    \"tax_rate_id\": null,\n    \"tax_rate\": null,\n    \"tax_lines\": null,\n    \"tax_total\": 0,\n    \"tax_credit\": 0,\n    \"product_total\": 250,\n    \"total_credit\": 250,\n    \"total\": 250,\n    \"allocated_amount\": 0,\n    \"planned_allocation_amount\": 0,\n    \"available_to_allocate\": 250,\n    \"refunded_amount\": 0,\n    \"remaining_amount\": 250,\n    \"lines\": [\n      {\n        \"id\": 31,\n        \"vendor_credit_id\": 17,\n        \"purchase_order_line_id\": 771,\n        \"financial_line_id\": null,\n        \"product_id\": 55,\n        \"quantity\": 5,\n        \"amount\": 250,\n        \"unit_cost\": 50,\n        \"description\": \"Blue Widget (Medium)\",\n        \"tax_allocation\": 0,\n        \"tax_rate_id\": null,\n        \"tax_rate\": null,\n        \"nominal_code_id\": null,\n        \"nominal_code\": null,\n        \"is_product\": true,\n        \"restock_inventory\": false,\n        \"proration\": null,\n        \"subtotal\": 250,\n        \"created_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"updated_at\": \"2026-06-20T10:15:00.000000Z\",\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"barcode\": 123456789012,\n          \"image\": null,\n          \"is_lot_tracked\": false,\n          \"lot_tracking_method\": null,\n          \"shelf_life_days\": null,\n          \"near_expiry_threshold_days\": null,\n          \"min_remaining_shelf_life_days\": null\n        },\n        \"purchase_order_line\": {\n          \"id\": 771,\n          \"purchase_order_id\": 310,\n          \"product_id\": 55,\n          \"quantity\": 20,\n          \"unit_price\": 50,\n          \"purchase_order_number\": \"PO-000310\"\n        }\n      }\n    ],\n    \"line_item_count\": 1,\n    \"total_quantity\": 5,\n    \"first_line_sku\": \"WID-BLU-M\",\n    \"has_products\": true,\n    \"allocations\": [],\n    \"payments\": [],\n    \"shipments_count\": 0,\n    \"tags\": [\n      \"damaged-goods\"\n    ],\n    \"inventory_movements\": [],\n    \"link_reference\": \"VC-000017\",\n    \"link_type_label\": \"Vendor Credit\",\n    \"link_route\": \"/purchases/vendor-credits/17\"\n  }\n}"}]},{"name":"List Return Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"List all return shipments for a vendor credit, with lines, product, warehouse location, shipping method and creator eager-loaded.\n\nAuthentication: Requires Bearer token (PAT).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"vendor_credit_id\": 1,\n      \"warehouse_id\": 3,\n      \"shipment_date\": \"2026-06-20\",\n      \"status\": \"shipped\",\n      \"status_label\": \"Shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"shipping_method_id\": 2,\n      \"custom_carrier\": null,\n      \"expected_arrival_date\": \"2026-06-27\",\n      \"vendor_rma_number\": \"RMA-44821\",\n      \"notes\": \"Returning defective units to supplier.\",\n      \"created_by_user_id\": 5,\n      \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n      \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 2,\n        \"name\": \"UPS Ground\"\n      },\n      \"created_by_user\": {\n        \"id\": 5,\n        \"name\": \"Jane Doe\"\n      },\n      \"lines\": [\n        {\n          \"id\": 30,\n          \"vendor_credit_shipment_id\": 12,\n          \"vendor_credit_line_id\": 88,\n          \"warehouse_location_id\": 14,\n          \"quantity\": 10,\n          \"notes\": null,\n          \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n          \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n          \"warehouse_location\": {\n            \"id\": 14,\n            \"name\": \"A-01-01\"\n          },\n          \"vendor_credit_line\": {\n            \"id\": 88,\n            \"description\": \"Widget Blue\",\n            \"quantity\": 10,\n            \"unit_cost\": 4.25\n          },\n          \"product\": {\n            \"id\": 501,\n            \"sku\": \"WIDGET-BLUE\",\n            \"name\": \"Widget Blue\"\n          }\n        }\n      ],\n      \"total_quantity\": 10,\n      \"link_reference\": \"VCS-12\",\n      \"link_type_label\": \"Vendor Credit Shipment\",\n      \"link_route\": \"/purchases/vendor-credits/1/shipments/12\"\n    }\n  ]\n}"}]},{"name":"Create Return Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Create a return (RTV) shipment against an authorized vendor credit. For each restock product line, posts the outbound inventory movement (negative adjustment) and transitions the matching planned allocation to fulfilled.\n\nAuthentication: Requires Bearer token (PAT).\n\nBody fields:\n- `warehouse_id` (required, integer) — warehouse the goods ship out of.\n- `shipment_date` (required, date).\n- `status` (optional, one of: pending, shipped, delivered, cancelled — defaults to shipped).\n- `tracking_number` (optional, string, max 191).\n- `shipping_method_id` (optional, integer — exists in shipping_methods).\n- `custom_carrier` (optional, string, max 191).\n- `expected_arrival_date` (optional, date).\n- `vendor_rma_number` (optional, string, max 191).\n- `notes` (optional, string).\n- `lines` (required, array, min 1) — each line:\n    - `vendor_credit_line_id` (required, integer — exists in vendor_credit_lines).\n    - `quantity` (required, integer, min 1).\n    - `warehouse_location_id` (optional, integer — exists in warehouse_locations).\n    - `notes` (optional, string).\n    - `lot_allocation` (optional, array) — FEFO override for lot-tracked products. When supplied, the named FIFO layers are consumed instead of automatic FEFO. Each entry: `{ fifo_layer_id (required, exists in fifo_layers), quantity (required, > 0) }`. The allocation must sum to the line quantity, every layer must be an active layer of the line's product + the shipment warehouse with enough available quantity, and the tenant's lot override policy is enforced (under `enforce`, consuming expired stock or skipping the earliest-expiry FEFO lot is rejected with 422). Omit to consume by automatic FEFO/FIFO.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"shipment_date\": \"2026-06-20\",\n  \"status\": \"shipped\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"shipping_method_id\": 2,\n  \"custom_carrier\": null,\n  \"expected_arrival_date\": \"2026-06-27\",\n  \"vendor_rma_number\": \"RMA-44821\",\n  \"notes\": \"Returning defective units to supplier.\",\n  \"lines\": [\n    {\n      \"vendor_credit_line_id\": 88,\n      \"quantity\": 10,\n      \"warehouse_location_id\": 14,\n      \"notes\": null,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 9001,\n          \"quantity\": 6\n        },\n        {\n          \"fifo_layer_id\": 9002,\n          \"quantity\": 4\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_credit_id\": 1,\n    \"warehouse_id\": 3,\n    \"shipment_date\": \"2026-06-20\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"shipping_method_id\": 2,\n    \"custom_carrier\": null,\n    \"expected_arrival_date\": \"2026-06-27\",\n    \"vendor_rma_number\": \"RMA-44821\",\n    \"notes\": \"Returning defective units to supplier.\",\n    \"created_by_user_id\": 5,\n    \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 2,\n      \"name\": \"UPS Ground\"\n    },\n    \"created_by_user\": {\n      \"id\": 5,\n      \"name\": \"Jane Doe\"\n    },\n    \"lines\": [\n      {\n        \"id\": 30,\n        \"vendor_credit_shipment_id\": 12,\n        \"vendor_credit_line_id\": 88,\n        \"warehouse_location_id\": 14,\n        \"quantity\": 10,\n        \"notes\": null,\n        \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"warehouse_location\": {\n          \"id\": 14,\n          \"name\": \"A-01-01\"\n        },\n        \"vendor_credit_line\": {\n          \"id\": 88,\n          \"description\": \"Widget Blue\",\n          \"quantity\": 10,\n          \"unit_cost\": 4.25\n        },\n        \"product\": {\n          \"id\": 501,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Widget Blue\"\n        }\n      }\n    ],\n    \"total_quantity\": 10,\n    \"link_reference\": \"VCS-12\",\n    \"link_type_label\": \"Vendor Credit Shipment\",\n    \"link_route\": \"/purchases/vendor-credits/1/shipments/12\"\n  },\n  \"message\": \"Vendor credit shipment created successfully.\"\n}"}]},{"name":"Update Return Shipment","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]},"description":"Update an existing return (RTV) shipment. Reverses the prior movements/allocations, then re-posts them from the new lines. For each restock product line, posts the outbound inventory movement (negative adjustment) and transitions the matching planned allocation to fulfilled.\n\nAuthentication: Requires Bearer token (PAT).\n\nBody fields:\n- `warehouse_id` (required, integer) — warehouse the goods ship out of.\n- `shipment_date` (required, date).\n- `status` (optional, one of: pending, shipped, delivered, cancelled — defaults to shipped).\n- `tracking_number` (optional, string, max 191).\n- `shipping_method_id` (optional, integer — exists in shipping_methods).\n- `custom_carrier` (optional, string, max 191).\n- `expected_arrival_date` (optional, date).\n- `vendor_rma_number` (optional, string, max 191).\n- `notes` (optional, string).\n- `lines` (required, array, min 1) — each line:\n    - `vendor_credit_line_id` (required, integer — exists in vendor_credit_lines).\n    - `quantity` (required, integer, min 1).\n    - `warehouse_location_id` (optional, integer — exists in warehouse_locations).\n    - `notes` (optional, string).\n    - `lot_allocation` (optional, array) — FEFO override for lot-tracked products. When supplied, the named FIFO layers are consumed instead of automatic FEFO. Each entry: `{ fifo_layer_id (required, exists in fifo_layers), quantity (required, > 0) }`. The allocation must sum to the line quantity, every layer must be an active layer of the line's product + the shipment warehouse with enough available quantity, and the tenant's lot override policy is enforced (under `enforce`, consuming expired stock or skipping the earliest-expiry FEFO lot is rejected with 422). Omit to consume by automatic FEFO/FIFO.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3,\n  \"shipment_date\": \"2026-06-20\",\n  \"status\": \"shipped\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"shipping_method_id\": 2,\n  \"custom_carrier\": null,\n  \"expected_arrival_date\": \"2026-06-27\",\n  \"vendor_rma_number\": \"RMA-44821\",\n  \"notes\": \"Returning defective units to supplier.\",\n  \"lines\": [\n    {\n      \"vendor_credit_line_id\": 88,\n      \"quantity\": 10,\n      \"warehouse_location_id\": 14,\n      \"notes\": null,\n      \"lot_allocation\": [\n        {\n          \"fifo_layer_id\": 9001,\n          \"quantity\": 6\n        },\n        {\n          \"fifo_layer_id\": 9002,\n          \"quantity\": 4\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_credit_id\": 1,\n    \"warehouse_id\": 3,\n    \"shipment_date\": \"2026-06-20\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"shipping_method_id\": 2,\n    \"custom_carrier\": null,\n    \"expected_arrival_date\": \"2026-06-27\",\n    \"vendor_rma_number\": \"RMA-44821\",\n    \"notes\": \"Returning defective units to supplier.\",\n    \"created_by_user_id\": 5,\n    \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 2,\n      \"name\": \"UPS Ground\"\n    },\n    \"created_by_user\": {\n      \"id\": 5,\n      \"name\": \"Jane Doe\"\n    },\n    \"lines\": [\n      {\n        \"id\": 30,\n        \"vendor_credit_shipment_id\": 12,\n        \"vendor_credit_line_id\": 88,\n        \"warehouse_location_id\": 14,\n        \"quantity\": 10,\n        \"notes\": null,\n        \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"warehouse_location\": {\n          \"id\": 14,\n          \"name\": \"A-01-01\"\n        },\n        \"vendor_credit_line\": {\n          \"id\": 88,\n          \"description\": \"Widget Blue\",\n          \"quantity\": 10,\n          \"unit_cost\": 4.25\n        },\n        \"product\": {\n          \"id\": 501,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Widget Blue\"\n        }\n      }\n    ],\n    \"total_quantity\": 10,\n    \"link_reference\": \"VCS-12\",\n    \"link_type_label\": \"Vendor Credit Shipment\",\n    \"link_route\": \"/purchases/vendor-credits/1/shipments/12\"\n  },\n  \"message\": \"Vendor credit shipment created successfully.\"\n}"}]},{"name":"Delete Return Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]},"description":"Delete a return shipment. Reverses the posted inventory movements (returning stock to its FIFO layers) and reverts the matching fulfilled allocations back to allocated.\n\nAuthentication: Requires Bearer token (PAT).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor credit shipment VCS-12 deleted successfully.\"\n}"}]},{"name":"Update Return Shipment Status","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}/status","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment","status"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]},"description":"Update only the status of a return shipment. Lightweight — no inventory/allocation side effects.\n\nBody: `status` (required, one of: pending, shipped, delivered, cancelled).\n\nAuthentication: Requires Bearer token (PAT).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"status\": \"delivered\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/shipments/{vendor_credit_shipment}/status","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","shipments",":vendor_credit_shipment","status"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"},{"key":"vendor_credit_shipment","value":"12","description":"Vendor credit shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"vendor_credit_id\": 1,\n    \"warehouse_id\": 3,\n    \"shipment_date\": \"2026-06-20\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"shipping_method_id\": 2,\n    \"custom_carrier\": null,\n    \"expected_arrival_date\": \"2026-06-27\",\n    \"vendor_rma_number\": \"RMA-44821\",\n    \"notes\": \"Returning defective units to supplier.\",\n    \"created_by_user_id\": 5,\n    \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 2,\n      \"name\": \"UPS Ground\"\n    },\n    \"created_by_user\": {\n      \"id\": 5,\n      \"name\": \"Jane Doe\"\n    },\n    \"lines\": [\n      {\n        \"id\": 30,\n        \"vendor_credit_shipment_id\": 12,\n        \"vendor_credit_line_id\": 88,\n        \"warehouse_location_id\": 14,\n        \"quantity\": 10,\n        \"notes\": null,\n        \"created_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"updated_at\": \"2026-06-20T14:03:11.000000Z\",\n        \"warehouse_location\": {\n          \"id\": 14,\n          \"name\": \"A-01-01\"\n        },\n        \"vendor_credit_line\": {\n          \"id\": 88,\n          \"description\": \"Widget Blue\",\n          \"quantity\": 10,\n          \"unit_cost\": 4.25\n        },\n        \"product\": {\n          \"id\": 501,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Widget Blue\"\n        }\n      }\n    ],\n    \"total_quantity\": 10,\n    \"link_reference\": \"VCS-12\",\n    \"link_type_label\": \"Vendor Credit Shipment\",\n    \"link_route\": \"/purchases/vendor-credits/1/shipments/12\"\n  },\n  \"message\": \"Vendor credit shipment created successfully.\"\n}"}]},{"name":"Get Return Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits","shipments",":shipment"],"variable":[{"key":"shipment","value":"9","description":"Vendor credit shipment ID"}]},"description":"Get a single return shipment (goods sent back to the supplier under a vendor credit) with its lines, warehouse, shipping method, and creator. The response also includes a summary of the parent vendor credit (number, status, and supplier) under the vendor_credit key.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","vendor-credits","shipments",":shipment"],"variable":[{"key":"shipment","value":"9","description":"Vendor credit shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9,\n    \"vendor_credit_id\": 17,\n    \"warehouse_id\": 2,\n    \"shipment_date\": \"2026-07-02\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"shipping_method_id\": 4,\n    \"custom_carrier\": null,\n    \"expected_arrival_date\": \"2026-07-09\",\n    \"vendor_rma_number\": \"RMA-5521\",\n    \"notes\": null,\n    \"created_by_user_id\": 3,\n    \"created_at\": \"2026-07-02T15:20:00.000000Z\",\n    \"updated_at\": \"2026-07-02T15:20:00.000000Z\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shipping_method\": {\n      \"id\": 4,\n      \"name\": \"UPS Ground\"\n    },\n    \"created_by_user\": {\n      \"id\": 3,\n      \"name\": \"Jane Operator\"\n    },\n    \"lines\": [\n      {\n        \"id\": 14,\n        \"vendor_credit_shipment_id\": 9,\n        \"vendor_credit_line_id\": 31,\n        \"warehouse_location_id\": null,\n        \"quantity\": 5,\n        \"notes\": null,\n        \"created_at\": \"2026-07-02T15:20:00.000000Z\",\n        \"updated_at\": \"2026-07-02T15:20:00.000000Z\",\n        \"warehouse_location\": null,\n        \"vendor_credit_line\": {\n          \"id\": 31,\n          \"description\": \"Blue Widget (Medium)\",\n          \"quantity\": 5,\n          \"unit_cost\": 50\n        },\n        \"product\": {\n          \"id\": 55,\n          \"sku\": \"WID-BLU-M\",\n          \"name\": \"Blue Widget (Medium)\"\n        }\n      }\n    ],\n    \"total_quantity\": 5,\n    \"link_reference\": \"1Z999AA10123456784\",\n    \"link_type_label\": \"Vendor Credit Shipment\",\n    \"link_route\": \"/purchases/vendor-credits/17/shipments/9\"\n  },\n  \"vendor_credit\": {\n    \"id\": 17,\n    \"vendor_credit_number\": \"VC-000017\",\n    \"credit_status\": \"open\",\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Components Ltd\"\n    }\n  }\n}"}]},{"name":"Get Return Shipment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-credits","shipments",":shipment","activity-log"],"variable":[{"key":"shipment","value":"9","description":"Vendor credit shipment ID"}]},"description":"Paginated audit trail for a return shipment and its lines, newest first. Each entry records the event, the changed attributes, and who made the change.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse filter[search] to match against the user's name, the event, or the recorded change details."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-credits","shipments",":shipment","activity-log"],"variable":[{"key":"shipment","value":"9","description":"Vendor credit shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3021,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"VendorCreditShipment\",\n      \"subject_id\": 9,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"shipped\"\n        },\n        \"old\": {\n          \"status\": \"pending\"\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-07-01T08:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/shipments/9/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/shipments/9/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}{{domain}}/api/vendor-credits/shipments/9/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/vendor-credits/shipments/9/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Preview Vendor Credit Ship Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/ship-impact","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","ship-impact"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Get a read-only preview of the order allocations that creating a return shipment for this vendor credit's restock lines would consume. Each row is one product whose stock the shipment would remove, split into free, soft-reserved and hard-allocated quantities, and lists the affected sales-order allocations highest-priority first so you can see which orders — and which printed shipping labels — would be demoted or voided before you post the shipment.\n\nThis endpoint makes no changes.\n\nResponse fields:\n- `data[].product_id` / `product_sku` / `product_name` — the product the action would consume stock for.\n- `data[].shortfall_quantity` — how much more than the available quantity the action removes; stock goes negative when greater than 0.\n- `data[].unallocated_quantity` / `soft_allocated_quantity` / `hard_allocated_quantity` — the free / soft-reserved / hard-allocated (label-printed) split of the consumed quantity.\n- `data[].affected_allocations[]` — the order allocations that would be consumed, highest priority first. `allocation_type` is `soft` or `hard`. For hard rows, `fulfillment_id` and `carrier` identify the printed label and `carrier_void_supported` / `voidable_status` (`voidable` or otherwise) indicate whether the label can be voided through the API.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/ship-impact","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","ship-impact"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 123,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget 500ml\",\n      \"shortfall_quantity\": 0,\n      \"unallocated_quantity\": 4,\n      \"soft_allocated_quantity\": 3,\n      \"hard_allocated_quantity\": 2,\n      \"affected_allocations\": [\n        {\n          \"allocation_id\": 88213,\n          \"allocation_type\": \"soft\",\n          \"sales_order_id\": 4521,\n          \"order_number\": \"SO-10442\",\n          \"customer_name\": \"Acme Retail\",\n          \"fulfillment_id\": null,\n          \"carrier\": null,\n          \"carrier_void_supported\": null,\n          \"voidable_status\": null,\n          \"voidable_detail\": null,\n          \"quantity\": 3\n        },\n        {\n          \"allocation_id\": 88240,\n          \"allocation_type\": \"hard\",\n          \"sales_order_id\": 4530,\n          \"order_number\": \"SO-10450\",\n          \"customer_name\": \"Beta Wholesale\",\n          \"fulfillment_id\": 77120,\n          \"carrier\": \"ups\",\n          \"carrier_void_supported\": true,\n          \"voidable_status\": \"voidable\",\n          \"voidable_detail\": null,\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Bulk Archive Vendor Credits","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/archive","host":["{{baseUrl}}"],"path":["api","vendor-credits","archive"]},"description":"Bulk archive vendor credits.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Body (either form):**\n```json\n{ \"ids\": [1, 2, 3] }\n```\nor apply-to-all with filters:\n```json\n{ \"apply_to_all\": true, \"filters\": { \"supplier_id\": 5 } }\n```","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Unarchive Vendor Credits","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/unarchive","host":["{{baseUrl}}"],"path":["api","vendor-credits","unarchive"]},"description":"Bulk unarchive vendor credits. Same body shape as Bulk Archive.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Void Vendor Credits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/bulk-void","host":["{{baseUrl}}"],"path":["api","vendor-credits","bulk-void"]},"description":"Void multiple vendor credits at once. Target credits either by an explicit ids array, or set apply_to_all to true with an optional filters object to void every credit matching the filter.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nVoiding reverses each credit's inventory movements and accounting transaction. Credits that cannot be voided (e.g. they have active allocations) are skipped and counted in the response message.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    17,\n    18\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/bulk-void","host":["{{baseUrl}}"],"path":["api","vendor-credits","bulk-void"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Voided 1 vendor credit(s). Skipped 1 (have active allocations).\"\n}"}]},{"name":"List Vendor Credit Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/notes","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","notes"],"variable":[{"key":"vendorCredit","value":"1","description":"Vendor credit ID"}]},"description":"Paginated list of notes on the vendor credit, ordered newest first. Each note includes its author (`user`) relation.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Add Vendor Credit Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/notes","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","notes"],"variable":[{"key":"vendorCredit","value":"1","description":"Vendor credit ID"}]},"description":"Add a note to the vendor credit. `note` is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"note\": \"Called supplier, they confirmed the credit will be applied on next bill.\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Vendor Credit Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/notes/{noteId}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","notes",":noteId"],"variable":[{"key":"vendorCredit","value":"1","description":"Vendor credit ID"},{"key":"noteId","value":"1","description":"Note ID"}]},"description":"Delete a single note from a vendor credit. Idempotent: returns success even if the note does not exist.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Toggle Vendor Credit Note Pin","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","notes",":noteId","toggle-pin"],"variable":[{"key":"vendorCredit","value":"17","description":"Vendor credit ID"},{"key":"noteId","value":"12","description":"Note ID"}]},"description":"Toggle the pinned state of a note on a vendor credit. Pinned notes sort to the top of the note list. No request body is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated note. Returns 404 when the note does not belong to the vendor credit."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/notes/{noteId}/toggle-pin","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","notes",":noteId","toggle-pin"],"variable":[{"key":"vendorCredit","value":"17","description":"Vendor credit ID"},{"key":"noteId","value":"12","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"note\": \"Called the supplier — replacement stock ships next week.\",\n    \"is_pinned\": true,\n    \"user_id\": 3,\n    \"notable_type\": \"App\\\\Models\\\\VendorCredit\",\n    \"notable_id\": 17,\n    \"created_at\": \"2026-07-01T08:05:00.000000Z\",\n    \"updated_at\": \"2026-07-07T09:40:00.000000Z\",\n    \"user\": {\n      \"id\": 3,\n      \"name\": \"Jane Operator\",\n      \"email\": \"jane@example.com\"\n    }\n  },\n  \"message\": \"Note pinned\"\n}"}]},{"name":"Get Vendor Credit Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","activity-log"],"variable":[{"key":"vendorCredit","value":"17","description":"Vendor credit ID"}]},"description":"Paginated audit trail for a vendor credit, newest first. Covers changes to the credit itself, its lines, and its return shipments and shipment lines. Each entry records the event, the changed attributes, and who made the change.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse filter[search] to match against the user's name, the event, or the recorded change details."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/activity-log","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","activity-log"],"variable":[{"key":"vendorCredit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3021,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"VendorCredit\",\n      \"subject_id\": 17,\n      \"properties\": {\n        \"attributes\": {\n          \"credit_status\": \"open\"\n        },\n        \"old\": {\n          \"credit_status\": \"draft\"\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-07-01T08:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/vendor-credits/17/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Vendor Credit FIFO Layer Usages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/fifo-layer-usages","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","fifo-layer-usages"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Read-only audit trail of the FIFO cost layers consumed or referenced when the vendor credit was authorized. Each usage records the credited quantity, the unit cost taken from the layer, whether the layer's available quantity was actually decremented, and details of the layer, product, and credit line involved.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/fifo-layer-usages","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","fifo-layer-usages"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"vendor_credit_line_id\": 31,\n      \"fifo_layer_id\": 4410,\n      \"quantity\": 5,\n      \"unit_cost\": 50,\n      \"line_total\": 250,\n      \"decremented_layer\": true,\n      \"created_at\": \"2026-06-20T10:20:00.000000Z\",\n      \"fifo_layer\": {\n        \"id\": 4410,\n        \"fifo_layer_date\": \"2026-05-12\",\n        \"original_quantity\": 20,\n        \"fulfilled_quantity\": 8,\n        \"available_quantity\": 12,\n        \"avg_cost\": 50,\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrderLine\",\n        \"link_id\": 771,\n        \"link_reference\": \"PO-000310\",\n        \"warehouse\": {\n          \"id\": 2,\n          \"name\": \"Main Warehouse\"\n        }\n      },\n      \"product\": {\n        \"id\": 55,\n        \"sku\": \"WID-BLU-M\",\n        \"name\": \"Blue Widget (Medium)\"\n      },\n      \"vendor_credit_line\": {\n        \"id\": 31,\n        \"description\": \"Blue Widget (Medium)\",\n        \"quantity\": 5\n      },\n      \"link_reference\": \"PO-000310\",\n      \"link_type_label\": \"FIFO Layer\",\n      \"link_route\": \"/inventory/fifo-layers/4410\"\n    }\n  ]\n}"}]},{"name":"List Vendor Credit Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/inventory-movements","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","inventory-movements"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]},"description":"Paginated inventory movements posted against a vendor credit: write-off movements on credit lines and outbound movements from return shipments. Each row includes the product, warehouse, quantity, and the FIFO layer and unit cost where known; unit_cost_provisional is true for rows whose cost is estimated from the product's current unit cost because no layer was consumed.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSortable by id, inventory_movement_date, type, inventory_status, quantity, reference, and created_at (default: -inventory_movement_date). Text filters on type, inventory_status, and reference support the advanced-filter operators (is / contains / starts_with / etc.); quantity supports numeric comparisons and inventory_movement_date / created_at support date comparisons."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/inventory-movements","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","inventory-movements"],"variable":[{"key":"vendor_credit","value":"17","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 7710,\n      \"type\": \"write_off\",\n      \"inventory_status\": \"on_hand\",\n      \"quantity\": -5,\n      \"reference\": \"VC-000017\",\n      \"link_type\": \"App\\\\Models\\\\VendorCreditLine\",\n      \"link_id\": 31,\n      \"parent_link_id\": 17,\n      \"detail_link_id\": null,\n      \"product_id\": 55,\n      \"product_sku\": \"WID-BLU-M\",\n      \"product_name\": \"Blue Widget (Medium)\",\n      \"warehouse_id\": 2,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"unit_cost\": 50,\n      \"unit_cost_provisional\": false,\n      \"layer\": {\n        \"name\": \"PO-000310\",\n        \"fifo_layer_id\": 4410\n      },\n      \"inventory_movement_date\": \"2026-06-20T10:20:00.000000Z\",\n      \"created_at\": \"2026-06-20T10:20:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/inventory-movements?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/inventory-movements?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}{{domain}}/api/vendor-credits/17/inventory-movements?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/vendor-credits/17/inventory-movements\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Vendor Credit PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/pdf","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","pdf"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Render the vendor credit as a PDF using the configured Vendor Credit template. Returns a PDF file (Content-Type: application/pdf) displayed inline. Customize the template in Settings → PDF Templates → Vendor Credit."}},{"name":"Generate Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendor_credit}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendor_credit","generate-accounting-transaction"],"variable":[{"key":"vendor_credit","value":"1","description":"Vendor credit ID"}]},"description":"Generate (or regenerate) the local accounting transaction for the vendor credit. Builds the transaction lines from the vendor credit and saves the accounting transaction. Returns an accounting transaction object with eager-loaded lines and nominal codes.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"List Vendor Credit Attachments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]},"description":"List all attachments for the given vendor credit, newest first. Each attachment includes the uploader (when loaded), a ready-to-use download_url, and OCR scan state (ocr_status: null, processing, pending_review, confirmed, failed, rejected, or duplicate_detected).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"file_name\": \"credit-memo-acme.pdf\",\n      \"file_size\": 482133,\n      \"mime_type\": \"application/pdf\",\n      \"created_at\": \"2026-06-01T14:22:08.000000Z\",\n      \"uploaded_by\": {\n        \"id\": 3,\n        \"name\": \"Jane Doe\"\n      },\n      \"download_url\": \"https://app.sku.io/api/vendor-credits/12/attachments/5/download\",\n      \"ocr_status\": \"pending_review\",\n      \"ocr_error_message\": null,\n      \"ocr_processed_at\": \"2026-06-01T14:24:51.000000Z\"\n    }\n  ]\n}"}]},{"name":"Upload Vendor Credit Attachment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]},"description":"Upload a new attachment to the vendor credit. multipart/form-data with a single `file` field.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nValidation:\n- file: required, max 20 MB (20480 KB), mimes: pdf, png, jpg, jpeg, webp\n- Empty (0-byte) files are rejected\n\nReturns 201 with the created attachment. Returns 422 if the vendor credit is archived or the file fails validation.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"file_name\": \"credit-memo-acme.pdf\",\n    \"file_size\": 482133,\n    \"mime_type\": \"application/pdf\",\n    \"created_at\": \"2026-06-01T14:22:08.000000Z\",\n    \"uploaded_by\": {\n      \"id\": 3,\n      \"name\": \"Jane Doe\"\n    },\n    \"download_url\": \"https://app.sku.io/api/vendor-credits/12/attachments/5/download\",\n    \"ocr_status\": null,\n    \"ocr_error_message\": null,\n    \"ocr_processed_at\": null\n  }\n}"}]},{"name":"Delete Vendor Credit Attachment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]},"description":"Delete an attachment (removes the stored file and the record). Returns 404 if the attachment does not belong to the vendor credit, and 422 if the vendor credit is archived.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the credit is archived/voided or the attachment's OCR scan is in progress."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Attachment deleted.\"\n}"}]},{"name":"Download Vendor Credit Attachment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/download","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","download"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]},"description":"Stream the attachment file as a download (Content-Disposition: attachment). The response is the binary file content with the original file name and MIME type — not JSON. Returns 404 if the attachment does not belong to the vendor credit or the file is missing from storage.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"View Attachment Inline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/view","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","view"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]},"description":"Stream the attachment file inline (Content-Disposition: inline) for in-browser preview of PDFs and images. The response is the binary file content — not JSON. Returns 404 if the attachment does not belong to the vendor credit or the file is missing from storage.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Upload Credit Memo for OCR","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/upload","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr","upload"]},"description":"Upload a credit memo PDF to begin OCR extraction. multipart/form-data.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nValidation:\n- file: required, PDF only (mimes: pdf), max 20 MB (20480 KB)\n- supplier_id: optional integer, must exist in suppliers\n- purchase_order_id: optional integer, must exist in purchase_orders. Pre-links the extraction to that PO; derives the supplier hint from the PO when supplier_id is omitted. A pre-linked PO wins over OCR's own po_number match.\n\nProcessing is asynchronous — the response includes a tracked_job_log_id for the tracked job log endpoints. Poll Get Extraction until status moves from processing to pending_review (or failed / duplicate_detected). Returns 422 if Vendor Credit OCR is not enabled in Settings → Invoice OCR.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"supplier_id","type":"text","value":""},{"key":"purchase_order_id","type":"text","value":""}]}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/upload","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr","upload"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"extraction_id\": 12,\n    \"tracked_job_log_id\": 3301,\n    \"status\": \"processing\"\n  },\n  \"message\": \"OCR processing started\"\n}"}]},{"name":"Get Vendor Credit Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Get a vendor credit OCR extraction record with extracted header fields, matched lines, and related records (supplier, purchase order, duplicate vendor credit, referenced purchase invoice, candidate purchase orders).\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nHeader fields: credit_number, credit_date, supplier_name, total, subtotal, tax_amount, currency_code, po_number, document_type, plus matched_supplier_id / matched_supplier_name / matched_purchase_order_id / matched_purchase_order_number.\n\nLine match_status values: exact, fuzzy, discount_confirmation, unmatched.\n\n**Classification fields:** `document_type` (`credit_memo` | `invoice` | `unknown`), `detection_signals` (array of raw classifier signals, e.g. `keyword:credit memo`, `doc_number:CM prefix`, `total:negative`; `null` when not classified) and `auto_routed` (`true` when the document arrived via the supplier-invoice intake and was automatically routed to the credit memo queue by the document type classifier)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"status\": \"pending_review\",\n    \"source\": \"upload\",\n    \"file_url\": \"https://app.sku.io/api/vendor-credits/ocr/12/pdf\",\n    \"file_name\": \"credit-memo-acme.pdf\",\n    \"page_count\": 2,\n    \"header\": {\n      \"credit_number\": \"CM-10422\",\n      \"credit_date\": \"2026-05-28\",\n      \"supplier_name\": \"Acme Supply Co\",\n      \"total\": 65,\n      \"subtotal\": 65,\n      \"tax_amount\": 0,\n      \"currency_code\": \"USD\",\n      \"po_number\": \"PO-2026-0144\",\n      \"document_type\": \"credit_memo\",\n      \"matched_supplier_id\": 7,\n      \"matched_supplier_name\": \"Acme Supply Co\",\n      \"matched_purchase_order_id\": 144,\n      \"matched_purchase_order_number\": \"PO-2026-0144\"\n    },\n    \"is_matched_supplier\": true,\n    \"extracted_supplier_name\": \"Acme Supply Co\",\n    \"lines\": [\n      {\n        \"id\": \"f4f0c2ab-9a31-4a2e-8f0a-3d7e1f0b6c11\",\n        \"description\": \"Blue Widget - damaged in transit\",\n        \"qty\": 4,\n        \"unit_price\": 12.5,\n        \"line_total\": 50,\n        \"confidence\": 0.96,\n        \"raw_sku\": \"WIDGET-BLU\",\n        \"match_status\": \"exact\",\n        \"matched_product_id\": 555,\n        \"matched_product_name\": \"Blue Widget\",\n        \"matched_product_sku\": \"WIDGET-BLU\",\n        \"saved_financial_line_type_id\": null,\n        \"discount_variance\": null,\n        \"po_expected_discount\": null\n      },\n      {\n        \"id\": \"0b2a6f7e-2c44-49d2-9a18-77c1f3a9e802\",\n        \"description\": \"Freight rebate\",\n        \"qty\": 1,\n        \"unit_price\": 15,\n        \"line_total\": 15,\n        \"confidence\": 0.91,\n        \"raw_sku\": null,\n        \"match_status\": \"unmatched\",\n        \"matched_product_id\": null,\n        \"matched_product_name\": null,\n        \"matched_product_sku\": null,\n        \"saved_financial_line_type_id\": null,\n        \"discount_variance\": null,\n        \"po_expected_discount\": null\n      }\n    ],\n    \"azure_cost_usd\": 0.02,\n    \"confidence_score\": 0.94,\n    \"error_message\": null,\n    \"document_type\": \"credit_memo\",\n    \"detection_signals\": [\n      \"keyword:credit memo\",\n      \"total:negative\"\n    ],\n    \"auto_routed\": true,\n    \"vendor_credit_id\": null,\n    \"vendor_credit_attachment_id\": null,\n    \"tracked_job_log_id\": 3301,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Supply Co\"\n    },\n    \"purchase_order\": {\n      \"id\": 144,\n      \"purchase_order_number\": \"PO-2026-0144\",\n      \"purchase_order_date\": \"2026-04-02\"\n    },\n    \"duplicate_vendor_credit\": null,\n    \"referenced_purchase_invoice\": null,\n    \"candidate_purchase_orders\": [\n      {\n        \"id\": 144,\n        \"purchase_order_number\": \"PO-2026-0144\",\n        \"purchase_order_date\": \"2026-04-02\",\n        \"order_status\": \"received\"\n      }\n    ],\n    \"created_at\": \"2026-06-01T14:22:08.000000Z\"\n  }\n}"}]},{"name":"Delete Vendor Credit Extraction","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Delete a vendor credit OCR extraction record and its associated stored file. Returns 204 No Content on success. Returns 422 if the extraction is confirmed (confirmed extractions cannot be deleted).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the extraction is confirmed or currently processing."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Stream Vendor Credit Extraction PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/pdf","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","pdf"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Stream the original credit memo PDF through the backend (avoids CORS issues with direct storage URLs). The response is binary PDF content (Content-Type: application/pdf, Content-Disposition: inline) — not JSON. Returns 404 if the file is no longer available in storage.\n\n**Required scope: `orders:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Re-scan Vendor Credit Extraction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/rescan","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","rescan"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Re-dispatch OCR processing for an existing extraction (e.g. after a failed scan or to pick up improved matching). Asynchronous — returns a new tracked_job_log_id. Returns 422 if the extraction is already confirmed or the original file is no longer available.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/rescan","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","rescan"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"extraction_id\": 12,\n    \"tracked_job_log_id\": 3305,\n    \"status\": \"processing\"\n  },\n  \"message\": \"Re-scan started.\"\n}"}]},{"name":"Create Vendor Credit from Extraction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/create-credit","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","create-credit"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Create a draft vendor credit from a reviewed OCR extraction. The OCR'd PDF is automatically attached to the new credit and the extraction is marked confirmed.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields (all top-level fields optional unless noted):\n- supplier_id: optional integer, must exist in suppliers\n- purchase_order_id: optional integer, must exist in purchase_orders\n- warehouse_id: optional integer, must exist in warehouses\n- currency_id: optional integer, must exist in currencies\n- credit_date: optional date\n- supplier_reference: optional string, max 255\n- vendor_credit_note: optional string\n- lines: REQUIRED array, min 1 element\n\nLine fields (per element of `lines`):\n- quantity: required, numeric, min 1\n- amount: required, numeric, must be less than 100000\n- purchase_order_line_id: optional integer (existing PO line)\n- product_id: optional integer (existing product)\n- description: optional string, max 255\n- unit_cost: optional numeric\n- nominal_code_id: optional integer (for non-product/financial lines)\n- is_product: optional boolean\n- restock_inventory: optional boolean\n\nReturns 201 with the new vendor_credit_id. Returns 422 with a message when the manager rejects the request (e.g. duplicate or invalid state).\n\nThe created credit's vendor_credit_number defaults to the supplier's credit reference (extracted credit_number / supplier_reference) when that number is not already in use; otherwise the next local VC-#### number is generated.\n\n**Reference fields:**\n- `vendor_credit_number` (string, max 255) — The supplier's credit memo number. On create it becomes the credit's number (falls back to the OCR-detected `credit_number`, auto-generates `VC-xxxxx` if taken). On apply it renames the credit — skipped silently if another credit already uses that number.\n- `supplier_po_number` (string, max 255) — The PO number printed on the supplier's memo, recorded as TEXT only (defaults from the OCR-detected `po_number` on create). It does not link a purchase order; use `purchase_order_id` for an actual link.\n- `supplier_reference` (string, max 255) — Any additional reference on the document (e.g. the vendor's internal credit-order number). No longer auto-filled with the memo number.","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 7,\n  \"purchase_order_id\": 144,\n  \"warehouse_id\": 2,\n  \"currency_id\": 1,\n  \"credit_date\": \"2026-05-28\",\n  \"supplier_reference\": \"CM-10422\",\n  \"supplier_po_number\": \"001\",\n  \"vendor_credit_number\": 1669,\n  \"vendor_credit_note\": \"Credit memo CM-10422 created from OCR upload.\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"product_id\": 555,\n      \"description\": \"Blue Widget - damaged in transit\",\n      \"quantity\": 4,\n      \"unit_cost\": 12.5,\n      \"amount\": 50,\n      \"nominal_code_id\": null,\n      \"is_product\": true,\n      \"restock_inventory\": false\n    },\n    {\n      \"purchase_order_line_id\": null,\n      \"product_id\": null,\n      \"description\": \"Freight rebate\",\n      \"quantity\": 1,\n      \"unit_cost\": 15,\n      \"amount\": 15,\n      \"nominal_code_id\": 27,\n      \"is_product\": false,\n      \"restock_inventory\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/create-credit","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","create-credit"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"vendor_credit_id\": 311,\n    \"extraction_id\": 12\n  },\n  \"message\": \"Vendor credit created from OCR extraction.\"\n}"}]},{"name":"Attach Extraction to Existing Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/attach-to-credit","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","attach-to-credit"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Attach the OCR'd PDF to an existing vendor credit that was created manually (instead of creating a new credit from the extraction).\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- vendor_credit_id: required integer, must exist in vendor_credits\n\nOnly extractions in pending_review or duplicate_detected status can be attached (422 otherwise). Returns 201 with the created attachment_id.","body":{"mode":"raw","raw":"{\n  \"vendor_credit_id\": 311\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/attach-to-credit","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","attach-to-credit"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"vendor_credit_id\": 311,\n    \"extraction_id\": 12,\n    \"attachment_id\": 57\n  },\n  \"message\": \"OCR document attached to existing vendor credit.\"\n}"}]},{"name":"Apply OCR Results to Vendor Credit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/ocr-apply","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","ocr-apply"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]},"description":"Apply reviewed OCR extraction results onto an existing vendor credit (header values and/or lines).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nIMPORTANT: the payload is FLAT — supplier_reference, credit_date, and vendor_credit_note are top-level fields. There is no header wrapper object.\n\nBody fields:\n- extraction_id: required integer, must exist in vendor_credit_ocr_extractions\n- line_mode: optional string, append or replace (how extracted lines are merged into the credit's existing lines)\n- supplier_reference: optional (sometimes) nullable string, max 255\n- credit_date: optional (sometimes) nullable date\n- vendor_credit_note: optional (sometimes) nullable string\n- lines: optional array\n\nLine fields (per element of `lines`):\n- quantity: required, numeric, min 1\n- amount: required, numeric, must be less than 100000\n- purchase_order_line_id: optional integer (existing PO line)\n- product_id: optional integer (existing product)\n- description: optional string, max 255\n- unit_cost: optional numeric\n- nominal_code_id: optional integer (for non-product/financial lines)\n- is_product: optional boolean\n- restock_inventory: optional boolean\n\nReturns 200 on success. Returns 422 with a message when the manager rejects the apply (e.g. invalid state).\n\n**Reference fields:**\n- `vendor_credit_number` (string, max 255) — The supplier's credit memo number. On create it becomes the credit's number (falls back to the OCR-detected `credit_number`, auto-generates `VC-xxxxx` if taken). On apply it renames the credit — skipped silently if another credit already uses that number.\n- `supplier_po_number` (string, max 255) — The PO number printed on the supplier's memo, recorded as TEXT only (defaults from the OCR-detected `po_number` on create). It does not link a purchase order; use `purchase_order_id` for an actual link.\n- `supplier_reference` (string, max 255) — Any additional reference on the document (e.g. the vendor's internal credit-order number). No longer auto-filled with the memo number.","body":{"mode":"raw","raw":"{\n  \"extraction_id\": 12,\n  \"line_mode\": \"replace\",\n  \"supplier_reference\": \"CM-10422\",\n  \"supplier_po_number\": \"001\",\n  \"vendor_credit_number\": 1669,\n  \"credit_date\": \"2026-05-28\",\n  \"vendor_credit_note\": \"Updated from OCR extraction CM-10422.\",\n  \"lines\": [\n    {\n      \"purchase_order_line_id\": 101,\n      \"product_id\": 555,\n      \"description\": \"Blue Widget - damaged in transit\",\n      \"quantity\": 4,\n      \"unit_cost\": 12.5,\n      \"amount\": 50,\n      \"nominal_code_id\": null,\n      \"is_product\": true,\n      \"restock_inventory\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/ocr-apply","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","ocr-apply"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"vendor_credit_id\": 311,\n    \"extraction_id\": 12\n  },\n  \"message\": \"OCR results applied to vendor credit.\"\n}"}]},{"name":"Reclassify as Supplier Invoice","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/reclassify-as-invoice","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","reclassify-as-invoice"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]},"description":"Reclassify a vendor credit extraction as a supplier invoice extraction — used when the scanned document turns out to be an invoice, not a credit memo. The vendor credit extraction is converted and a purchase invoice extraction is returned. No request body. Returns 422 if the extraction is already confirmed.\n\n**Required scope: `orders:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the extraction is confirmed or not in a reviewable status (pending review / duplicate detected)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/ocr/{extraction}/reclassify-as-invoice","host":["{{baseUrl}}"],"path":["api","vendor-credits","ocr",":extraction","reclassify-as-invoice"],"variable":[{"key":"extraction","value":"12","description":"Vendor credit OCR extraction ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Reclassified as supplier invoice.\",\n  \"data\": {\n    \"purchase_invoice_extraction_id\": 88\n  }\n}"}]},{"name":"Get Latest Attachment Extraction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","ocr"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]},"description":"Get the latest OCR extraction for a vendor credit attachment, including extracted header, matched lines, and related records. Returns data: null (200) when the attachment has never been scanned. Returns 404 if the attachment does not belong to the vendor credit.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Classification fields:** `document_type` (`credit_memo` | `invoice` | `unknown`), `detection_signals` (array of raw classifier signals, e.g. `keyword:credit memo`, `doc_number:CM prefix`, `total:negative`; `null` when not classified) and `auto_routed` (`true` when the document arrived via the supplier-invoice intake and was automatically routed to the credit memo queue by the document type classifier)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","ocr"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"status\": \"pending_review\",\n    \"source\": \"upload\",\n    \"file_url\": \"https://app.sku.io/api/vendor-credits/ocr/12/pdf\",\n    \"file_name\": \"credit-memo-acme.pdf\",\n    \"page_count\": 2,\n    \"header\": {\n      \"credit_number\": \"CM-10422\",\n      \"credit_date\": \"2026-05-28\",\n      \"supplier_name\": \"Acme Supply Co\",\n      \"total\": 65,\n      \"subtotal\": 65,\n      \"tax_amount\": 0,\n      \"currency_code\": \"USD\",\n      \"po_number\": \"PO-2026-0144\",\n      \"document_type\": \"credit_memo\",\n      \"matched_supplier_id\": 7,\n      \"matched_supplier_name\": \"Acme Supply Co\",\n      \"matched_purchase_order_id\": 144,\n      \"matched_purchase_order_number\": \"PO-2026-0144\"\n    },\n    \"is_matched_supplier\": true,\n    \"extracted_supplier_name\": \"Acme Supply Co\",\n    \"lines\": [\n      {\n        \"id\": \"f4f0c2ab-9a31-4a2e-8f0a-3d7e1f0b6c11\",\n        \"description\": \"Blue Widget - damaged in transit\",\n        \"qty\": 4,\n        \"unit_price\": 12.5,\n        \"line_total\": 50,\n        \"confidence\": 0.96,\n        \"raw_sku\": \"WIDGET-BLU\",\n        \"match_status\": \"exact\",\n        \"matched_product_id\": 555,\n        \"matched_product_name\": \"Blue Widget\",\n        \"matched_product_sku\": \"WIDGET-BLU\",\n        \"saved_financial_line_type_id\": null,\n        \"discount_variance\": null,\n        \"po_expected_discount\": null\n      },\n      {\n        \"id\": \"0b2a6f7e-2c44-49d2-9a18-77c1f3a9e802\",\n        \"description\": \"Freight rebate\",\n        \"qty\": 1,\n        \"unit_price\": 15,\n        \"line_total\": 15,\n        \"confidence\": 0.91,\n        \"raw_sku\": null,\n        \"match_status\": \"unmatched\",\n        \"matched_product_id\": null,\n        \"matched_product_name\": null,\n        \"matched_product_sku\": null,\n        \"saved_financial_line_type_id\": null,\n        \"discount_variance\": null,\n        \"po_expected_discount\": null\n      }\n    ],\n    \"azure_cost_usd\": 0.02,\n    \"confidence_score\": 0.94,\n    \"error_message\": null,\n    \"document_type\": \"credit_memo\",\n    \"detection_signals\": [\n      \"keyword:credit memo\",\n      \"total:negative\"\n    ],\n    \"auto_routed\": true,\n    \"vendor_credit_id\": null,\n    \"vendor_credit_attachment_id\": null,\n    \"tracked_job_log_id\": 3301,\n    \"supplier\": {\n      \"id\": 7,\n      \"name\": \"Acme Supply Co\"\n    },\n    \"purchase_order\": {\n      \"id\": 144,\n      \"purchase_order_number\": \"PO-2026-0144\",\n      \"purchase_order_date\": \"2026-04-02\"\n    },\n    \"duplicate_vendor_credit\": null,\n    \"referenced_purchase_invoice\": null,\n    \"candidate_purchase_orders\": [\n      {\n        \"id\": 144,\n        \"purchase_order_number\": \"PO-2026-0144\",\n        \"purchase_order_date\": \"2026-04-02\",\n        \"order_status\": \"received\"\n      }\n    ],\n    \"created_at\": \"2026-06-01T14:22:08.000000Z\"\n  }\n}"}]},{"name":"Scan Attachment with OCR","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","ocr"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]},"description":"Trigger OCR processing for an existing vendor credit attachment. Only PDF attachments can be scanned (422 for other MIME types). Asynchronous — returns a tracked_job_log_id for the tracked job log endpoints. Returns 404 if the attachment does not belong to the vendor credit, and 422 if Vendor Credit OCR is not enabled in Settings → Invoice OCR.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/{vendorCredit}/attachments/{attachment}/ocr","host":["{{baseUrl}}"],"path":["api","vendor-credits",":vendorCredit","attachments",":attachment","ocr"],"variable":[{"key":"vendorCredit","value":"12","description":"Vendor credit ID"},{"key":"attachment","value":"5","description":"Vendor credit attachment ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"extraction_id\": 12,\n    \"tracked_job_log_id\": 3301,\n    \"attachment_id\": 5,\n    \"status\": \"processing\"\n  },\n  \"message\": \"OCR processing started\"\n}"}]},{"name":"Export Vendor Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/list/export","host":["{{baseUrl}}"],"path":["api","vendor-credits","list","export"]},"description":"Download an Excel/CSV export of vendor credits.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: a binary file download (xlsx or csv), NOT JSON. Columns: ID, Credit #, Supplier Ref, Supplier, PO #, Credit Date, Status, Payment Status, Warehouse, Currency, Tax Total, Total Credit, Allocated, Refunded, Remaining, Settled, Note, Created At.\n\nQuery params:\n- format: xlsx (default) or csv\n- scope: 'filtered' (default — respects the same filters as the list endpoint) or 'selected'\n- ids: comma-separated IDs (only when scope=selected)"}},{"name":"Download Vendor Credit Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-credits/import/template","host":["{{baseUrl}}"],"path":["api","vendor-credits","import","template"]},"description":"Download a multi-sheet XLSX import template pre-filled with sample rows, a field guide, and reference data (stores, currencies, warehouses, tax rates, nominal codes, suppliers) from your account.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: a binary XLSX file download, NOT JSON. Use this template as the starting point for the import — fill the 'Import Here' sheet, then upload it in the import wizard."}},{"name":"Validate Vendor Credit Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/import/validate","host":["{{baseUrl}}"],"path":["api","vendor-credits","import","validate"]},"description":"Validate and preview mapped import rows BEFORE importing. No database writes occur — safe to call repeatedly.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResolves supplier / purchase order / store / currency / warehouse / SKU / nominal code / tax rate names to IDs, groups flat rows into credits (by id, then vendor_credit_number, then purchase_order_number), and computes an upsert action per credit:\n- create: no existing credit matched\n- update: matched an existing DRAFT credit\n- blocked: matched a credit that cannot be updated (archived, voided, closed, refunded, allocated, or already authorized/open). The block_reason is returned for display.\n\nEach row accepts all template columns: id, vendor_credit_number, credit_date, purchase_order_number, supplier_name, supplier_email, supplier_id, warehouse_name, currency_code, store_name, supplier_reference, vendor_credit_note, sku, purchase_order_line_id, description, quantity, amount, unit_cost, nominal_code, tax_rate, is_product, restock_inventory.\n\nMax 50000 rows per call.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"id\": \"\",\n      \"vendor_credit_number\": \"VC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"purchase_order_number\": \"\",\n      \"supplier_name\": \"Acme Supplies\",\n      \"supplier_email\": \"\",\n      \"supplier_id\": \"\",\n      \"warehouse_name\": \"Main Warehouse\",\n      \"currency_code\": \"USD\",\n      \"store_name\": \"\",\n      \"supplier_reference\": \"CN-55321\",\n      \"vendor_credit_note\": \"Damaged on arrival\",\n      \"sku\": \"WIDGET-001\",\n      \"purchase_order_line_id\": \"\",\n      \"description\": \"Blue Widget - Large\",\n      \"quantity\": \"2\",\n      \"amount\": \"19.99\",\n      \"unit_cost\": \"\",\n      \"nominal_code\": \"\",\n      \"tax_rate\": \"\",\n      \"is_product\": \"true\",\n      \"restock_inventory\": \"false\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/import/validate","host":["{{baseUrl}}"],"path":["api","vendor-credits","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"vendor_credits\": [\n    {\n      \"group_key\": \"vcn:vc-001\",\n      \"id\": null,\n      \"vendor_credit_number\": \"VC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"supplier_reference\": \"CN-55321\",\n      \"vendor_credit_note\": \"Damaged on arrival\",\n      \"action\": \"create\",\n      \"match_reason\": null,\n      \"block_reason\": null,\n      \"existing_vendor_credit\": null,\n      \"purchase_order\": null,\n      \"supplier\": {\n        \"id\": 12,\n        \"name\": \"Acme Supplies\",\n        \"email\": \"orders@acme.com\"\n      },\n      \"store\": null,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"errors\": [],\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 845,\n          \"product_name\": \"Blue Widget - Large\",\n          \"purchase_order_line_id\": null,\n          \"description\": \"Blue Widget - Large\",\n          \"quantity\": 2,\n          \"amount\": 19.99,\n          \"unit_cost\": null,\n          \"nominal_code_id\": null,\n          \"tax_rate_id\": null,\n          \"is_product\": true,\n          \"restock_inventory\": false,\n          \"line_total\": 39.98,\n          \"errors\": []\n        }\n      ],\n      \"total_quantity\": 2,\n      \"total_amount\": 39.98\n    }\n  ],\n  \"summary\": {\n    \"total_vendor_credits\": 1,\n    \"total_line_items\": 1,\n    \"total_errors\": 0,\n    \"total_will_create\": 1,\n    \"total_will_update\": 0,\n    \"total_blocked\": 0\n  }\n}"}]},{"name":"Import Vendor Credits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-credits/import","host":["{{baseUrl}}"],"path":["api","vendor-credits","import"]},"description":"Execute the import — upsert vendor credits from validated data (typically the output of the Validate Import endpoint).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nUpsert behavior:\n- Rows with no matched existing credit are CREATED in DRAFT status so you can review and authorize them.\n- Rows matching an existing DRAFT credit are UPDATED.\n- Rows with action=blocked are rejected (archived / voided / closed / refunded / allocated / already-authorized credits cannot be updated via import).\n\ncontinue_on_error (default false): when true, each credit is imported in its own transaction and failures are collected into 'skipped' instead of aborting the whole import. When false, the entire import runs in one transaction and any failure rolls everything back.\n\nA per-user lock serializes concurrent imports.\n\nReturns 201 when any credit was created, otherwise 200.","body":{"mode":"raw","raw":"{\n  \"continue_on_error\": false,\n  \"vendor_credits\": [\n    {\n      \"group_key\": \"vcn:vc-001\",\n      \"id\": null,\n      \"action\": \"create\",\n      \"match_reason\": null,\n      \"block_reason\": null,\n      \"existing_vendor_credit\": null,\n      \"vendor_credit_number\": \"VC-001\",\n      \"credit_date\": \"2026-04-01\",\n      \"supplier_reference\": \"CN-55321\",\n      \"vendor_credit_note\": \"Damaged on arrival\",\n      \"purchase_order\": null,\n      \"supplier\": {\n        \"id\": 12,\n        \"name\": \"Acme Supplies\",\n        \"email\": \"orders@acme.com\"\n      },\n      \"store\": null,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\"\n      },\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      },\n      \"lines\": [\n        {\n          \"sku\": \"WIDGET-001\",\n          \"product_id\": 845,\n          \"product_name\": \"Blue Widget - Large\",\n          \"purchase_order_line_id\": null,\n          \"description\": \"Blue Widget - Large\",\n          \"quantity\": 2,\n          \"amount\": 19.99,\n          \"unit_cost\": null,\n          \"nominal_code_id\": null,\n          \"tax_rate_id\": null,\n          \"is_product\": true,\n          \"restock_inventory\": false\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-credits/import","host":["{{baseUrl}}"],"path":["api","vendor-credits","import"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"created\": [\n    {\n      \"id\": 501,\n      \"vendor_credit_number\": \"VC-001\"\n    }\n  ],\n  \"updated\": [],\n  \"skipped\": [],\n  \"summary\": {\n    \"total\": 1,\n    \"created\": 1,\n    \"updated\": 0,\n    \"skipped\": 0\n  }\n}"}]}]},{"name":"Vendor Deposits","item":[{"name":"List Vendor Deposits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","vendor-deposits"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of vendor deposits. Supports Spatie QueryBuilder filters and sorting.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Note:** bank details are omitted from list responses — `payee_bank_details` and `supplier.wire_instructions` are only returned by detail-type endpoints (show, action responses).\n\nEach deposit includes `attachments_count` (number of attached documents) and `attachment_filenames` (their file names). Sortable by `attachments_count`. Filter with `filter[attachments_count]` (e.g. `filter[attachments_count.is]=0` for deposits with no documents) or `filter[attachment_filename]` to match an attached document's file name."}},{"name":"Create Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits","host":["{{baseUrl}}"],"path":["api","vendor-deposits"]},"description":"Create a new vendor deposit. Validated by CreateVendorDepositRequest. Returns 201 with the created deposit.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Proforma invoice / payment request fields:**\n- `payee_bank_details` (string, nullable, max 2000) — payee bank block captured from the supplier's proforma invoice. If it matches the supplier profile's `wire_instructions` (case/whitespace-insensitive) it is normalized to `null` (\"per supplier profile\").\n- `bank_details_verified` (boolean, default false) — acknowledgment that details differing from the supplier profile were verified out-of-band. When true (and a differing snapshot is present), `bank_details_verified_at`/`bank_details_verified_by` are stamped. A deposit with an UNVERIFIED differing snapshot saves as draft but cannot be submitted for approval (422).","body":{"mode":"raw","raw":"{\n  \"supplier_id\": 1,\n  \"purchase_order_id\": null,\n  \"currency_id\": 1,\n  \"currency_rate\": 1,\n  \"currency_id_tenant_snapshot\": 1,\n  \"amount\": 500,\n  \"amount_in_tenant_currency\": 500,\n  \"deposit_date\": \"2026-04-12\",\n  \"due_date\": \"2026-05-12\",\n  \"external_reference\": \"WIRE-2026-0001\",\n  \"notes\": \"50% upfront deposit\",\n  \"tax_amount\": 0,\n  \"tax_amount_in_tenant_currency\": 0,\n  \"tax_lines\": [],\n  \"payee_bank_details\": \"Bank of East Asia, Hong Kong\\nSWIFT: BEASHKHH\\nAccount: 01551468050442\\nBeneficiary: Example Trading Co., Limited\",\n  \"bank_details_verified\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Vendor Deposit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Retrieve a single vendor deposit with its relations (supplier, purchase order, payments, applications, refunds).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Update Vendor Deposit","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Update a vendor deposit. All fields are optional (`sometimes`).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Editability by status:** draft and pending-approval deposits accept the full field set. Approved/paid/applied deposits accept only the descriptive fields — `deposit_date`, `due_date`, `external_reference`, `notes`; sending any other field returns 422 with the locked field(s) named. Terminal deposits (cancelled, void, refunded, written off) cannot be updated at all.\n\n**Bank details:** `payee_bank_details` may be updated on draft/pending deposits. Changing the snapshot without `bank_details_verified: true` clears the verification stamps — the deposit must then be re-verified before submit-for-approval succeeds. Details matching the supplier profile collapse to null.","body":{"mode":"raw","raw":"{\n  \"amount\": 600,\n  \"deposit_date\": \"2026-04-12\",\n  \"due_date\": \"2026-05-30\",\n  \"external_reference\": \"WIRE-2026-0001-REV\",\n  \"notes\": \"Revised deposit amount\",\n  \"payee_bank_details\": \"Bank: Different Bank\\nAccount: 11112222\",\n  \"bank_details_verified\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Vendor Deposit","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Delete a vendor deposit. Returns 204 No Content.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Payment Request Routing Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/payment-request-routing","host":["{{baseUrl}}"],"path":["api","vendor-deposits","payment-request-routing"]},"description":"Preview where a payment request would route before submitting. Drives the \"Payment request will be sent to …\" indicator in the Record Proforma Invoice drawer and the draft-deposit hint.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Routing precedence:** matching approval levels → the site-wide default payer (AccountingSettings.vendor_deposit_default_payer_user_id, set in Accounting Settings) → the legacy amount threshold.\n\n**Response fields:**\n- `mode` — `approval_levels` | `payer` | `self_payer` | `threshold_approval` | `auto_approve`\n- `payer` — `{id, name, email}` of the resolved site-wide payer, or null\n- `payer_configured` — true when a payer id is configured even if unresolvable (admins are notified in that case)\n- `levels_count` — matching approval levels when mode=approval_levels\n\n`auto_approve` means nothing is configured: submitting will auto-approve without notifying anyone — the UI warns and links to Accounting Settings.\n\n`self_payer` means the acting user is themselves the configured payer: there is no one to send a request to, so submitting approves the deposit immediately and the payment can be recorded directly."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/payment-request-routing","host":["{{baseUrl}}"],"path":["api","vendor-deposits","payment-request-routing"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"mode\": \"self_payer\",\n  \"payer\": {\n    \"id\": 3,\n    \"name\": \"Kalvin M.\",\n    \"email\": \"kalvin@example.com\"\n  },\n  \"payer_configured\": true,\n  \"levels_count\": 0\n}"}]},{"name":"Submit Vendor Deposit for Approval","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/submit-for-approval","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","submit-for-approval"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Submit a draft deposit for payment approval.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Routing precedence:** matching approval levels → the configured default payer → the amount threshold → auto-approve.\n\n- **Approval levels match** — the deposit enters the approval chain (status `pending_approval`).\n- **A default payer is configured** — the payment request is sent to that payer (status `pending_approval`).\n- **The acting user IS the configured payer** — there is no one to send a request to, so the deposit is approved immediately (status `approved`) and a payment can be recorded right away.\n- **Nothing configured** — submission auto-approves without notifying anyone.\n\nDeposits whose payee bank details differ from the supplier profile must have those details verified before submission.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Approve Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approve","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approve"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Approve a pending deposit.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Approve Vendor Deposit (Without Payment)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approve-only","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approve-only"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Approve a deposit without recording a payment. Status becomes APPROVED; amount_paid is unchanged. Use this when payment will be recorded later via /payments.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Reject Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/reject","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","reject"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Reject a pending deposit with an optional reason.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Incorrect supplier\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Cancel Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/cancel","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","cancel"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Cancel a vendor deposit.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Write Off Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/write-off","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","write-off"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Write off the remaining balance of a deposit with an optional reason.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"reason\": \"Unrecoverable balance\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Duplicate Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/duplicate","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","duplicate"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Duplicate an existing deposit. Returns 201 with the new deposit.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Void Vendor Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/void","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","void"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Void a vendor deposit with an optional reason. Voiding reverses the deposit's accounting impact and removes it from open-liability reporting. Deposits with applied or refunded amounts cannot be voided.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated deposit.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Duplicate entry created in error\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/void","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","void"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"deposit_number\": \"DEP-000042\",\n  \"status\": \"void\",\n  \"status_label\": \"Void\",\n  \"supplier_id\": 7,\n  \"supplier\": {\n    \"id\": 7,\n    \"name\": \"Acme Components Ltd\",\n    \"email\": \"accounts@acme-components.com\",\n    \"wire_instructions\": \"Routing 026009593, account 4426123456\",\n    \"link_route\": \"/v2/crm/suppliers/7\"\n  },\n  \"purchase_order_id\": 310,\n  \"payment_term_schedule_line_index\": 1,\n  \"inbound_shipment_id\": null,\n  \"payment_term_schedule_snapshot\": {\n    \"label\": \"30% deposit on order\",\n    \"trigger_event\": \"po_approved\",\n    \"percentage\": 30\n  },\n  \"is_ownership_transfer\": false,\n  \"ownership_transferred_at\": null,\n  \"purchase_order\": {\n    \"id\": 310,\n    \"purchase_order_number\": \"PO-000310\",\n    \"link_route\": \"/v2/orders/purchase-orders/310\",\n    \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"link_type_label\": \"Purchase Order\",\n    \"link_id\": 310,\n    \"link_reference\": \"PO-000310\"\n  },\n  \"currency_id\": 1,\n  \"currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"currency_rate\": 1,\n  \"currency_id_tenant_snapshot\": 1,\n  \"tenant_currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"amount\": 1500,\n  \"amount_in_tenant_currency\": 1500,\n  \"amount_paid\": 0,\n  \"amount_paid_in_tenant_currency\": 0,\n  \"amount_applied\": 0,\n  \"amount_applied_in_tenant_currency\": 0,\n  \"amount_refunded\": 0,\n  \"amount_refunded_in_tenant_currency\": 0,\n  \"amount_written_off\": 0,\n  \"amount_written_off_in_tenant_currency\": 0,\n  \"available_balance\": 0,\n  \"available_balance_in_tenant_currency\": 0,\n  \"tax_amount\": 0,\n  \"tax_amount_in_tenant_currency\": 0,\n  \"tax_lines\": null,\n  \"deposit_date\": \"2026-06-15\",\n  \"due_date\": \"2026-07-20\",\n  \"paid_at\": null,\n  \"external_reference\": \"WIRE-20260615-042\",\n  \"payee_bank_details\": null,\n  \"bank_details_verified_at\": null,\n  \"bank_details_verified_by\": null,\n  \"bank_details_verified_by_user\": null,\n  \"payment_requested_at\": null,\n  \"payment_requested_by\": null,\n  \"payment_requested_by_user\": null,\n  \"remittance_sent_at\": null,\n  \"notes\": \"30% deposit for PO-000310\",\n  \"proportional_apply_enabled\": false,\n  \"auto_apply_enabled\": null,\n  \"auto_apply_effective\": true,\n  \"approved_by\": null,\n  \"approver\": null,\n  \"approved_at\": null,\n  \"approval_notes\": null,\n  \"submit_action\": null,\n  \"submit_action_label\": null,\n  \"created_by\": 3,\n  \"creator\": {\n    \"id\": 3,\n    \"name\": \"Jane Operator\"\n  },\n  \"applications\": [],\n  \"payments\": [],\n  \"refunds\": [],\n  \"created_at\": \"2026-06-15T14:02:11+00:00\",\n  \"updated_at\": \"2026-07-01T09:30:00+00:00\",\n  \"archived_at\": null\n}"}]},{"name":"Revert Vendor Deposit to Draft","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","revert-to-draft"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Revert a submitted or approved vendor deposit back to draft with an optional reason. Any pending approval chain is discarded so a resubmission rebuilds it from scratch.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated deposit.","body":{"mode":"raw","raw":"{\n  \"reason\": \"Amount needs to be corrected before payment\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/revert-to-draft","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","revert-to-draft"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"deposit_number\": \"DEP-000042\",\n  \"status\": \"draft\",\n  \"status_label\": \"Draft\",\n  \"supplier_id\": 7,\n  \"supplier\": {\n    \"id\": 7,\n    \"name\": \"Acme Components Ltd\",\n    \"email\": \"accounts@acme-components.com\",\n    \"wire_instructions\": \"Routing 026009593, account 4426123456\",\n    \"link_route\": \"/v2/crm/suppliers/7\"\n  },\n  \"purchase_order_id\": 310,\n  \"payment_term_schedule_line_index\": 1,\n  \"inbound_shipment_id\": null,\n  \"payment_term_schedule_snapshot\": {\n    \"label\": \"30% deposit on order\",\n    \"trigger_event\": \"po_approved\",\n    \"percentage\": 30\n  },\n  \"is_ownership_transfer\": false,\n  \"ownership_transferred_at\": null,\n  \"purchase_order\": {\n    \"id\": 310,\n    \"purchase_order_number\": \"PO-000310\",\n    \"link_route\": \"/v2/orders/purchase-orders/310\",\n    \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"link_type_label\": \"Purchase Order\",\n    \"link_id\": 310,\n    \"link_reference\": \"PO-000310\"\n  },\n  \"currency_id\": 1,\n  \"currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"currency_rate\": 1,\n  \"currency_id_tenant_snapshot\": 1,\n  \"tenant_currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"amount\": 1500,\n  \"amount_in_tenant_currency\": 1500,\n  \"amount_paid\": 0,\n  \"amount_paid_in_tenant_currency\": 0,\n  \"amount_applied\": 0,\n  \"amount_applied_in_tenant_currency\": 0,\n  \"amount_refunded\": 0,\n  \"amount_refunded_in_tenant_currency\": 0,\n  \"amount_written_off\": 0,\n  \"amount_written_off_in_tenant_currency\": 0,\n  \"available_balance\": 0,\n  \"available_balance_in_tenant_currency\": 0,\n  \"tax_amount\": 0,\n  \"tax_amount_in_tenant_currency\": 0,\n  \"tax_lines\": null,\n  \"deposit_date\": \"2026-06-15\",\n  \"due_date\": \"2026-07-20\",\n  \"paid_at\": null,\n  \"external_reference\": \"WIRE-20260615-042\",\n  \"payee_bank_details\": null,\n  \"bank_details_verified_at\": null,\n  \"bank_details_verified_by\": null,\n  \"bank_details_verified_by_user\": null,\n  \"payment_requested_at\": null,\n  \"payment_requested_by\": null,\n  \"payment_requested_by_user\": null,\n  \"remittance_sent_at\": null,\n  \"notes\": \"30% deposit for PO-000310\",\n  \"proportional_apply_enabled\": false,\n  \"auto_apply_enabled\": null,\n  \"auto_apply_effective\": true,\n  \"approved_by\": null,\n  \"approver\": null,\n  \"approved_at\": null,\n  \"approval_notes\": null,\n  \"submit_action\": \"approve\",\n  \"submit_action_label\": \"Approve Deposit\",\n  \"created_by\": 3,\n  \"creator\": {\n    \"id\": 3,\n    \"name\": \"Jane Operator\"\n  },\n  \"applications\": [],\n  \"payments\": [],\n  \"refunds\": [],\n  \"created_at\": \"2026-06-15T14:02:11+00:00\",\n  \"updated_at\": \"2026-07-01T09:30:00+00:00\",\n  \"archived_at\": null\n}"}]},{"name":"Link Vendor Deposit to Purchase Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/purchase-order","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","purchase-order"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Link a vendor deposit to a purchase order, or unlink it by passing null. The purchase order must belong to the same supplier as the deposit.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns the updated deposit.","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 310\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/purchase-order","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","purchase-order"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 42,\n  \"deposit_number\": \"DEP-000042\",\n  \"status\": \"draft\",\n  \"status_label\": \"Draft\",\n  \"supplier_id\": 7,\n  \"supplier\": {\n    \"id\": 7,\n    \"name\": \"Acme Components Ltd\",\n    \"email\": \"accounts@acme-components.com\",\n    \"wire_instructions\": \"Routing 026009593, account 4426123456\",\n    \"link_route\": \"/v2/crm/suppliers/7\"\n  },\n  \"purchase_order_id\": 310,\n  \"payment_term_schedule_line_index\": 1,\n  \"inbound_shipment_id\": null,\n  \"payment_term_schedule_snapshot\": {\n    \"label\": \"30% deposit on order\",\n    \"trigger_event\": \"po_approved\",\n    \"percentage\": 30\n  },\n  \"is_ownership_transfer\": false,\n  \"ownership_transferred_at\": null,\n  \"purchase_order\": {\n    \"id\": 310,\n    \"purchase_order_number\": \"PO-000310\",\n    \"link_route\": \"/v2/orders/purchase-orders/310\",\n    \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"link_type_label\": \"Purchase Order\",\n    \"link_id\": 310,\n    \"link_reference\": \"PO-000310\"\n  },\n  \"currency_id\": 1,\n  \"currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"currency_rate\": 1,\n  \"currency_id_tenant_snapshot\": 1,\n  \"tenant_currency\": {\n    \"id\": 1,\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"amount\": 1500,\n  \"amount_in_tenant_currency\": 1500,\n  \"amount_paid\": 0,\n  \"amount_paid_in_tenant_currency\": 0,\n  \"amount_applied\": 0,\n  \"amount_applied_in_tenant_currency\": 0,\n  \"amount_refunded\": 0,\n  \"amount_refunded_in_tenant_currency\": 0,\n  \"amount_written_off\": 0,\n  \"amount_written_off_in_tenant_currency\": 0,\n  \"available_balance\": 0,\n  \"available_balance_in_tenant_currency\": 0,\n  \"tax_amount\": 0,\n  \"tax_amount_in_tenant_currency\": 0,\n  \"tax_lines\": null,\n  \"deposit_date\": \"2026-06-15\",\n  \"due_date\": \"2026-07-20\",\n  \"paid_at\": null,\n  \"external_reference\": \"WIRE-20260615-042\",\n  \"payee_bank_details\": null,\n  \"bank_details_verified_at\": null,\n  \"bank_details_verified_by\": null,\n  \"bank_details_verified_by_user\": null,\n  \"payment_requested_at\": null,\n  \"payment_requested_by\": null,\n  \"payment_requested_by_user\": null,\n  \"remittance_sent_at\": null,\n  \"notes\": \"30% deposit for PO-000310\",\n  \"proportional_apply_enabled\": false,\n  \"auto_apply_enabled\": null,\n  \"auto_apply_effective\": true,\n  \"approved_by\": null,\n  \"approver\": null,\n  \"approved_at\": null,\n  \"approval_notes\": null,\n  \"submit_action\": \"approve\",\n  \"submit_action_label\": \"Approve Deposit\",\n  \"created_by\": 3,\n  \"creator\": {\n    \"id\": 3,\n    \"name\": \"Jane Operator\"\n  },\n  \"applications\": [],\n  \"payments\": [],\n  \"refunds\": [],\n  \"created_at\": \"2026-06-15T14:02:11+00:00\",\n  \"updated_at\": \"2026-07-01T09:30:00+00:00\",\n  \"archived_at\": null\n}"}]},{"name":"List Vendor Deposit Approval Steps","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"List the approval chain for a vendor deposit, ordered by level. Each step records its approval level, assigned approver, status (pending, approved, or rejected), and who actioned it.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSteps are created when a deposit that crosses an approval-level threshold is submitted for approval."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 11,\n      \"vendor_deposit_id\": 42,\n      \"approval_level_id\": 2,\n      \"level_order\": 1,\n      \"level_name\": \"Finance Review\",\n      \"status\": \"approved\",\n      \"approver_user_id\": 5,\n      \"approver_user\": {\n        \"id\": 5,\n        \"name\": \"Maya Finance\",\n        \"email\": \"maya@example.com\"\n      },\n      \"actioned_by\": 5,\n      \"actioned_by_user\": {\n        \"id\": 5,\n        \"name\": \"Maya Finance\"\n      },\n      \"actioned_at\": \"2026-07-07T10:12:00+00:00\",\n      \"notes\": \"Amount matches the PO schedule.\",\n      \"created_at\": \"2026-06-15T14:05:00+00:00\",\n      \"updated_at\": \"2026-07-07T10:12:00+00:00\"\n    },\n    {\n      \"id\": 12,\n      \"vendor_deposit_id\": 42,\n      \"approval_level_id\": 3,\n      \"level_order\": 2,\n      \"level_name\": \"CFO Sign-off\",\n      \"status\": \"pending\",\n      \"approver_user_id\": 6,\n      \"approver_user\": {\n        \"id\": 6,\n        \"name\": \"Sam Chief\",\n        \"email\": \"sam@example.com\"\n      },\n      \"actioned_by\": null,\n      \"actioned_by_user\": null,\n      \"actioned_at\": null,\n      \"notes\": null,\n      \"created_at\": \"2026-06-15T14:05:00+00:00\",\n      \"updated_at\": \"2026-06-15T14:05:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Approve Vendor Deposit Approval Step","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps/approve","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps","approve"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Approve the next pending approval step on a vendor deposit, with optional notes (max 1000 characters). Only the step's assigned approver may action it. When the final step is approved the deposit transitions to approved.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFails when there are no pending steps, when the caller is not the assigned approver, or when the deposit's bank details differ from the supplier profile and have not been verified.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Amount matches the PO schedule.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps/approve","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps","approve"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"vendor_deposit_id\": 42,\n    \"approval_level_id\": 2,\n    \"level_order\": 1,\n    \"level_name\": \"Finance Review\",\n    \"status\": \"approved\",\n    \"approver_user_id\": 5,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Maya Finance\",\n      \"email\": \"maya@example.com\"\n    },\n    \"actioned_by\": 5,\n    \"actioned_by_user\": {\n      \"id\": 5,\n      \"name\": \"Maya Finance\"\n    },\n    \"actioned_at\": \"2026-07-07T10:12:00+00:00\",\n    \"notes\": \"Amount matches the PO schedule.\",\n    \"created_at\": \"2026-06-15T14:05:00+00:00\",\n    \"updated_at\": \"2026-07-07T10:12:00+00:00\"\n  }\n}"}]},{"name":"Reject Vendor Deposit Approval Step","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps/reject","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps","reject"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Reject the deposit at the next pending approval step, with optional notes (max 1000 characters). Only the step's assigned approver may action it. Rejection transitions the deposit back to draft.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"notes\": \"Deposit percentage does not match the agreed terms.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/approval-steps/reject","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","approval-steps","reject"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"vendor_deposit_id\": 42,\n    \"approval_level_id\": 2,\n    \"level_order\": 1,\n    \"level_name\": \"Finance Review\",\n    \"status\": \"rejected\",\n    \"approver_user_id\": 5,\n    \"approver_user\": {\n      \"id\": 5,\n      \"name\": \"Maya Finance\",\n      \"email\": \"maya@example.com\"\n    },\n    \"actioned_by\": 5,\n    \"actioned_by_user\": {\n      \"id\": 5,\n      \"name\": \"Maya Finance\"\n    },\n    \"actioned_at\": \"2026-07-07T10:12:00+00:00\",\n    \"notes\": \"Deposit percentage does not match the agreed terms.\",\n    \"created_at\": \"2026-06-15T14:05:00+00:00\",\n    \"updated_at\": \"2026-06-15T14:05:00+00:00\"\n  }\n}"}]},{"name":"Record Payment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/payments","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","payments"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Record a payment against a vendor deposit (full or partial), with the payment date, currency rate, and optional reference.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nPayments can also be recorded on a **draft** deposit — useful for capturing a payment that was already made in the past. The deposit then moves directly to Partially Paid / Paid without a payment request or approval step.\n\nThe payment amount cannot exceed the deposit's outstanding balance (deposit amount minus payments already recorded). Deposits whose payee bank details differ from the supplier profile must have those details verified before payments can be recorded. Payments cannot be recorded against cancelled, void, refunded, or written-off deposits.","body":{"mode":"raw","raw":"{\n  \"amount_in_deposit_currency\": 250,\n  \"currency_rate\": 1,\n  \"payment_date\": \"2026-04-12\",\n  \"payment_method_id\": 1,\n  \"external_reference\": \"WIRE-REF-001\",\n  \"bank_account_id\": null,\n  \"paid_externally\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refund Deposit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/refunds","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","refunds"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Refund an amount from a vendor deposit. Validated by RefundVendorDepositRequest.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"amount_in_deposit_currency\": 100,\n  \"currency_rate\": 1,\n  \"refund_date\": \"2026-04-12\",\n  \"reason\": \"Partial refund — PO cancelled\",\n  \"external_reference\": \"RFD-0001\",\n  \"notes\": \"Returned via bank transfer\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Send Remittance Advice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/send-remittance","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","send-remittance"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Email a remittance advice for a paid vendor deposit to the supplier.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nSends a supplier-facing email containing the deposit reference, PO number, supplier reference (PI #), amount paid, payment date and payment reference — bank/account numbers are never included. Selected deposit attachments (e.g. the wire confirmation uploaded with category `payment_proof`) are attached to the email. Stamps `remittance_sent_at` on the deposit and returns the full updated deposit resource.\n\n**Validation (SendVendorDepositRemittanceRequest):**\n- `to` (required, email) — recipient, usually the supplier's email\n- `cc` (optional, array of emails)\n- `subject` (required, string, max 255)\n- `note` (optional, string, max 2000) — included in the email body\n- `attachment_ids` (optional, array of integers) — must belong to this deposit, else 422\n\n**Errors (422):** deposit not yet paid (allowed statuses: partially_paid, paid, partially_applied, fully_applied); attachment ids not belonging to the deposit; validation failures.\n- attachment file missing from storage → 422 before anything is sent.","body":{"mode":"raw","raw":"{\n  \"to\": \"accounts@supplier.example.com\",\n  \"cc\": [\n    \"finance@yourcompany.example.com\"\n  ],\n  \"subject\": \"Remittance Advice — VD-00012 / PO-0660\",\n  \"note\": \"Wire sent today via SWIFT; please confirm receipt.\",\n  \"attachment_ids\": [\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/send-remittance","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","send-remittance"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 12,\n  \"deposit_number\": \"VD-00012\",\n  \"status\": \"paid\",\n  \"status_label\": \"Paid\",\n  \"supplier_id\": 1,\n  \"purchase_order_id\": 7,\n  \"amount\": 28147.71,\n  \"amount_paid\": 28147.71,\n  \"external_reference\": \"PI-2026-0630-199\",\n  \"payee_bank_details\": \"Bank of East Asia, Hong Kong\\nSWIFT: BEASHKHH\\nAccount: 01551468050442\",\n  \"bank_details_verified_at\": \"2026-07-02T18:10:00+00:00\",\n  \"bank_details_verified_by\": 2,\n  \"payment_requested_at\": \"2026-07-01T09:20:00+00:00\",\n  \"payment_requested_by\": 3,\n  \"remittance_sent_at\": \"2026-07-02T19:45:12+00:00\",\n  \"paid_at\": \"2026-07-02T00:00:00+00:00\"\n}"}]},{"name":"Scan Payment Proof (OCR)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/scan-proof","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","scan-proof"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"OCR a payment-proof image/PDF (a wire confirmation or receipt) and return the extracted payment fields for the payer to review before recording the payment.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRuns the shared OCR stack — Azure Document Intelligence layout OCR + a small LLM extraction — and returns the fields WITHOUT persisting anything. The file is only stored (as a payment_proof attachment) when the payment itself is recorded. The Record Payment / Approve & Mark Paid dialogs use this to pre-fill Reference, Amount, and Date.\n\n**Gating & metering:** requires the tenant's OCR setting to be enabled (Settings → Accounting → Invoice OCR) and Azure DI credentials configured; each scan is metered in the shared OCR usage log. Throttled to 20/min.\n\n**Body (multipart/form-data):** `file` — required image/PDF, max 10MB.\n\n**Errors (422):** OCR not enabled; Azure not configured; no readable text found; file validation.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/scan-proof","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","scan-proof"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"FT26183999888\",\n    \"amount\": 28147.71,\n    \"currency_code\": \"USD\",\n    \"value_date\": \"2026-07-02\",\n    \"payee_name\": \"Pacific Rim Trading Co.\"\n  }\n}"}]},{"name":"Apply To Purchase Invoices","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/applications","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","applications"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Apply deposit balance to one or more purchase invoices. Validated by ApplyVendorDepositRequest.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"applications\": [\n    {\n      \"purchase_invoice_id\": 1,\n      \"amount_in_deposit_currency\": 150\n    },\n    {\n      \"purchase_invoice_id\": 2,\n      \"amount_in_deposit_currency\": 75.5\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unapply Deposit Application","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposit-applications/{applicationId}","host":["{{baseUrl}}"],"path":["api","vendor-deposit-applications",":applicationId"],"variable":[{"key":"applicationId","value":"","description":"The application ID."}]},"description":"Unapply (reverse) a previously applied deposit application. Returns 204 No Content.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress."}},{"name":"Preview Vendor Deposit Application","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/applications/preview","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","applications","preview"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Preview the effect of applying a deposit amount to a purchase invoice (bill) without committing anything. Returns the before/after balances on both the deposit and the bill, the tenant-currency amount, and any FX gain/loss that would be posted when the deposit and bill currencies differ.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nValidation problems (deposit not applicable, supplier mismatch, amount exceeding the unapplied balance) are returned in the errors and warnings arrays rather than as an HTTP error.","body":{"mode":"raw","raw":"{\n  \"purchase_invoice_id\": 88,\n  \"amount_in_deposit_currency\": 500\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/applications/preview","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","applications","preview"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deposit_id\": 42,\n    \"purchase_invoice_id\": 88,\n    \"amount_in_deposit_currency\": 500,\n    \"amount_in_tenant_currency\": 500,\n    \"amount_at_bill_rate\": 500,\n    \"fx_gain_loss\": 0,\n    \"deposit_balance_before\": {\n      \"available\": 1500,\n      \"applied\": 0\n    },\n    \"deposit_balance_after\": {\n      \"available\": 1000,\n      \"applied\": 500\n    },\n    \"bill_balance_before\": {\n      \"outstanding\": 5000,\n      \"total\": 5000,\n      \"total_deposits_applied\": 0\n    },\n    \"bill_balance_after\": {\n      \"outstanding\": 4500,\n      \"total\": 5000,\n      \"total_deposits_applied\": 500\n    },\n    \"warnings\": [],\n    \"errors\": []\n  }\n}"}]},{"name":"List Applicable Bills for Vendor Deposit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/applicable-bills","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","applicable-bills"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"List open purchase invoices (bills) from the deposit's supplier that the deposit can be applied to, including each bill's outstanding balance after payments and previously applied deposits. Returns up to 100 bills.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/applicable-bills","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","applicable-bills"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"purchase_invoice_number\": \"INV-2026-0088\",\n      \"purchase_order_id\": 310,\n      \"purchase_order_number\": \"PO-000310\",\n      \"supplier_id\": 7,\n      \"supplier_name\": \"Acme Components Ltd\",\n      \"currency_code\": \"USD\",\n      \"total\": 5000,\n      \"total_paid\": 0,\n      \"total_deposits_applied\": 1500,\n      \"outstanding_balance\": 3500,\n      \"invoice_date\": \"2026-06-28\",\n      \"due_date\": \"2026-07-28\",\n      \"status\": \"approved\"\n    }\n  ]\n}"}]},{"name":"Get Vendor Deposit Accounting Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/accounting","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","accounting"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Get the accounting transactions posted for a vendor deposit. The primary vendor-deposit-paid transaction is returned in data (null when none exists yet); application, refund, and write-off transactions are returned in related_transactions.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe eligibility object indicates whether an accounting transaction can currently be generated for this deposit and, when it cannot, why (e.g. the Prepaid Vendor Deposits nominal code is not configured, or the deposit has no payments, applications, refunds, or write-offs to post)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/accounting","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","accounting"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"transaction_date\": \"2026-06-15\",\n    \"type\": {\n      \"name\": \"vendor_deposit_paid\",\n      \"link_type\": \"App\\\\Models\\\\VendorDeposit\",\n      \"link_id\": 42,\n      \"link_type_label\": \"Vendor Deposit Paid\",\n      \"link_route\": \"/orders/vendor-deposits/42\"\n    },\n    \"integration_invoice_number_override\": null,\n    \"name\": \"Vendor Deposit Paid\",\n    \"is_tax_included\": false,\n    \"total\": 1500,\n    \"reference\": \"DEP-000042\",\n    \"last_sync_error\": null,\n    \"is_sync_enabled\": true,\n    \"is_type_sync_enabled\": true,\n    \"lines\": [\n      {\n        \"id\": 9001,\n        \"type\": \"debit\",\n        \"nominal_code\": {\n          \"id\": 21,\n          \"code\": \"1350\",\n          \"name\": \"Prepaid Vendor Deposits\"\n        },\n        \"description\": \"Deposit paid to Acme Components Ltd\",\n        \"quantity\": 1,\n        \"amount\": 1500,\n        \"subtotal\": 1500,\n        \"tax_amount\": 0,\n        \"created_at\": \"2026-06-15T14:10:00.000000Z\",\n        \"updated_at\": \"2026-06-15T14:10:00.000000Z\"\n      },\n      {\n        \"id\": 9002,\n        \"type\": \"credit\",\n        \"nominal_code\": {\n          \"id\": 5,\n          \"code\": \"1200\",\n          \"name\": \"Bank Account\"\n        },\n        \"description\": \"Deposit paid to Acme Components Ltd\",\n        \"quantity\": 1,\n        \"amount\": -1500,\n        \"subtotal\": -1500,\n        \"tax_amount\": 0,\n        \"created_at\": \"2026-06-15T14:10:00.000000Z\",\n        \"updated_at\": \"2026-06-15T14:10:00.000000Z\"\n      }\n    ],\n    \"status\": \"approved\",\n    \"is_locked\": false,\n    \"is_batchable\": true,\n    \"updated_at\": \"2026-06-15T14:10:00.000000Z\",\n    \"created_at\": \"2026-06-15T14:10:00.000000Z\"\n  },\n  \"related_transactions\": [],\n  \"eligibility\": {\n    \"eligible\": true,\n    \"reason\": null,\n    \"settings_route\": null,\n    \"settings_label\": null\n  }\n}"}]},{"name":"Generate Vendor Deposit Accounting Transaction","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","generate-accounting-transaction"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Generate (or regenerate) the accounting transactions for a vendor deposit from its current payments, applications, refunds, and write-offs. No request body is required.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","generate-accounting-transaction"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Ledger entry generated successfully.\",\n  \"data\": null\n}"}]},{"name":"Push Vendor Deposit to QuickBooks Online","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/push-to-qbo","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","push-to-qbo"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Queue a push of the vendor deposit's accounting transactions to QuickBooks Online. The push runs asynchronously — a 200 response confirms the sync was queued, not that it has completed. Requires a connected QuickBooks Online integration.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the deposit cannot be pushed (e.g. no accounting transaction exists or no QuickBooks Online connection is configured)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/push-to-qbo","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","push-to-qbo"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor deposit push to QuickBooks Online queued.\",\n  \"data\": {\n    \"vendor_deposit_id\": 42\n  }\n}"}]},{"name":"Push Vendor Deposit to Xero","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/push-to-xero","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","push-to-xero"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Queue a push of the vendor deposit's accounting transactions to Xero. The push runs asynchronously — a 200 response confirms the sync was queued, not that it has completed. Requires a connected Xero integration.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the deposit cannot be pushed (e.g. no accounting transaction exists or no Xero connection is configured)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/push-to-xero","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","push-to-xero"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Vendor deposit push to Xero queued.\",\n  \"data\": {\n    \"vendor_deposit_id\": 42\n  }\n}"}]},{"name":"List Vendor Deposit Attachments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","attachments"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"List all attachments on a vendor deposit.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Upload Vendor Deposit Attachment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/attachments","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","attachments"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Upload an attachment (multipart/form-data). Max size 10 MB. Optional description (<=500 chars).\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n**Category:** optional `category` field — `proforma_invoice`, `payment_proof`, or `other` (default). Categories drive UI chips and remittance-advice attachment pre-selection.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"description","type":"text","value":""},{"key":"category","type":"text","value":""}]}}},{"name":"Download Vendor Deposit Attachment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/attachments/{attachmentId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","attachments",":attachmentId"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."},{"key":"attachmentId","value":"","description":"The attachment ID."}]},"description":"Download the original attachment file.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Delete Vendor Deposit Attachment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/attachments/{attachmentId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","attachments",":attachmentId"],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."},{"key":"attachmentId","value":"","description":"The attachment ID."}]},"description":"Delete an attachment. Returns 204 No Content.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Get Vendor Deposit Aging Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/aging-report?supplier_id=1","host":["{{baseUrl}}"],"path":["api","vendor-deposits","aging-report"],"query":[{"key":"supplier_id","value":"1","description":"Optional — filter by supplier","disabled":true}]},"description":"Aging report bucketed by current / 1-30 / 31-60 / 61-90 / over_90 days. Returns totals and deposit details per bucket.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Get Vendor Deposit Summary Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/summary-stats","host":["{{baseUrl}}"],"path":["api","vendor-deposits","summary-stats"]},"description":"Aggregate KPI stats across all deposits (totals by status, available balance, etc.).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Supplier Statement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/supplier-statement/{supplierId}","host":["{{baseUrl}}"],"path":["api","vendor-deposits","supplier-statement",":supplierId"],"variable":[{"key":"supplierId","value":"","description":"The supplier ID."}]},"description":"All deposits for a specific supplier with totals (amount, paid, applied, refunded, available).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Get Vendor Deposit Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/{vendorDepositId}/activity-log?per_page=15","host":["{{baseUrl}}"],"path":["api","vendor-deposits",":vendorDepositId","activity-log"],"query":[{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"vendorDepositId","value":"","description":"The vendor deposit ID."}]},"description":"Paginated activity log (Spatie Activitylog) for a vendor deposit.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."}},{"name":"Get Vendor Deposit Write-Off Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/write-off-report","host":["{{baseUrl}}"],"path":["api","vendor-deposits","write-off-report"]},"description":"Report of written-off vendor deposits, with per-deposit rows, totals, and a per-supplier breakdown sorted by written-off amount.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOptionally filter by written-off date range and supplier."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/write-off-report","host":["{{baseUrl}}"],"path":["api","vendor-deposits","write-off-report"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"id\": 42,\n        \"deposit_number\": \"DEP-000042\",\n        \"supplier_id\": 7,\n        \"supplier_name\": \"Acme Components Ltd\",\n        \"deposit_date\": \"2026-03-02\",\n        \"due_date\": \"2026-04-01\",\n        \"written_off_at\": \"2026-06-20\",\n        \"write_off_reason\": \"Supplier ceased trading\",\n        \"written_off_by\": \"Jane Operator\",\n        \"currency_code\": \"USD\",\n        \"amount\": 750,\n        \"amount_written_off\": 750,\n        \"amount_written_off_in_tenant_currency\": 750\n      }\n    ],\n    \"count\": 1,\n    \"total_written_off\": 750,\n    \"total_written_off_in_tenant_currency\": 750,\n    \"by_supplier\": [\n      {\n        \"supplier_id\": 7,\n        \"supplier_name\": \"Acme Components Ltd\",\n        \"count\": 1,\n        \"total_written_off_in_tenant_currency\": 750\n      }\n    ]\n  }\n}"}]},{"name":"Get Cash Due Schedule","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/cash-due-schedule","host":["{{baseUrl}}"],"path":["api","vendor-deposits","cash-due-schedule"]},"description":"Cash due schedule for deposit obligations, combining existing deposits and projected payment-term milestones on open purchase orders. Rows are grouped into sections: due_now (triggered and due or overdue), due_within_30_days, upcoming_by_trigger (dated but trigger not yet reached), undated, late_shipments, and shortfalls.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nEach section row describes the obligation: source_type (deposit or installment), deposit/PO references, milestone label, trigger event, due date, amounts in the deposit currency and the tenant currency, and flags (has_triggered, is_ready_to_pay, is_overdue)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/cash-due-schedule","host":["{{baseUrl}}"],"path":["api","vendor-deposits","cash-due-schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"due_now_count\": 1,\n      \"due_now_in_tenant_currency\": 1500,\n      \"due_within_30_days_count\": 0,\n      \"due_within_30_days_in_tenant_currency\": 0,\n      \"upcoming_by_trigger_count\": 0,\n      \"upcoming_by_trigger_in_tenant_currency\": 0,\n      \"undated_count\": 0,\n      \"undated_in_tenant_currency\": 0,\n      \"late_shipment_count\": 0,\n      \"late_shipment_in_tenant_currency\": 0,\n      \"shortfall_count\": 0,\n      \"shortfall_in_tenant_currency\": 0\n    },\n    \"sections\": {\n      \"due_now\": [\n        {\n          \"source_type\": \"deposit\",\n          \"row_key\": \"42\",\n          \"vendor_deposit_id\": 42,\n          \"vendor_deposit_number\": \"DEP-000042\",\n          \"deposit_status\": \"approved\",\n          \"deposit_status_label\": \"Approved\",\n          \"supplier_id\": 7,\n          \"supplier_name\": \"Acme Components Ltd\",\n          \"purchase_order_id\": 310,\n          \"purchase_order_number\": \"PO-000310\",\n          \"payment_term_schedule_line_index\": 1,\n          \"inbound_shipment_id\": null,\n          \"milestone_label\": \"30% deposit on order\",\n          \"currency_code\": \"USD\",\n          \"settlement_type\": \"vendor_deposit\",\n          \"settlement_type_label\": \"Vendor Deposit\",\n          \"trigger_event\": \"po_approved\",\n          \"trigger_event_label\": \"PO Approved\",\n          \"due_date\": \"2026-07-20\",\n          \"amount\": 1500,\n          \"amount_paid\": 0,\n          \"remaining_amount\": 1500,\n          \"amount_in_tenant_currency\": 1500,\n          \"amount_paid_in_tenant_currency\": 0,\n          \"remaining_amount_in_tenant_currency\": 1500,\n          \"has_triggered\": true,\n          \"is_ready_to_pay\": true,\n          \"forecast_source\": \"deposit_due_date\",\n          \"forecast_source_label\": \"Deposit due date\",\n          \"is_overdue\": false\n        }\n      ],\n      \"due_within_30_days\": [],\n      \"upcoming_by_trigger\": [],\n      \"undated\": [],\n      \"late_shipments\": [],\n      \"shortfalls\": []\n    },\n    \"shortfall_summary\": {\n      \"count\": 0,\n      \"shortfall_count\": 0,\n      \"undercoverage_count\": 0,\n      \"overage_count\": 0,\n      \"overdue_count\": 0,\n      \"shortfall_in_tenant_currency\": 0,\n      \"overage_in_tenant_currency\": 0,\n      \"overdue_in_tenant_currency\": 0\n    }\n  }\n}"}]},{"name":"Get Cash Flow Forecast","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/cash-flow-forecast","host":["{{baseUrl}}"],"path":["api","vendor-deposits","cash-flow-forecast"]},"description":"Forecast of upcoming cash outflows from unpaid deposit obligations, bucketed by day, week, or month. Buckets include existing deposits and projected payment-term milestones on open purchase orders, keyed by due date.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nDefaults: date_from = today, date_to = six months out, granularity = month. Undated obligations (no due date yet) are listed separately in undated_rows; coverage shortfalls appear in shortfall_rows."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/cash-flow-forecast","host":["{{baseUrl}}"],"path":["api","vendor-deposits","cash-flow-forecast"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"granularity\": \"month\",\n    \"date_from\": \"2026-07-07\",\n    \"date_to\": \"2027-01-07\",\n    \"settlement_scope\": \"all\",\n    \"buckets\": [\n      {\n        \"period_start\": \"2026-07-01\",\n        \"period_label\": \"Jul 2026\",\n        \"obligation_count\": 1,\n        \"deposit_count\": 1,\n        \"total_outstanding\": 1500,\n        \"total_outstanding_in_tenant_currency\": 1500,\n        \"rows\": [\n          {\n            \"source_type\": \"deposit\",\n            \"row_key\": \"42\",\n            \"vendor_deposit_id\": 42,\n            \"vendor_deposit_number\": \"DEP-000042\",\n            \"deposit_status\": \"approved\",\n            \"deposit_status_label\": \"Approved\",\n            \"supplier_id\": 7,\n            \"supplier_name\": \"Acme Components Ltd\",\n            \"purchase_order_id\": 310,\n            \"purchase_order_number\": \"PO-000310\",\n            \"payment_term_schedule_line_index\": 1,\n            \"inbound_shipment_id\": null,\n            \"milestone_label\": \"30% deposit on order\",\n            \"currency_code\": \"USD\",\n            \"settlement_type\": \"vendor_deposit\",\n            \"settlement_type_label\": \"Vendor Deposit\",\n            \"trigger_event\": \"po_approved\",\n            \"trigger_event_label\": \"PO Approved\",\n            \"due_date\": \"2026-07-20\",\n            \"amount\": 1500,\n            \"amount_paid\": 0,\n            \"remaining_amount\": 1500,\n            \"amount_in_tenant_currency\": 1500,\n            \"amount_paid_in_tenant_currency\": 0,\n            \"remaining_amount_in_tenant_currency\": 1500,\n            \"has_triggered\": true,\n            \"is_ready_to_pay\": true,\n            \"forecast_source\": \"deposit_due_date\",\n            \"forecast_source_label\": \"Deposit due date\",\n            \"is_overdue\": false\n          }\n        ]\n      }\n    ],\n    \"total_outstanding_in_tenant_currency\": 1500,\n    \"obligation_count\": 1,\n    \"deposit_count\": 1,\n    \"undated_rows\": [],\n    \"undated_count\": 0,\n    \"undated_outstanding_in_tenant_currency\": 0,\n    \"shortfall_rows\": [],\n    \"shortfall_count\": 0,\n    \"shortfall_in_tenant_currency\": 0,\n    \"shortfall_overdue_in_tenant_currency\": 0\n  }\n}"}]},{"name":"Get Upcoming Liability Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/upcoming-liability","host":["{{baseUrl}}"],"path":["api","vendor-deposits","upcoming-liability"]},"description":"Upcoming deposit liabilities: every outstanding deposit obligation (existing deposits plus projected payment-term milestones on open purchase orders), sorted with overdue and ready-to-pay rows first. Rows with no due date are returned separately in undated_rows.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe summary aggregates the tenant-currency exposure: total outstanding, overdue, due in the next 7 and 30 days, ready to pay, and blocked (trigger event not yet reached)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/upcoming-liability","host":["{{baseUrl}}"],"path":["api","vendor-deposits","upcoming-liability"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"source_type\": \"deposit\",\n        \"row_key\": \"42\",\n        \"vendor_deposit_id\": 42,\n        \"vendor_deposit_number\": \"DEP-000042\",\n        \"deposit_status\": \"approved\",\n        \"deposit_status_label\": \"Approved\",\n        \"supplier_id\": 7,\n        \"supplier_name\": \"Acme Components Ltd\",\n        \"purchase_order_id\": 310,\n        \"purchase_order_number\": \"PO-000310\",\n        \"payment_term_schedule_line_index\": 1,\n        \"inbound_shipment_id\": null,\n        \"milestone_label\": \"30% deposit on order\",\n        \"currency_code\": \"USD\",\n        \"settlement_type\": \"vendor_deposit\",\n        \"settlement_type_label\": \"Vendor Deposit\",\n        \"trigger_event\": \"po_approved\",\n        \"trigger_event_label\": \"PO Approved\",\n        \"due_date\": \"2026-07-20\",\n        \"amount\": 1500,\n        \"amount_paid\": 0,\n        \"remaining_amount\": 1500,\n        \"amount_in_tenant_currency\": 1500,\n        \"amount_paid_in_tenant_currency\": 0,\n        \"remaining_amount_in_tenant_currency\": 1500,\n        \"has_triggered\": true,\n        \"is_ready_to_pay\": true,\n        \"forecast_source\": \"deposit_due_date\",\n        \"forecast_source_label\": \"Deposit due date\",\n        \"is_overdue\": false\n      }\n    ],\n    \"summary\": {\n      \"row_count\": 1,\n      \"outstanding_in_tenant_currency\": 1500,\n      \"overdue_count\": 0,\n      \"overdue_in_tenant_currency\": 0,\n      \"due_in_7_days_count\": 0,\n      \"due_in_7_days_in_tenant_currency\": 0,\n      \"due_in_30_days_count\": 1,\n      \"due_in_30_days_in_tenant_currency\": 1500,\n      \"ready_to_pay_count\": 1,\n      \"ready_to_pay_in_tenant_currency\": 1500,\n      \"blocked_count\": 0,\n      \"blocked_in_tenant_currency\": 0\n    },\n    \"undated_rows\": [],\n    \"undated_count\": 0,\n    \"undated_total\": 0,\n    \"shortfall_rows\": [],\n    \"shortfall_summary\": {\n      \"count\": 0,\n      \"shortfall_count\": 0,\n      \"undercoverage_count\": 0,\n      \"overage_count\": 0,\n      \"overdue_count\": 0,\n      \"shortfall_in_tenant_currency\": 0,\n      \"overage_in_tenant_currency\": 0,\n      \"overdue_in_tenant_currency\": 0\n    }\n  }\n}"}]},{"name":"Get Supplier Exposure Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/supplier-exposure","host":["{{baseUrl}}"],"path":["api","vendor-deposits","supplier-exposure"]},"description":"Deposit exposure grouped by supplier, sorted by outstanding amount. Each supplier row aggregates its outstanding obligations (existing deposits plus projected milestones), overdue and near-term amounts, unapplied paid balances, pending approvals, and coverage shortfalls/overages, and includes the underlying obligation_rows, shortfall_rows, and a per-purchase-order breakdown.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/supplier-exposure","host":["{{baseUrl}}"],"path":["api","vendor-deposits","supplier-exposure"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rows\": [\n      {\n        \"supplier_id\": 7,\n        \"supplier_name\": \"Acme Components Ltd\",\n        \"deposit_count\": 2,\n        \"obligation_count\": 1,\n        \"po_count\": 1,\n        \"outstanding_in_tenant_currency\": 1500,\n        \"overdue_in_tenant_currency\": 0,\n        \"due_in_7_days_in_tenant_currency\": 0,\n        \"due_in_30_days_in_tenant_currency\": 1500,\n        \"blocked_in_tenant_currency\": 0,\n        \"unapplied_balance_in_tenant_currency\": 250,\n        \"pending_approval_count\": 0,\n        \"shortfall_count\": 0,\n        \"shortfall_in_tenant_currency\": 0,\n        \"shortfall_overdue_in_tenant_currency\": 0,\n        \"overage_count\": 0,\n        \"overage_in_tenant_currency\": 0,\n        \"obligation_rows\": [\n          {\n            \"source_type\": \"deposit\",\n            \"row_key\": \"42\",\n            \"vendor_deposit_id\": 42,\n            \"vendor_deposit_number\": \"DEP-000042\",\n            \"deposit_status\": \"approved\",\n            \"deposit_status_label\": \"Approved\",\n            \"supplier_id\": 7,\n            \"supplier_name\": \"Acme Components Ltd\",\n            \"purchase_order_id\": 310,\n            \"purchase_order_number\": \"PO-000310\",\n            \"payment_term_schedule_line_index\": 1,\n            \"inbound_shipment_id\": null,\n            \"milestone_label\": \"30% deposit on order\",\n            \"currency_code\": \"USD\",\n            \"settlement_type\": \"vendor_deposit\",\n            \"settlement_type_label\": \"Vendor Deposit\",\n            \"trigger_event\": \"po_approved\",\n            \"trigger_event_label\": \"PO Approved\",\n            \"due_date\": \"2026-07-20\",\n            \"amount\": 1500,\n            \"amount_paid\": 0,\n            \"remaining_amount\": 1500,\n            \"amount_in_tenant_currency\": 1500,\n            \"amount_paid_in_tenant_currency\": 0,\n            \"remaining_amount_in_tenant_currency\": 1500,\n            \"has_triggered\": true,\n            \"is_ready_to_pay\": true,\n            \"forecast_source\": \"deposit_due_date\",\n            \"forecast_source_label\": \"Deposit due date\",\n            \"is_overdue\": false\n          }\n        ],\n        \"shortfall_rows\": [],\n        \"purchase_orders\": [\n          {\n            \"purchase_order_id\": 310,\n            \"purchase_order_number\": \"PO-000310\",\n            \"order_status\": \"open\",\n            \"order_status_label\": \"Open\",\n            \"shipment_status\": \"not_shipped\",\n            \"shipment_status_label\": \"Not Shipped\",\n            \"obligation_count\": 1,\n            \"outstanding_in_tenant_currency\": 1500,\n            \"due_in_7_days_in_tenant_currency\": 0,\n            \"awaiting_trigger_in_tenant_currency\": 0\n          }\n        ]\n      }\n    ],\n    \"summary\": {\n      \"supplier_count\": 1,\n      \"outstanding_in_tenant_currency\": 1500,\n      \"overdue_in_tenant_currency\": 0,\n      \"due_in_7_days_in_tenant_currency\": 0,\n      \"due_in_30_days_in_tenant_currency\": 1500,\n      \"blocked_in_tenant_currency\": 0,\n      \"unapplied_balance_in_tenant_currency\": 250,\n      \"shortfall_count\": 0,\n      \"shortfall_in_tenant_currency\": 0,\n      \"shortfall_overdue_in_tenant_currency\": 0,\n      \"overage_count\": 0,\n      \"overage_in_tenant_currency\": 0\n    }\n  }\n}"}]},{"name":"Get Exceptions Queue","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/exceptions-queue","host":["{{baseUrl}}"],"path":["api","vendor-deposits","exceptions-queue"]},"description":"Deposit obligations that need attention, grouped into sections: overdue, due_soon (next 7 days), blocked (trigger event not yet reached), pending_approval, unapplied_after_bill (paid deposits still unapplied after a supplier bill has arrived), late_shipments, and shortfalls. The summary aggregates counts and tenant-currency amounts per section.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/exceptions-queue","host":["{{baseUrl}}"],"path":["api","vendor-deposits","exceptions-queue"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"overdue_count\": 0,\n      \"overdue_in_tenant_currency\": 0,\n      \"due_soon_count\": 1,\n      \"due_soon_in_tenant_currency\": 1500,\n      \"blocked_count\": 0,\n      \"blocked_in_tenant_currency\": 0,\n      \"pending_approval_count\": 1,\n      \"pending_approval_in_tenant_currency\": 1500,\n      \"unapplied_after_bill_count\": 0,\n      \"unapplied_after_bill_in_tenant_currency\": 0,\n      \"late_shipment_count\": 0,\n      \"shortfall_count\": 0,\n      \"shortfall_in_tenant_currency\": 0\n    },\n    \"sections\": {\n      \"overdue\": [],\n      \"due_soon\": [\n        {\n          \"source_type\": \"deposit\",\n          \"row_key\": \"42\",\n          \"vendor_deposit_id\": 42,\n          \"vendor_deposit_number\": \"DEP-000042\",\n          \"deposit_status\": \"approved\",\n          \"deposit_status_label\": \"Approved\",\n          \"supplier_id\": 7,\n          \"supplier_name\": \"Acme Components Ltd\",\n          \"purchase_order_id\": 310,\n          \"purchase_order_number\": \"PO-000310\",\n          \"payment_term_schedule_line_index\": 1,\n          \"inbound_shipment_id\": null,\n          \"milestone_label\": \"30% deposit on order\",\n          \"currency_code\": \"USD\",\n          \"settlement_type\": \"vendor_deposit\",\n          \"settlement_type_label\": \"Vendor Deposit\",\n          \"trigger_event\": \"po_approved\",\n          \"trigger_event_label\": \"PO Approved\",\n          \"due_date\": \"2026-07-20\",\n          \"amount\": 1500,\n          \"amount_paid\": 0,\n          \"remaining_amount\": 1500,\n          \"amount_in_tenant_currency\": 1500,\n          \"amount_paid_in_tenant_currency\": 0,\n          \"remaining_amount_in_tenant_currency\": 1500,\n          \"has_triggered\": true,\n          \"is_ready_to_pay\": true,\n          \"forecast_source\": \"deposit_due_date\",\n          \"forecast_source_label\": \"Deposit due date\",\n          \"is_overdue\": false\n        }\n      ],\n      \"blocked\": [],\n      \"pending_approval\": [\n        {\n          \"vendor_deposit_id\": 42,\n          \"vendor_deposit_number\": \"DEP-000042\",\n          \"supplier_id\": 7,\n          \"supplier_name\": \"Acme Components Ltd\",\n          \"purchase_order_id\": 310,\n          \"purchase_order_number\": \"PO-000310\",\n          \"deposit_date\": \"2026-06-15\",\n          \"due_date\": \"2026-07-20\",\n          \"remaining_amount_in_tenant_currency\": 1500\n        }\n      ],\n      \"unapplied_after_bill\": [],\n      \"late_shipments\": [],\n      \"shortfalls\": []\n    },\n    \"shortfall_summary\": {\n      \"count\": 0,\n      \"shortfall_count\": 0,\n      \"undercoverage_count\": 0,\n      \"overage_count\": 0,\n      \"overdue_count\": 0,\n      \"shortfall_in_tenant_currency\": 0,\n      \"overage_in_tenant_currency\": 0,\n      \"overdue_in_tenant_currency\": 0\n    }\n  }\n}"}]},{"name":"Get Purchase Orders by Shipping Stage","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/po-by-shipping-stage","host":["{{baseUrl}}"],"path":["api","vendor-deposits","po-by-shipping-stage"]},"description":"Open purchase orders with deposit schedules, grouped by their farthest-reached installment trigger stage (e.g. PO approved, shipped, received). Each stage lists its purchase orders with the outstanding deposit amount still owed, so you can see how much cash is committed at each stage of the inbound pipeline.\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/po-by-shipping-stage","host":["{{baseUrl}}"],"path":["api","vendor-deposits","po-by-shipping-stage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"stages\": [\n      {\n        \"stage\": \"manual\",\n        \"stage_label\": \"Not Yet Triggered\",\n        \"stage_ordering\": 0,\n        \"po_count\": 0,\n        \"outstanding_in_tenant_currency\": 0,\n        \"purchase_orders\": []\n      },\n      {\n        \"stage\": \"po_approved\",\n        \"stage_label\": \"PO Approved\",\n        \"stage_ordering\": 1,\n        \"po_count\": 1,\n        \"outstanding_in_tenant_currency\": 3500,\n        \"purchase_orders\": [\n          {\n            \"purchase_order_id\": 310,\n            \"purchase_order_number\": \"PO-000310\",\n            \"supplier_id\": 7,\n            \"supplier_name\": \"Acme Components Ltd\",\n            \"order_status\": \"open\",\n            \"order_status_label\": \"Open\",\n            \"shipment_status\": \"not_shipped\",\n            \"shipment_status_label\": \"Not Shipped\",\n            \"outstanding_in_tenant_currency\": 3500\n          }\n        ]\n      }\n    ],\n    \"total_po_count\": 1,\n    \"total_outstanding_in_tenant_currency\": 3500\n  }\n}"}]},{"name":"List Expected Deposit Milestones","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/expected-milestones","host":["{{baseUrl}}"],"path":["api","vendor-deposits","expected-milestones"]},"description":"List expected deposit milestones derived from the payment-term schedules of draft and open purchase orders. Each milestone describes an installment: its trigger event, expected amount, due date, and lifecycle status — expected (trigger not reached), ready_to_create (trigger reached, no deposit yet), created (linked to a deposit), or out_of_sync (linked deposit no longer matches the schedule).\n\n**Required scope: `accounting:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nUse unlinked_only=1 to list only milestones that should create a deposit but have none linked yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/vendor-deposits/expected-milestones","host":["{{baseUrl}}"],"path":["api","vendor-deposits","expected-milestones"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"row_count\": 1,\n      \"expected_count\": 0,\n      \"ready_to_create_count\": 1,\n      \"created_count\": 0,\n      \"out_of_sync_count\": 0,\n      \"expected_amount_in_tenant_currency\": 1500\n    },\n    \"rows\": [\n      {\n        \"key\": \"po-310-line-1\",\n        \"status\": \"ready_to_create\",\n        \"status_label\": \"Ready to Create\",\n        \"status_reason\": null,\n        \"status_reasons\": [],\n        \"purchase_order_id\": 310,\n        \"purchase_order_number\": \"PO-000310\",\n        \"supplier_id\": 7,\n        \"supplier_name\": \"Acme Components Ltd\",\n        \"currency_id\": 1,\n        \"currency_code\": \"USD\",\n        \"line_index\": 1,\n        \"shipment_id\": null,\n        \"shipment_reference\": null,\n        \"label\": \"30% deposit on order\",\n        \"amount_mode\": \"percent\",\n        \"fixed_amount\": null,\n        \"percentage\": 30,\n        \"is_ownership_transfer\": false,\n        \"settlement_type\": \"vendor_deposit\",\n        \"settlement_type_label\": \"Vendor Deposit\",\n        \"creates_vendor_deposit\": true,\n        \"trigger_event\": \"po_approved\",\n        \"trigger_event_label\": \"PO Approved\",\n        \"offset_days\": 0,\n        \"per_shipment\": false,\n        \"shipment_date_basis\": null,\n        \"forecast_source\": \"po_approved_at\",\n        \"forecast_source_label\": \"PO approval date\",\n        \"is_synthesized\": false,\n        \"expected_amount\": 1500,\n        \"expected_amount_in_tenant_currency\": 1500,\n        \"basis_date\": \"2026-06-10\",\n        \"due_date\": \"2026-07-20\",\n        \"is_trigger_reached\": true,\n        \"is_ready_to_create\": true,\n        \"linked_vendor_deposit_id\": null,\n        \"linked_vendor_deposit_number\": null,\n        \"linked_vendor_deposit_status\": null,\n        \"linked_vendor_deposit_status_label\": null,\n        \"schedule_snapshot\": {\n          \"label\": \"30% deposit on order\",\n          \"trigger_event\": \"po_approved\",\n          \"percentage\": 30\n        },\n        \"placeholder_reason\": null\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Archive Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-archive","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-archive"]},"description":"Archive multiple deposits by id.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Unarchive Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-unarchive"]},"description":"Unarchive multiple deposits by id.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Delete Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-delete","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-delete"]},"description":"Hard-delete multiple deposits by id. Returns a message with the delete count.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Create Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-create","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-create"]},"description":"Create multiple vendor deposits in one call — one per item, each linked to a purchase order. Shared header fields (deposit_date, due_date, external_reference, notes, proportional_apply_enabled) apply to every deposit created.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nItem fields: purchase_order_id (required), currency_id, currency_rate, currency_id_tenant_snapshot, amount, and amount_in_tenant_currency are required; supplier_id, tax_amount, tax_amount_in_tenant_currency, tax_lines, payment_term_schedule_line_index, inbound_shipment_id, payment_term_schedule_snapshot, and is_ownership_transfer are optional.\n\nReturns 201 with the created deposits.","body":{"mode":"raw","raw":"{\n  \"deposit_date\": \"2026-07-07\",\n  \"due_date\": \"2026-08-01\",\n  \"external_reference\": \"WIRE-20260707-001\",\n  \"notes\": \"Deposits for July purchase orders\",\n  \"proportional_apply_enabled\": false,\n  \"items\": [\n    {\n      \"purchase_order_id\": 310,\n      \"supplier_id\": 7,\n      \"currency_id\": 1,\n      \"currency_rate\": 1,\n      \"currency_id_tenant_snapshot\": 1,\n      \"amount\": 1500,\n      \"amount_in_tenant_currency\": 1500,\n      \"tax_amount\": 0,\n      \"tax_amount_in_tenant_currency\": 0,\n      \"payment_term_schedule_line_index\": 1,\n      \"inbound_shipment_id\": null,\n      \"is_ownership_transfer\": false\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-create","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-create"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"deposit_number\": \"DEP-000042\",\n      \"status\": \"draft\",\n      \"status_label\": \"Draft\",\n      \"supplier_id\": 7,\n      \"supplier\": {\n        \"id\": 7,\n        \"name\": \"Acme Components Ltd\",\n        \"email\": \"accounts@acme-components.com\",\n        \"wire_instructions\": \"Routing 026009593, account 4426123456\",\n        \"link_route\": \"/v2/crm/suppliers/7\"\n      },\n      \"purchase_order_id\": 310,\n      \"payment_term_schedule_line_index\": 1,\n      \"inbound_shipment_id\": null,\n      \"payment_term_schedule_snapshot\": {\n        \"label\": \"30% deposit on order\",\n        \"trigger_event\": \"po_approved\",\n        \"percentage\": 30\n      },\n      \"is_ownership_transfer\": false,\n      \"ownership_transferred_at\": null,\n      \"purchase_order\": {\n        \"id\": 310,\n        \"purchase_order_number\": \"PO-000310\",\n        \"link_route\": \"/v2/orders/purchase-orders/310\",\n        \"link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n        \"link_type_label\": \"Purchase Order\",\n        \"link_id\": 310,\n        \"link_reference\": \"PO-000310\"\n      },\n      \"currency_id\": 1,\n      \"currency\": {\n        \"id\": 1,\n        \"code\": \"USD\",\n        \"symbol\": \"$\"\n      },\n      \"currency_rate\": 1,\n      \"currency_id_tenant_snapshot\": 1,\n      \"tenant_currency\": {\n        \"id\": 1,\n        \"code\": \"USD\",\n        \"symbol\": \"$\"\n      },\n      \"amount\": 1500,\n      \"amount_in_tenant_currency\": 1500,\n      \"amount_paid\": 0,\n      \"amount_paid_in_tenant_currency\": 0,\n      \"amount_applied\": 0,\n      \"amount_applied_in_tenant_currency\": 0,\n      \"amount_refunded\": 0,\n      \"amount_refunded_in_tenant_currency\": 0,\n      \"amount_written_off\": 0,\n      \"amount_written_off_in_tenant_currency\": 0,\n      \"available_balance\": 0,\n      \"available_balance_in_tenant_currency\": 0,\n      \"tax_amount\": 0,\n      \"tax_amount_in_tenant_currency\": 0,\n      \"tax_lines\": null,\n      \"deposit_date\": \"2026-06-15\",\n      \"due_date\": \"2026-07-20\",\n      \"paid_at\": null,\n      \"external_reference\": \"WIRE-20260615-042\",\n      \"payee_bank_details\": null,\n      \"bank_details_verified_at\": null,\n      \"bank_details_verified_by\": null,\n      \"bank_details_verified_by_user\": null,\n      \"payment_requested_at\": null,\n      \"payment_requested_by\": null,\n      \"payment_requested_by_user\": null,\n      \"remittance_sent_at\": null,\n      \"notes\": \"30% deposit for PO-000310\",\n      \"proportional_apply_enabled\": false,\n      \"auto_apply_enabled\": null,\n      \"auto_apply_effective\": true,\n      \"approved_by\": null,\n      \"approver\": null,\n      \"approved_at\": null,\n      \"approval_notes\": null,\n      \"submit_action\": \"approve\",\n      \"submit_action_label\": \"Approve Deposit\",\n      \"created_by\": 3,\n      \"creator\": {\n        \"id\": 3,\n        \"name\": \"Jane Operator\"\n      },\n      \"applications\": [],\n      \"payments\": [],\n      \"refunds\": [],\n      \"created_at\": \"2026-06-15T14:02:11+00:00\",\n      \"updated_at\": \"2026-07-01T09:30:00+00:00\",\n      \"archived_at\": null\n    }\n  ],\n  \"message\": \"Deposits created.\"\n}"}]},{"name":"Bulk Apply Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-apply","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-apply"]},"description":"Apply multiple deposits to purchase invoices (bills) in one operation. Each item names a deposit, a bill, and the amount to apply in the deposit's currency.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe applications are processed asynchronously in the background — the endpoint returns 202 Accepted immediately with a tracked_job_log_id you can use to follow progress.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"vendor_deposit_id\": 42,\n      \"purchase_invoice_id\": 88,\n      \"amount_in_deposit_currency\": 500\n    },\n    {\n      \"vendor_deposit_id\": 43,\n      \"purchase_invoice_id\": 91,\n      \"amount_in_deposit_currency\": 1200\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-apply","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-apply"]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8231\n  },\n  \"message\": \"Bulk apply started — track progress in the job tray.\"\n}"}]},{"name":"Bulk Approve Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-approve","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-approve"]},"description":"Approve multiple vendor deposits in one operation. Deposit IDs must be unique and refer to existing deposits.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nThe approvals are processed asynchronously in the background — the endpoint returns 202 Accepted immediately with a tracked_job_log_id you can use to follow progress.","body":{"mode":"raw","raw":"{\n  \"vendor_deposit_ids\": [\n    42,\n    43,\n    44\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/bulk-approve","host":["{{baseUrl}}"],"path":["api","vendor-deposits","bulk-approve"]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8232\n  },\n  \"message\": \"Bulk approve started — track progress in the job tray.\"\n}"}]},{"name":"Preview Vendor Deposit Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/import/preview","host":["{{baseUrl}}"],"path":["api","vendor-deposits","import","preview"]},"description":"Preview a CSV import of vendor deposits before running it. References a previously uploaded CSV file by its stored name and returns the parsed records, the detected file headers, the list of importable fields, and any unmapped (difference) or missing required (required_difference) fields so the column mapping can be corrected before importing.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nBody fields: original_name and stored_name are required; mapping (array of {file_field, expected_field} pairs), separator, escape, meta, and task_id are optional.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"vendor-deposits.csv\",\n  \"stored_name\": \"imports/2026/07/vendor-deposits-9f1c2a34.csv\",\n  \"separator\": \",\",\n  \"mapping\": [\n    {\n      \"file_field\": \"Deposit Number\",\n      \"expected_field\": \"deposit_number\"\n    },\n    {\n      \"file_field\": \"Supplier\",\n      \"expected_field\": \"supplier\"\n    },\n    {\n      \"file_field\": \"Amount\",\n      \"expected_field\": \"amount\"\n    },\n    {\n      \"file_field\": \"Deposit Date\",\n      \"expected_field\": \"deposit_date\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/import/preview","host":["{{baseUrl}}"],"path":["api","vendor-deposits","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"records\": [\n      {\n        \"Deposit Number\": \"DEP-000101\",\n        \"Supplier\": \"Acme Components Ltd\",\n        \"Amount\": \"1500.00\",\n        \"Deposit Date\": \"07/01/2026\"\n      }\n    ],\n    \"file_headers\": [\n      \"Deposit Number\",\n      \"Supplier\",\n      \"Amount\",\n      \"Deposit Date\"\n    ],\n    \"importable_fields\": [\n      \"deposit_number\",\n      \"supplier\",\n      \"amount\",\n      \"deposit_date\",\n      \"due_date\",\n      \"external_reference\",\n      \"notes\"\n    ],\n    \"difference\": [],\n    \"required_difference\": [],\n    \"not_importable\": [],\n    \"task_id\": \"9f1c2a34-77aa-4f0e-9a3d-1b2c3d4e5f60\"\n  }\n}"}]},{"name":"Import Vendor Deposits","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/vendor-deposits/import","host":["{{baseUrl}}"],"path":["api","vendor-deposits","import"]},"description":"Import vendor deposits from a previously uploaded CSV file using the supplied column mapping. If required fields are missing from the mapping, the endpoint returns the same preview payload as the preview endpoint instead of importing.\n\n**Required scope: `accounting:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nLarge files are imported asynchronously in the background — in that case the response data reads \"The data will be imported shortly.\" Row-level validation failures return 500 with the per-row errors.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"vendor-deposits.csv\",\n  \"stored_name\": \"imports/2026/07/vendor-deposits-9f1c2a34.csv\",\n  \"separator\": \",\",\n  \"mapping\": [\n    {\n      \"file_field\": \"Deposit Number\",\n      \"expected_field\": \"deposit_number\"\n    },\n    {\n      \"file_field\": \"Supplier\",\n      \"expected_field\": \"supplier\"\n    },\n    {\n      \"file_field\": \"Amount\",\n      \"expected_field\": \"amount\"\n    },\n    {\n      \"file_field\": \"Deposit Date\",\n      \"expected_field\": \"deposit_date\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/vendor-deposits/import","host":["{{baseUrl}}"],"path":["api","vendor-deposits","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Data import was successful.\"\n}"}]}]}]},{"name":"Integrations","item":[{"name":"17TRACK","item":[{"name":"Test Connection","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integrations/17track/test","host":["{{baseUrl}}"],"path":["api","integrations","17track","test"]},"description":"Validate a 17TRACK API key WITHOUT persisting an instance — powers the connect-modal `Test Connection` button.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUnder the hood the supplied key is sent to 17TRACK's `/getquota` endpoint; the response reports the quota so the UI can warn before connecting.\n\n**Required Fields:**\n- `api_key` — 17TRACK API key (string, 8–255 chars)\n\n**Responses:**\n- `200 OK` — key is valid, returns the live quota\n- `422 Unprocessable Entity` with `code: invalid_key` — 17TRACK rejected the key (auth error)\n- `422 Unprocessable Entity` with `code: api_error` — 17TRACK API returned a non-auth error (rate-limited, upstream failure, etc.)","body":{"mode":"raw","raw":"{\n  \"api_key\": \"sk_17track_live_xxxxxxxxxxxxxxxxxxxx\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integrations/17track/test","host":["{{baseUrl}}"],"path":["api","integrations","17track","test"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"quota\": {\n      \"used\": 142,\n      \"total\": 1000,\n      \"remaining\": 858\n    }\n  },\n  \"message\": \"Connection successful\"\n}"}]},{"name":"Create 17TRACK Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances"]},"description":"Persist the singleton 17TRACK instance for this tenant. The `WebhookRoutable` trait mints a unique `wh_*` token as part of the create flow — the resulting webhook URL is returned in the response so it can be copied into the tenant's 17TRACK dashboard.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Required Fields:**\n- `name` — Display name (string, max 255 chars)\n- `api_key` — 17TRACK API key (string, 8–255 chars)\n\n**Optional Fields:**\n- `auto_track` — Per-entity auto-track flags (object). When omitted or partial, every missing key defaults to `true` (\"all on\" happy path):\n  - `auto_track.sales_order_fulfillments` (boolean)\n  - `auto_track.inbound_shipments` (boolean)\n  - `auto_track.warehouse_transfer_shipments` (boolean)\n  - `auto_track.rmas` (boolean)\n  - `auto_track.vendor_credit_shipments` (boolean)\n\n**Responses:**\n- `201 Created` — Instance persisted; payload includes the freshly minted `webhook_url`.\n- `422 Unprocessable Entity` — Validation failure OR a 17TRACK instance already exists for this tenant (the integration is a singleton).\n\n**Sales-channel scoping (`auto_track_channels`)** — optional. `default` is `all` (track everything not explicitly disabled) or `none` (track nothing until explicitly enabled). `channels` is an optional object keyed by sales-channel id; each entry may carry a boolean `enabled` flag and/or a `sub_channels` object keyed by sub-channel id (booleans). Resolution is most-specific-first: a `sub_channels` override wins, then the channel `enabled` flag, then `default`. Fulfillment type is modeled as a sub-channel (e.g. Amazon FBA vs merchant-fulfilled, or Shopify Web vs POS), so excluding high-volume marketplace-fulfilled shipments is just disabling that sub-channel. Only sales order fulfillments are scoped; other shipment types are unaffected. Validation: `default` must be `all` or `none` (422 otherwise).","body":{"mode":"raw","raw":"{\n  \"name\": \"17TRACK Production\",\n  \"api_key\": \"sk_17track_live_xxxxxxxxxxxxxxxxxxxx\",\n  \"auto_track\": {\n    \"sales_order_fulfillments\": true,\n    \"inbound_shipments\": true,\n    \"warehouse_transfer_shipments\": true,\n    \"rmas\": true,\n    \"vendor_credit_shipments\": true\n  },\n  \"auto_track_channels\": {\n    \"default\": \"all\",\n    \"channels\": {}\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"17TRACK Production\",\n    \"is_automatic_sync_enabled\": true,\n    \"auto_track\": {\n      \"sales_order_fulfillments\": true,\n      \"inbound_shipments\": true,\n      \"warehouse_transfer_shipments\": true,\n      \"rmas\": true,\n      \"vendor_credit_shipments\": true\n    },\n    \"auto_track_channels\": {\n      \"default\": \"all\",\n      \"channels\": {}\n    },\n    \"webhook_url\": \"https://acme.sku.io/webhooks/seventeentrack/wh_aB3cD4eF5gH6iJ7kL8mN9oP\",\n    \"quota\": null,\n    \"status_counts\": null,\n    \"last_webhook_at\": null,\n    \"last_event_at\": null,\n    \"created_at\": \"2026-06-18T14:32:00+00:00\",\n    \"updated_at\": \"2026-06-18T14:32:00+00:00\"\n  }\n}"}]},{"name":"Get 17TRACK Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Return the 17TRACK instance enriched with the LIVE dashboard summary — quota, per-status counts, the webhook URL, and the most recent webhook + event timestamps. This is the payload that powers the connect dashboard.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute-model binding resolves the integer ID against `SeventeenTrackIntegrationInstance`; its global scope guarantees only 17TRACK rows resolve here.\n\n**Response includes:**\n- Instance config (name, auto-sync flag, per-entity auto-track flags, timestamps)\n- `webhook_url` — the unique URL to paste into the 17TRACK dashboard\n- `quota` — live quota from 17TRACK's `/getquota`\n- `status_counts` — zero-filled map of EVERY `DeliveryStatusEnum` value to count (10 buckets)\n- `last_webhook_at` — ISO timestamp of the most recent webhook ingest\n- `last_event_at` — ISO timestamp of the most recent carrier event across all rows\n\n**Responses:**\n- `200 OK` — instance + dashboard summary\n- `404 Not Found` — instance ID does not exist\n\n**Sales-channel scoping (`auto_track_channels`)** — optional. `default` is `all` (track everything not explicitly disabled) or `none` (track nothing until explicitly enabled). `channels` is an optional object keyed by sales-channel id; each entry may carry a boolean `enabled` flag and/or a `sub_channels` object keyed by sub-channel id (booleans). Resolution is most-specific-first: a `sub_channels` override wins, then the channel `enabled` flag, then `default`. Fulfillment type is modeled as a sub-channel (e.g. Amazon FBA vs merchant-fulfilled, or Shopify Web vs POS), so excluding high-volume marketplace-fulfilled shipments is just disabling that sub-channel. Only sales order fulfillments are scoped; other shipment types are unaffected. Validation: `default` must be `all` or `none` (422 otherwise)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"17TRACK Production\",\n    \"is_automatic_sync_enabled\": true,\n    \"auto_track\": {\n      \"sales_order_fulfillments\": true,\n      \"inbound_shipments\": true,\n      \"warehouse_transfer_shipments\": true,\n      \"rmas\": true,\n      \"vendor_credit_shipments\": true\n    },\n    \"auto_track_channels\": {\n      \"default\": \"all\",\n      \"channels\": {}\n    },\n    \"webhook_url\": \"https://acme.sku.io/webhooks/seventeentrack/wh_aB3cD4eF5gH6iJ7kL8mN9oP\",\n    \"quota\": {\n      \"used\": 412,\n      \"total\": 1000,\n      \"remaining\": 588\n    },\n    \"status_counts\": {\n      \"pending\": 12,\n      \"info_received\": 31,\n      \"in_transit\": 184,\n      \"available_for_pickup\": 7,\n      \"out_for_delivery\": 22,\n      \"delivered\": 1043,\n      \"delivery_failure\": 4,\n      \"exception\": 9,\n      \"expired\": 3,\n      \"not_found\": 1\n    },\n    \"pending_registration_count\": 14,\n    \"registration_errors\": [\n      {\n        \"message\": \"Sorry, but due to the policy of carrier 'USPS' (code '21051'), registration is temporarily unavailable. Please complete the quota purchase and configure the 'Special Carriers' before proceeding.\",\n        \"count\": 14,\n        \"last_failed_at\": \"2026-06-27T08:55:16+00:00\"\n      }\n    ],\n    \"last_webhook_at\": \"2026-06-18T14:28:11+00:00\",\n    \"last_event_at\": \"2026-06-18T14:27:55+00:00\",\n    \"created_at\": \"2026-06-01T09:00:00+00:00\",\n    \"updated_at\": \"2026-06-18T14:28:11+00:00\"\n  }\n}"}]},{"name":"Update 17TRACK Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Patch any combination of `name`, `api_key`, per-entity `auto_track` toggles, or the `is_automatic_sync_enabled` flag on the singleton instance. All fields are optional; only the keys present in the request body are applied.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed by the dashboard's per-entity toggles, the rename action, key rotation, and the automatic-sync flip.\n\n**Optional Fields:**\n- `name` — string, max 255 chars\n- `api_key` — string, 8–255 chars (key rotation)\n- `auto_track.sales_order_fulfillments` — boolean\n- `auto_track.inbound_shipments` — boolean\n- `auto_track.warehouse_transfer_shipments` — boolean\n- `auto_track.rmas` — boolean\n- `auto_track.vendor_credit_shipments` — boolean\n- `is_automatic_sync_enabled` — boolean (global polling/sync kill switch)\n\n**Responses:**\n- `200 OK` — returns the updated instance (without the live dashboard summary; call `GET` to re-hydrate it)\n- `422 Unprocessable Entity` — validation failure\n\n**Alert & side-effect settings (all optional):**\n- `side_effects.vendor_credit_shipment_auto_delivered` (boolean, default true) — auto-set the vendor credit shipment's status to Delivered when the carrier confirms delivery\n- `side_effects.inbound_shipment_arrival_alert` (boolean, default true) — in-app admin alert \"package delivered — ready to receive\" for inbound shipments\n- `side_effects.rma_arrival_alert` (boolean, default true) — in-app admin alert \"package delivered — ready to inspect\" for RMAs\n- `quota_alert_threshold` (integer 1–99, default 80) — quota usage % at which admins get a warning alert; a second high-priority alert always fires at 100% (exhausted). Changing the threshold re-arms the alert state machine.\n\nThe instance resource now also returns `side_effects`, `quota_alert_threshold`, and a `transit` analytics block (avg days in transit + on-time-vs-ETA rate for rows delivered in the last 90 days, overall and per carrier).\n\n**Sales-channel scoping (`auto_track_channels`)** — optional. `default` is `all` (track everything not explicitly disabled) or `none` (track nothing until explicitly enabled). `channels` is an optional object keyed by sales-channel id; each entry may carry a boolean `enabled` flag and/or a `sub_channels` object keyed by sub-channel id (booleans). Resolution is most-specific-first: a `sub_channels` override wins, then the channel `enabled` flag, then `default`. Fulfillment type is modeled as a sub-channel (e.g. Amazon FBA vs merchant-fulfilled, or Shopify Web vs POS), so excluding high-volume marketplace-fulfilled shipments is just disabling that sub-channel. Only sales order fulfillments are scoped; other shipment types are unaffected. Validation: `default` must be `all` or `none` (422 otherwise).","body":{"mode":"raw","raw":"{\n  \"name\": \"My 17TRACK\",\n  \"api_key\": \"ABCDEF1234567890\",\n  \"is_automatic_sync_enabled\": true,\n  \"auto_track\": {\n    \"sales_order_fulfillments\": true,\n    \"inbound_shipments\": true,\n    \"warehouse_transfer_shipments\": true,\n    \"rmas\": true,\n    \"vendor_credit_shipments\": true\n  },\n  \"auto_track_channels\": {\n    \"default\": \"none\",\n    \"channels\": {\n      \"3\": {\n        \"sub_channels\": {\n          \"31\": false,\n          \"32\": true\n        }\n      },\n      \"5\": {\n        \"enabled\": true\n      }\n    }\n  },\n  \"side_effects\": {\n    \"vendor_credit_shipment_auto_delivered\": true,\n    \"inbound_shipment_arrival_alert\": true,\n    \"rma_arrival_alert\": true\n  },\n  \"quota_alert_threshold\": 80\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"17TRACK Production (Updated)\",\n    \"is_automatic_sync_enabled\": true,\n    \"auto_track\": {\n      \"sales_order_fulfillments\": true,\n      \"inbound_shipments\": false,\n      \"warehouse_transfer_shipments\": true,\n      \"rmas\": true,\n      \"vendor_credit_shipments\": true\n    },\n    \"auto_track_channels\": {\n      \"default\": \"none\",\n      \"channels\": {\n        \"3\": {\n          \"sub_channels\": {\n            \"31\": false,\n            \"32\": true\n          }\n        },\n        \"5\": {\n          \"enabled\": true\n        }\n      }\n    },\n    \"webhook_url\": null,\n    \"quota\": null,\n    \"status_counts\": null,\n    \"last_webhook_at\": null,\n    \"last_event_at\": null,\n    \"created_at\": \"2026-06-01T09:00:00+00:00\",\n    \"updated_at\": \"2026-06-18T14:35:42+00:00\"\n  }\n}"}]},{"name":"Disconnect 17TRACK Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Disconnect 17TRACK. Per the PRD edge-case spec:\n- Historical tracking rows are retained (read-only history is preserved).\n- Currently-active rows are stamped `stopped_at = now()` so polling stops.\n- The webhook token row in the central registry is removed.\n- The integration instance itself is deleted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns `204 No Content` on success."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Get Trackable Channels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/trackable-channels","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","trackable-channels"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"List every connected sales channel together with its sub-channels. 17TRACK auto-tracking is scoped per (sales channel, sub-channel) pair — fulfillment type (e.g. Amazon FBA vs merchant-fulfilled, or Shopify Web vs POS) is represented as a sub-channel. Channels with no sub-channels are tracked at the channel level and return an empty `sub_channels` array.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/trackable-channels","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","trackable-channels"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Amazon US\",\n      \"platform\": \"Amazon\",\n      \"icon_url\": \"/images/integrations/icons/amazon.svg\",\n      \"sub_channels\": [\n        {\n          \"id\": 31,\n          \"name\": \"FBA\",\n          \"external_identifier\": \"FBA\"\n        },\n        {\n          \"id\": 32,\n          \"name\": \"MFN\",\n          \"external_identifier\": \"MFN\"\n        }\n      ]\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Shopify Main Store\",\n      \"platform\": \"Shopify\",\n      \"icon_url\": \"/images/integrations/icons/shopify.svg\",\n      \"sub_channels\": [\n        {\n          \"id\": 40,\n          \"name\": \"Web\",\n          \"external_identifier\": \"web\"\n        },\n        {\n          \"id\": 41,\n          \"name\": \"Pos\",\n          \"external_identifier\": \"pos\"\n        }\n      ]\n    },\n    {\n      \"id\": 7,\n      \"name\": \"eBay Store\",\n      \"platform\": \"Ebay\",\n      \"icon_url\": \"/images/integrations/icons/ebay.svg\",\n      \"sub_channels\": []\n    }\n  ]\n}"}]},{"name":"List Instance Trackings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/trackings","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","trackings"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Paginated list of shipment_trackings rows scoped to a single 17TRACK integration instance. Powers the \"Trackings\" sub-page of the 17TRACK integration UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters / sorts / `per_page` are read directly from the request via Spatie QueryBuilder.\n\n**Supported filters:**\n- `filter[search]` — substring match on tracking_number\n- `filter[delivery_status]` — comma-separated DeliveryStatusEnum values\n- `filter[carrier_code]` — comma-separated 17TRACK numeric carrier codes\n- `filter[trackable_type]` — comma-separated trackable type slugs OR FQCNs\n- `filter[date_from]`, `filter[date_to]` — m/d/Y, applied to created_at\n\n**Allowed sorts:** `created_at`, `last_event_at`, `delivered_at` (default: `-created_at`).\n\n**Responses:**\n- `200 OK` — paginated tracking rows\n- `401 Unauthorized` — missing/invalid bearer token\n- `404 Not Found` — instance id does not exist"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/trackings","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","trackings"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"trackable_type\": \"sales_order_fulfillment\",\n      \"trackable_id\": 1801,\n      \"trackable_label\": \"SO-1234 / FUL-1801\",\n      \"trackable_url\": \"/v2/orders/sales-orders/1234\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier_code\": 100002,\n      \"carrier_name\": \"UPS\",\n      \"delivery_status\": \"in_transit\",\n      \"delivery_status_label\": \"In Transit\",\n      \"delivery_status_color\": \"blue\",\n      \"sub_status\": \"InTransit_CustomsProcessing\",\n      \"latest_event_description\": \"Departed UPS facility\",\n      \"latest_event_location\": \"Memphis, TN\",\n      \"last_event_at\": \"2026-06-09T13:14:00+00:00\",\n      \"estimated_delivery_at\": \"2026-06-11T00:00:00+00:00\",\n      \"delivered_at\": null,\n      \"picked_up_at\": \"2026-06-08T20:30:00+00:00\",\n      \"registered_at\": \"2026-06-08T19:55:00+00:00\",\n      \"registration_error\": null,\n      \"stopped_at\": null,\n      \"created_at\": \"2026-06-08T19:55:00+00:00\"\n    },\n    {\n      \"id\": 43,\n      \"trackable_type\": \"sales_order_fulfillment\",\n      \"trackable_id\": 1802,\n      \"trackable_label\": \"SO-1235 / FUL-1802\",\n      \"trackable_url\": \"/v2/orders/sales-orders/1235\",\n      \"tracking_number\": \"9405550105799029763087\",\n      \"carrier_code\": null,\n      \"carrier_name\": null,\n      \"delivery_status\": \"pending\",\n      \"delivery_status_label\": \"Pending\",\n      \"delivery_status_color\": \"grey\",\n      \"sub_status\": null,\n      \"latest_event_description\": null,\n      \"latest_event_location\": null,\n      \"last_event_at\": null,\n      \"estimated_delivery_at\": null,\n      \"delivered_at\": null,\n      \"picked_up_at\": null,\n      \"registered_at\": null,\n      \"registration_error\": \"Sorry, but due to the policy of carrier 'USPS' (code '21051'), registration is temporarily unavailable. Please complete the quota purchase and configure the 'Special Carriers' before proceeding.\",\n      \"stopped_at\": null,\n      \"created_at\": \"2026-06-25T15:18:32+00:00\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"https://example.test/api/integrations/17track/instances/1/trackings?page=1\",\n    \"last\": \"https://example.test/api/integrations/17track/instances/1/trackings?page=10\",\n    \"prev\": null,\n    \"next\": \"https://example.test/api/integrations/17track/instances/1/trackings?page=2\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 10,\n    \"per_page\": 15,\n    \"to\": 15,\n    \"total\": 150,\n    \"path\": \"https://example.test/api/integrations/17track/instances/1/trackings\"\n  }\n}"}]},{"name":"List Instance Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/webhooks","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","webhooks"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Paginated audit log of every 17TRACK webhook received for this integration instance. One row per inbound webhook, persisted by a background job BEFORE processing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPowers the \"Webhooks\" sub-page of the 17TRACK integration UI.\n\n**Supported filters:**\n- `filter[event_type]` — comma-separated 17TRACK event types\n- `filter[result]` — comma-separated outcomes (processed, failed, ignored)\n- `filter[tracking_number]` — substring match on tracking_number\n- `filter[date_from]`, `filter[date_to]` — m/d/Y, applied to received_at\n\n**Allowed sorts:** `received_at`, `created_at`, `event_type`, `result` (default: `-received_at`).\n\n**Each row includes a precomputed `summary` string** like \"In Transit → Delivered\".\n\n**Responses:**\n- `200 OK` — paginated webhook event rows\n- `401 Unauthorized` — missing/invalid bearer token\n- `404 Not Found` — instance id does not exist"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/webhooks","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","webhooks"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 99,\n      \"integration_instance_id\": 1,\n      \"received_at\": \"2026-06-18T15:42:00+00:00\",\n      \"event_type\": \"TRACKING_UPDATED\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"status_from\": \"In Transit\",\n      \"status_to\": \"Delivered\",\n      \"summary\": \"In Transit → Delivered\",\n      \"payload\": {\n        \"event\": \"TRACKING_UPDATED\",\n        \"data\": {\n          \"number\": \"1Z999AA10123456784\",\n          \"carrier\": 100002,\n          \"track_info\": {\n            \"latest_status\": {\n              \"status\": \"Delivered\",\n              \"sub_status\": \"Delivered_001\"\n            }\n          }\n        }\n      },\n      \"result\": \"processed\",\n      \"error_message\": null,\n      \"processing_duration_ms\": 42,\n      \"created_at\": \"2026-06-18T15:42:00+00:00\",\n      \"updated_at\": \"2026-06-18T15:42:00+00:00\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"https://example.test/api/integrations/17track/instances/1/webhooks?page=1\",\n    \"last\": \"https://example.test/api/integrations/17track/instances/1/webhooks?page=5\",\n    \"prev\": null,\n    \"next\": \"https://example.test/api/integrations/17track/instances/1/webhooks?page=2\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 5,\n    \"per_page\": 15,\n    \"to\": 15,\n    \"total\": 75,\n    \"path\": \"https://example.test/api/integrations/17track/instances/1/webhooks\"\n  }\n}"}]},{"name":"List Instance Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/activity","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","activity"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]},"description":"Paginated activity log entries scoped to a single 17TRACK integration instance. Surfaces both (1) rows where the instance itself is the activity subject (connect / settings update / disconnect) and (2) rows where `properties.integration_instance_id` matches (webhook ingest, backfill, quota threshold).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPowers the \"Activity\" sub-page of the 17TRACK integration UI.\n\n**Supported filters:**\n- `filter[event_type]` — comma-separated activity event names (Spatie `event` column)\n- `filter[causer_id]` — comma-separated user IDs\n- `filter[search]` — substring match on description\n- `filter[date_from]`, `filter[date_to]` — m/d/Y, applied to created_at\n\n**Allowed sorts:** `created_at`, `event`, `id` (default: `-created_at, -id`).\n\n**Common event values emitted by the 17TRACK module:**\n- `connected` — Integration connected (causer = user)\n- `updated` — Settings updated (properties.changed_keys)\n- `disconnected` — Integration disconnected\n- `webhook_processed` / `webhook_failed` — per webhook ingest\n- `backfill_started` / `backfill_completed` — historical backfill job\n- `quota_exceeded` — quota threshold reached (no causer)\n\n**Responses:**\n- `200 OK` — paginated activity rows\n- `401 Unauthorized` — missing/invalid bearer token\n- `404 Not Found` — instance id does not exist"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance}/activity","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance","activity"],"variable":[{"key":"instance","value":"1","description":"ID of the 17TRACK integration instance."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"event\": \"webhook_processed\",\n      \"description\": \"Webhook processed\",\n      \"causer\": null,\n      \"properties\": {\n        \"integration_instance_id\": 1,\n        \"event_type\": \"TRACKING_UPDATED\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"updated\": 1,\n        \"status_from\": \"In Transit\",\n        \"status_to\": \"Delivered\"\n      },\n      \"created_at\": \"2026-06-18T15:42:00+00:00\",\n      \"occurred_at_human\": \"2 minutes ago\"\n    },\n    {\n      \"id\": 511,\n      \"event\": \"updated\",\n      \"description\": \"Settings updated\",\n      \"causer\": {\n        \"id\": 5,\n        \"name\": \"Operations Lead\",\n        \"email\": \"ops@example.com\"\n      },\n      \"properties\": {\n        \"integration_instance_id\": 1,\n        \"changed_keys\": [\n          \"auto_track\",\n          \"name\"\n        ]\n      },\n      \"created_at\": \"2026-06-18T14:10:00+00:00\",\n      \"occurred_at_human\": \"1 hour ago\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"https://example.test/api/integrations/17track/instances/1/activity?page=1\",\n    \"last\": \"https://example.test/api/integrations/17track/instances/1/activity?page=20\",\n    \"prev\": null,\n    \"next\": \"https://example.test/api/integrations/17track/instances/1/activity?page=2\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 20,\n    \"per_page\": 15,\n    \"to\": 15,\n    \"total\": 300,\n    \"path\": \"https://example.test/api/integrations/17track/instances/1/activity\"\n  }\n}"}]},{"name":"List Shipment Trackings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipment-trackings","host":["{{baseUrl}}"],"path":["api","shipment-trackings"]},"description":"Paginated cross-entity listing of shipment tracking rows. Powers the Delivery Exceptions view, the global Trackings table, and per-entity filtered subsets.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters / sorts / `per_page` are read directly from the request by the repository per the Spatie QueryBuilder pagination idiom.\n\n**Allowed filters (`filter[...]`):**\n- `delivery_status` — comma-separated `DeliveryStatusEnum` values\n- `trackable_type` — comma-separated friendly slugs (see query param description for the full alias list)\n- `search` — substring match on `tracking_number`\n- `date_from` / `date_to` — `m/d/Y` bounds on `last_event_at` (app timezone)\n- `stalled` — `1` for `in_transit` rows whose last event is >7 days old\n- `integration_instance_id` — exact match\n\n**Allowed sorts:** `id`, `created_at`, `last_event_at`, `delivery_status`. Prefix with `-` for DESC.\n\n**The canonical Delivery Exceptions query:**\n```\n?filter[delivery_status]=exception,delivery_failure,expired&filter[stalled]=1\n```\nThese statuses are the ones flagged by `DeliveryStatusEnum::isException`; `stalled=1` adds in_transit rows that have stopped moving.\n\n**Response shape:** Standard Laravel `LengthAwarePaginator` JSON with `data[]`, `current_page`, `last_page`, `per_page`, `total`, `from`, `to`, `*_page_url`, `path`, `links`. Each row in `data[]` is shaped as a shipment tracking object."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipment-trackings","host":["{{baseUrl}}"],"path":["api","shipment-trackings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"trackable_type\": \"sales_order_fulfillment\",\n      \"trackable_id\": 9132,\n      \"trackable_label\": \"SO-7411 / FUL-9132\",\n      \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier_code\": 100002,\n      \"carrier_name\": \"UPS\",\n      \"delivery_status\": \"exception\",\n      \"delivery_status_label\": \"Exception\",\n      \"delivery_status_color\": \"error\",\n      \"sub_status\": \"Exception_Other\",\n      \"latest_event_description\": \"Customs clearance delayed — documentation required\",\n      \"latest_event_location\": \"Cincinnati, OH, US\",\n      \"last_event_at\": \"2026-06-15T08:12:00+00:00\",\n      \"estimated_delivery_at\": null,\n      \"delivered_at\": null,\n      \"registered_at\": \"2026-06-12T16:04:21+00:00\",\n      \"stopped_at\": null,\n      \"created_at\": \"2026-06-12T15:58:00+00:00\"\n    },\n    {\n      \"id\": 4819,\n      \"trackable_type\": \"inbound_shipment\",\n      \"trackable_id\": 312,\n      \"trackable_label\": \"INB-2026-0312\",\n      \"trackable_url\": \"/v2/inbound-shipments/312\",\n      \"tracking_number\": \"9400111899223345678901\",\n      \"carrier_code\": 21051,\n      \"carrier_name\": \"USPS\",\n      \"delivery_status\": \"delivery_failure\",\n      \"delivery_status_label\": \"Delivery Failure\",\n      \"delivery_status_color\": \"orange\",\n      \"sub_status\": \"DeliveryFailure_NoBody\",\n      \"latest_event_description\": \"Delivery attempted — no one available to sign\",\n      \"latest_event_location\": \"San Francisco, CA, US\",\n      \"last_event_at\": \"2026-06-17T19:44:00+00:00\",\n      \"estimated_delivery_at\": \"2026-06-18T00:00:00+00:00\",\n      \"delivered_at\": null,\n      \"registered_at\": \"2026-06-10T11:02:00+00:00\",\n      \"stopped_at\": null,\n      \"created_at\": \"2026-06-10T11:00:00+00:00\"\n    },\n    {\n      \"id\": 4775,\n      \"trackable_type\": \"sales_order_fulfillment\",\n      \"trackable_id\": 9001,\n      \"trackable_label\": \"SO-7388 / FUL-9001\",\n      \"trackable_url\": \"/v2/orders/sales-orders/7388\",\n      \"tracking_number\": \"LX123456789CN\",\n      \"carrier_code\": 3011,\n      \"carrier_name\": \"China Post\",\n      \"delivery_status\": \"expired\",\n      \"delivery_status_label\": \"Expired\",\n      \"delivery_status_color\": \"grey-darken-2\",\n      \"sub_status\": null,\n      \"latest_event_description\": \"No tracking events in 60+ days — tracking expired\",\n      \"latest_event_location\": null,\n      \"last_event_at\": \"2026-04-10T03:21:00+00:00\",\n      \"estimated_delivery_at\": null,\n      \"delivered_at\": null,\n      \"registered_at\": \"2026-04-08T09:14:00+00:00\",\n      \"stopped_at\": \"2026-06-09T03:21:00+00:00\",\n      \"created_at\": \"2026-04-08T09:12:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 3,\n  \"from\": 1,\n  \"to\": 3,\n  \"first_page_url\": \"https://acme.sku.io/api/shipment-trackings?page=1\",\n  \"last_page_url\": \"https://acme.sku.io/api/shipment-trackings?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"https://acme.sku.io/api/shipment-trackings\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://acme.sku.io/api/shipment-trackings?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ]\n}"}]},{"name":"Get Shipment Tracking","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row."}]},"description":"Single tracking row with the FULL event timeline + integration instance descriptor. Powers the per-row timeline detail view in the Delivery Exceptions view and on entity detail pages.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse adds the following on top of the listing shape:\n- `events` — ordered array of carrier events (`events_payload` JSON column)\n- `registration_error` — last registration error string from 17TRACK if any\n- `integration_instance` — the parent instance `{ id, name }`\n\n**Responses:**\n- `200 OK` — detail payload\n- `404 Not Found` — tracking ID does not exist"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"trackable_type\": \"sales_order_fulfillment\",\n    \"trackable_id\": 9132,\n    \"trackable_label\": \"SO-7411 / FUL-9132\",\n    \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier_code\": 100002,\n    \"carrier_name\": \"UPS\",\n    \"delivery_status\": \"exception\",\n    \"delivery_status_label\": \"Exception\",\n    \"delivery_status_color\": \"error\",\n    \"sub_status\": \"Exception_Other\",\n    \"latest_event_description\": \"Customs clearance delayed — documentation required\",\n    \"latest_event_location\": \"Cincinnati, OH, US\",\n    \"last_event_at\": \"2026-06-15T08:12:00+00:00\",\n    \"estimated_delivery_at\": null,\n    \"delivered_at\": null,\n    \"registered_at\": \"2026-06-12T16:04:21+00:00\",\n    \"stopped_at\": null,\n    \"created_at\": \"2026-06-12T15:58:00+00:00\",\n    \"events\": [\n      {\n        \"time_iso\": \"2026-06-15T08:12:00+00:00\",\n        \"location\": \"Cincinnati, OH, US\",\n        \"description\": \"Customs clearance delayed — documentation required\",\n        \"stage\": \"Exception\",\n        \"sub_status\": \"Exception_Other\"\n      },\n      {\n        \"time_iso\": \"2026-06-14T22:05:00+00:00\",\n        \"location\": \"Louisville, KY, US\",\n        \"description\": \"Arrived at facility\",\n        \"stage\": \"InTransit\",\n        \"sub_status\": null\n      },\n      {\n        \"time_iso\": \"2026-06-13T09:30:00+00:00\",\n        \"location\": \"Cincinnati, OH, US\",\n        \"description\": \"Departed origin facility\",\n        \"stage\": \"InTransit\",\n        \"sub_status\": null\n      },\n      {\n        \"time_iso\": \"2026-06-12T16:08:00+00:00\",\n        \"location\": null,\n        \"description\": \"Shipper created label\",\n        \"stage\": \"InfoReceived\",\n        \"sub_status\": null\n      }\n    ],\n    \"registration_error\": null,\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"17TRACK Production\"\n    }\n  }\n}"}]},{"name":"Refresh Shipment Tracking","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/refresh","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","refresh"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row to refresh."}]},"description":"On-demand refresh — hits 17TRACK's `/gettrackinfo` synchronously and re-hydrates the local row (events, status, sub_status, estimated_delivery_at, etc.). Returns the same shape as `GET /shipment-trackings/{id}` so the timeline detail view can swap the payload in-place.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Responses:**\n- `200 OK` — refreshed detail payload (same shape as GET)\n- `422 Unprocessable Entity` with `code: refresh_failed` — 17TRACK API rejected the request (quota exceeded, rate-limited, connector failure). The timeline detail view surfaces this as a friendly error toast.\n- `404 Not Found` — tracking ID does not exist"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/refresh","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","refresh"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row to refresh."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"trackable_type\": \"sales_order_fulfillment\",\n    \"trackable_id\": 9132,\n    \"trackable_label\": \"SO-7411 / FUL-9132\",\n    \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier_code\": 100002,\n    \"carrier_name\": \"UPS\",\n    \"delivery_status\": \"in_transit\",\n    \"delivery_status_label\": \"In Transit\",\n    \"delivery_status_color\": \"blue\",\n    \"sub_status\": null,\n    \"latest_event_description\": \"Departed customs facility — documentation accepted\",\n    \"latest_event_location\": \"Cincinnati, OH, US\",\n    \"last_event_at\": \"2026-06-18T11:02:00+00:00\",\n    \"estimated_delivery_at\": \"2026-06-20T00:00:00+00:00\",\n    \"delivered_at\": null,\n    \"registered_at\": \"2026-06-12T16:04:21+00:00\",\n    \"stopped_at\": null,\n    \"created_at\": \"2026-06-12T15:58:00+00:00\",\n    \"events\": [\n      {\n        \"time_iso\": \"2026-06-18T11:02:00+00:00\",\n        \"location\": \"Cincinnati, OH, US\",\n        \"description\": \"Departed customs facility — documentation accepted\",\n        \"stage\": \"InTransit\",\n        \"sub_status\": null\n      },\n      {\n        \"time_iso\": \"2026-06-15T08:12:00+00:00\",\n        \"location\": \"Cincinnati, OH, US\",\n        \"description\": \"Customs clearance delayed — documentation required\",\n        \"stage\": \"Exception\",\n        \"sub_status\": \"Exception_Other\"\n      }\n    ],\n    \"registration_error\": null,\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"17TRACK Production\"\n    }\n  }\n}"}]},{"name":"Register Shipment Tracking","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/register","host":["{{baseUrl}}"],"path":["api","shipment-trackings","register"]},"description":"Manual `Track this shipment` trigger from an entity detail page. Resolves the entity, creates a pending `shipment_trackings` row via the manager, and kicks off a background job so the row gets pushed to 17TRACK promptly.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Required Fields:**\n- `trackable_type` — friendly slug. One of: `sales_order_fulfillment`, `inbound_shipment`, `warehouse_transfer_shipment`, `rma`, `vendor_credit_shipment`\n- `trackable_id` — integer, min 1. The PK of the trackable entity.\n\n**Responses:**\n- `201 Created` — pending tracking row created (carrier event data not yet hydrated; the register job will fill it on the next tick)\n- `404 Not Found` — trackable entity does not exist\n- `422 Unprocessable Entity` with `code: not_connected` — no active 17TRACK instance\n- `422 Unprocessable Entity` with `code: register_skipped` — entity has an empty tracking number, OR auto-track is disabled for this entity type\n\nThis manual action bypasses the `auto_track_channels` sales-channel scoping — an explicit request to track one shipment always registers it, even if its channel is excluded from automatic tracking.","body":{"mode":"raw","raw":"{\n  \"trackable_type\": \"sales_order_fulfillment\",\n  \"trackable_id\": 9132\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/register","host":["{{baseUrl}}"],"path":["api","shipment-trackings","register"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4822,\n    \"trackable_type\": \"sales_order_fulfillment\",\n    \"trackable_id\": 9132,\n    \"trackable_label\": \"SO-7411 / FUL-9132\",\n    \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n    \"tracking_number\": \"1Z999AA10123456999\",\n    \"carrier_code\": null,\n    \"carrier_name\": null,\n    \"delivery_status\": \"pending\",\n    \"delivery_status_label\": \"Pending\",\n    \"delivery_status_color\": \"grey\",\n    \"sub_status\": null,\n    \"latest_event_description\": null,\n    \"latest_event_location\": null,\n    \"last_event_at\": null,\n    \"estimated_delivery_at\": null,\n    \"delivered_at\": null,\n    \"registered_at\": null,\n    \"stopped_at\": null,\n    \"created_at\": \"2026-06-18T14:40:00+00:00\"\n  }\n}"}]},{"name":"Backfill Shipment Trackings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/backfill","host":["{{baseUrl}}"],"path":["api","shipment-trackings","backfill"]},"description":"Kick off a background job that scans recent rows of the selected entity types and registers any that have a `tracking_number` but no `shipment_trackings` row yet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the `tracked_job_log_id` which can be polled for progress via the tracked job log endpoints.\n\n**Optional Fields:**\n- `entity_types` — array of strings. Defaults to all five. Each value must be one of: `sales_order_fulfillments`, `inbound_shipments`, `warehouse_transfer_shipments`, `rmas`, `vendor_credit_shipments`.\n- `since_days` — integer, 1–365. Defaults to 30. Look-back window in days.\n\n**Responses:**\n- `200 OK` — backfill dispatched; payload contains `tracked_job_log_id`\n- `422 Unprocessable Entity` with `code: not_connected` — no active 17TRACK instance","body":{"mode":"raw","raw":"{\n  \"entity_types\": [\n    \"sales_order_fulfillments\",\n    \"inbound_shipments\",\n    \"warehouse_transfer_shipments\",\n    \"rmas\",\n    \"vendor_credit_shipments\"\n  ],\n  \"since_days\": 30\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/backfill","host":["{{baseUrl}}"],"path":["api","shipment-trackings","backfill"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 81244\n  },\n  \"message\": \"Backfill started — track progress in the job tray.\"\n}"}]},{"name":"Re-track Shipment Tracking","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/retrack","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","retrack"],"variable":[{"key":"tracking","value":"4821","description":"ID of the expired / stopped shipment tracking row to re-activate."}]},"description":"Re-activate tracking for an expired or stopped number via 17TRACK's `/retrack` endpoint. 17TRACK auto-stops tracking ~30 idle days after the last event; this asks it to resume pushing updates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOnly accepted for numbers 17TRACK has stopped following — an actively-tracked number is rejected. Each number can be re-tracked ONCE (17TRACK limit -18019905).\n\nOn success the local row's `stopped_at` is cleared, `delivery_status` resets to `pending` (re-entering the polling set), and the row is immediately re-hydrated via `/gettrackinfo`.\n\n**Responses:**\n- `200 OK` — re-hydrated detail payload (same shape as `GET /shipment-trackings/{id}`)\n- `422 Unprocessable Entity` with `code: retrack_failed` — 17TRACK rejected the retrack (number still active, retrack already used once, connector failure)\n- `404 Not Found` — tracking ID does not exist"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/retrack","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","retrack"],"variable":[{"key":"tracking","value":"4821","description":"ID of the expired / stopped shipment tracking row to re-activate."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"trackable_type\": \"sales_order_fulfillment\",\n    \"trackable_id\": 9132,\n    \"trackable_label\": \"SO-7411 / FUL-9132\",\n    \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier_code\": 100002,\n    \"carrier_name\": \"UPS\",\n    \"delivery_status\": \"pending\",\n    \"delivery_status_label\": \"Pending\",\n    \"delivery_status_color\": \"grey\",\n    \"sub_status\": null,\n    \"latest_event_description\": \"Departed UPS facility\",\n    \"latest_event_location\": \"Memphis, TN\",\n    \"last_event_at\": \"2026-06-09T13:14:00+00:00\",\n    \"estimated_delivery_at\": \"2026-06-11T00:00:00+00:00\",\n    \"delivered_at\": null,\n    \"registered_at\": \"2026-05-12T16:04:21+00:00\",\n    \"registration_error\": null,\n    \"stopped_at\": null,\n    \"created_at\": \"2026-05-12T15:58:00+00:00\",\n    \"events\": [],\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"17TRACK\"\n    }\n  },\n  \"message\": \"Re-tracking started — 17TRACK will resume pushing updates for this number.\"\n}"}]},{"name":"Change Shipment Tracking Carrier","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/change-carrier","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","change-carrier"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row whose carrier was mis-detected."}]},"description":"Correct a mis-detected carrier via 17TRACK's `/changecarrier` endpoint and re-hydrate the row under the new carrier. 17TRACK auto-detects the carrier from the number format when registering and sometimes picks wrong — this fixes it without stopping/re-registering.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n17TRACK caps carrier changes at 5 per number (error -18019807).\n\n**Request body:**\n- `carrier_code` (integer, required) — 17TRACK numeric carrier key the shipment actually ships with. Carriers configured in SKU.io (Settings → Shipping Carriers) can carry a `seventeen_track_carrier_code`; the full directory is at https://res.17track.net/asset/carrier/info/apicarrier.all.json.\n\nOn success the local row's `carrier_code` is updated, `carrier_name` clears (re-hydrated on the next `/gettrackinfo`), and the tracking history reloads under the new carrier.\n\n**Responses:**\n- `200 OK` — re-hydrated detail payload\n- `422 Unprocessable Entity` with `code: change_carrier_failed` — 17TRACK rejected the change, or validation failed (missing/invalid `carrier_code`)\n- `404 Not Found` — tracking ID does not exist","body":{"mode":"raw","raw":"{\n  \"carrier_code\": 21051\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/{tracking}/change-carrier","host":["{{baseUrl}}"],"path":["api","shipment-trackings",":tracking","change-carrier"],"variable":[{"key":"tracking","value":"4821","description":"ID of the shipment tracking row whose carrier was mis-detected."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"trackable_type\": \"sales_order_fulfillment\",\n    \"trackable_id\": 9132,\n    \"trackable_label\": \"SO-7411 / FUL-9132\",\n    \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier_code\": 100002,\n    \"carrier_name\": \"UPS\",\n    \"delivery_status\": \"pending\",\n    \"delivery_status_label\": \"Pending\",\n    \"delivery_status_color\": \"grey\",\n    \"sub_status\": null,\n    \"latest_event_description\": \"Departed UPS facility\",\n    \"latest_event_location\": \"Memphis, TN\",\n    \"last_event_at\": \"2026-06-09T13:14:00+00:00\",\n    \"estimated_delivery_at\": \"2026-06-11T00:00:00+00:00\",\n    \"delivered_at\": null,\n    \"registered_at\": \"2026-05-12T16:04:21+00:00\",\n    \"registration_error\": null,\n    \"stopped_at\": null,\n    \"created_at\": \"2026-05-12T15:58:00+00:00\",\n    \"events\": [],\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"17TRACK\"\n    }\n  },\n  \"message\": \"Re-tracking started — 17TRACK will resume pushing updates for this number.\"\n}"}]},{"name":"Register Parcel Trackings (Multi-Parcel)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipment-trackings/register-parcels","host":["{{baseUrl}}"],"path":["api","shipment-trackings","register-parcels"]},"description":"Register additional parcel tracking numbers against ONE entity — the multi-parcel path for shipments split across several cartons (each with its own carrier number). The entity's primary `tracking_number` is registered by the save observer; this endpoint covers the remaining boxes so every carton tracks independently.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n- `trackable_type` (string, required) — one of `sales_order_fulfillment`, `inbound_shipment`, `warehouse_transfer_shipment`, `rma`, `vendor_credit_shipment`\n- `trackable_id` (integer, required) — ID of the entity\n- `tracking_numbers` (string[], required, 1–40 items) — parcel tracking numbers to register\n\nNumbers already tracked for the entity are skipped; garbage values (`n/a`, `local pickup`, …) are dropped; new rows are created `pending` and pushed via the debounced batch register job. Respects the per-entity auto-track toggle.\n\n**Responses:**\n- `201 Created` — array of the queued tracking rows\n- `422 Unprocessable Entity` with `code: register_skipped` — every number was already tracked / dropped, or auto-track is disabled for this entity type\n- `422 Unprocessable Entity` with `code: not_connected` — 17TRACK is not connected\n- `404 Not Found` — trackable entity does not exist\n\nThis manual action bypasses the `auto_track_channels` sales-channel scoping — an explicit request to track one shipment always registers it, even if its channel is excluded from automatic tracking.","body":{"mode":"raw","raw":"{\n  \"trackable_type\": \"sales_order_fulfillment\",\n  \"trackable_id\": 9132,\n  \"tracking_numbers\": [\n    \"1Z999AA10123456791\",\n    \"1Z999AA10123456806\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipment-trackings/register-parcels","host":["{{baseUrl}}"],"path":["api","shipment-trackings","register-parcels"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4899,\n      \"trackable_type\": \"sales_order_fulfillment\",\n      \"trackable_id\": 9132,\n      \"trackable_label\": \"SO-7411 / FUL-9132\",\n      \"trackable_url\": \"/v2/orders/sales-orders/7411\",\n      \"tracking_number\": \"1Z999AA10123456791\",\n      \"carrier_code\": null,\n      \"carrier_name\": null,\n      \"delivery_status\": \"pending\",\n      \"delivery_status_label\": \"Pending\",\n      \"delivery_status_color\": \"grey\",\n      \"sub_status\": null,\n      \"registered_at\": null,\n      \"registration_error\": null,\n      \"stopped_at\": null,\n      \"created_at\": \"2026-07-03T15:40:00+00:00\"\n    }\n  ],\n  \"message\": \"2 parcel(s) queued for tracking.\"\n}"}]},{"name":"17TRACK Webhook (TRACKING_UPDATED)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/webhooks/seventeentrack/{webhook_token}","host":["{{baseUrl}}"],"path":["webhooks","seventeentrack",":webhook_token"],"variable":[{"key":"webhook_token","value":"wh_aB3cD4eF5gH6iJ7kL8mN9oP","description":"Opaque per-instance token minted by the `WebhookRoutable` trait. Globally unique across all tenants. Pattern: `wh_[A-Za-z0-9]+`."}]},"description":"**This endpoint is INCOMING — it is called by 17TRACK, not by SKU.io clients. Documented here for reference only.**\n\nFull URL shape: `POST /webhooks/seventeentrack/{webhook_token}`. The token in the URL identifies the tenant + instance; the `sign` field at the top of the JSON body is an HMAC-SHA256 over the request body computed with the instance's API key as the HMAC secret — verified by `VerifySeventeenTrackWebhook` middleware before the controller runs.\n\n**Envelope (v2.4):**\n```\n{\n  \"event\": \"TRACKING_UPDATED\" | \"TRACKING_STOPPED\",\n  \"data\": { ... carrier-event payload ... },\n  \"sign\": \"<sha256-hex>\"\n}\n```\n\n**Behavior:**\n- Empty body → `200 { status: 'acknowledged' }` (avoids 17TRACK retry storm).\n- Missing `event` key → `200 { status: 'ignored' }`.\n- Valid payload → `200 { status: 'success' }` and a background job is dispatched for async ingest. Out-of-order events (older `last_event_at` than what's already stored) are dropped inside the repository.\n\n**Why always 200?** 17TRACK retries non-2xx responses for several hours. Any non-actionable scenario still acks with 200 to avoid bogus retry storms.","body":{"mode":"raw","raw":"{\n  \"event\": \"TRACKING_UPDATED\",\n  \"data\": {\n    \"number\": \"1Z999AA10123456784\",\n    \"carrier\": 100002,\n    \"track_info\": {\n      \"latest_status\": {\n        \"status\": \"InTransit\",\n        \"sub_status\": \"InTransit_Other\",\n        \"sub_status_descr\": null\n      },\n      \"latest_event\": {\n        \"time_iso\": \"2026-06-18T11:02:00+00:00\",\n        \"description\": \"Departed customs facility — documentation accepted\",\n        \"location\": \"Cincinnati, OH, US\",\n        \"stage\": \"InTransit\",\n        \"sub_status\": null\n      },\n      \"time_metrics\": {\n        \"estimated_delivery_date\": {\n          \"source\": \"Carrier\",\n          \"from\": \"2026-06-19\",\n          \"to\": \"2026-06-20\"\n        }\n      },\n      \"tracking\": {\n        \"providers\": [\n          {\n            \"events\": [\n              {\n                \"time_iso\": \"2026-06-18T11:02:00+00:00\",\n                \"location\": \"Cincinnati, OH, US\",\n                \"description\": \"Departed customs facility — documentation accepted\",\n                \"stage\": \"InTransit\"\n              },\n              {\n                \"time_iso\": \"2026-06-15T08:12:00+00:00\",\n                \"location\": \"Cincinnati, OH, US\",\n                \"description\": \"Customs clearance delayed — documentation required\",\n                \"stage\": \"Exception\"\n              }\n            ]\n          }\n        ]\n      }\n    }\n  },\n  \"sign\": \"7a3f1c9b4e2d8f0a6c5e9b1d4f7a2c0e8b5d3f1a9c7e4b2d6f0a8c3e5b1d4f7a\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/webhooks/seventeentrack/{webhook_token}","host":["{{baseUrl}}"],"path":["webhooks","seventeentrack",":webhook_token"],"variable":[{"key":"webhook_token","value":"wh_aB3cD4eF5gH6iJ7kL8mN9oP","description":"Opaque per-instance token minted by the `WebhookRoutable` trait. Globally unique across all tenants. Pattern: `wh_[A-Za-z0-9]+`."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"Register Tracking Numbers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/register","host":["{{baseUrl}}"],"path":["register"]},"description":"Register up to **40 tracking numbers per call** for auto-tracking.\n\n**Per-item fields:**\n- `number` (string, required) — the tracking number\n- `carrier` (int, optional) — 17TRACK carrier code; omit + set `auto_detection: true` to let 17TRACK guess\n- `auto_detection` (bool, optional) — fall back to auto-detect when carrier is unknown/wrong\n- `lang`, `order_no`, `order_time`, `tag`, `destination_country`, `destination_postal_code`, `shipper`, `consignee`, `phone_number_last_4`, `phone_number`, `email`, `remark` — optional enrichment fields\n\n**Response envelope:** `{code, data: {accepted, rejected}}`. Per-row rejections (already-registered, carrier not detected, …) come back in `data.rejected[]` with the error code — they're NOT envelope errors.\n\n**Common envelope error codes:**\n- `-18010002` invalid API key\n- `-18010014` rate limit exceeded (also HTTP 429)\n- `-18019907` daily tracking limit reached\n- `-18019908` monthly quota exhausted","body":{"mode":"raw","raw":"[\n  {\n    \"number\": \"RR123456789CN\",\n    \"carrier\": 3011,\n    \"auto_detection\": true,\n    \"lang\": \"en\",\n    \"order_no\": \"ORDER-1234\",\n    \"order_time\": \"2026-06-25\",\n    \"tag\": \"sku.io\",\n    \"destination_country\": \"US\",\n    \"destination_postal_code\": \"94110\",\n    \"shipper\": \"Acme Shipper\",\n    \"consignee\": \"Customer Name\"\n  }\n]","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/register","host":["{{baseUrl}}"],"path":["register"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"code\": 0,\n  \"data\": {\n    \"accepted\": [\n      {\n        \"origin\": 1,\n        \"number\": \"RR123456789CN\",\n        \"carrier\": 3011\n      }\n    ],\n    \"rejected\": []\n  }\n}"}]},{"name":"Pull Tracking Updates from 17TRACK","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance_id}/refresh","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance_id","refresh"],"variable":[{"key":"instance_id","value":"","description":"The instance ID."}]},"description":"Dispatch an immediate a background job — pulls the latest status from 17TRACK for non-terminal trackings whose last event is older than `instance.last_polled_at`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFires the same code path as the scheduled 6-hour poll. Tracked via `TrackedJobLog` so the tracked job log endpoints surfaces it.\n\n**Activity log:** writes `manual_refresh_triggered` (with causer = acting user)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance_id}/refresh","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance_id","refresh"],"variable":[{"key":"instance_id","value":"","description":"The instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 446215\n  },\n  \"message\": \"Sync started — track progress in the job tray.\"\n}"}]},{"name":"Push Pending Tracking Numbers to 17TRACK","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance_id}/push-pending","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance_id","push-pending"],"variable":[{"key":"instance_id","value":"","description":"The instance ID."}]},"description":"Push every pending or previously-failed tracking row to 17TRACK in one shot — manual recovery path for the **Sync to 17TRACK** button.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Pending = `registered_at IS NULL AND stopped_at IS NULL`** — covers (a) freshly-created rows the observer flow hasn't dispatched for yet, (b) rows whose previous register call failed with `quota_exceeded`, and (c) orphans from a transient API error.\n\n**Response branches:**\n- `tracked_job_log_id` set when a fresh job is queued\n- `tracked_job_log_id: null` when a push is already in flight (existing job will pick up the new rows)\n- `pending_count: 0` early-exit when nothing is pending (no wasted queue slot)\n\n**Activity log:** writes `manual_push_triggered` (with causer = acting user)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integrations/17track/instances/{instance_id}/push-pending","host":["{{baseUrl}}"],"path":["api","integrations","17track","instances",":instance_id","push-pending"],"variable":[{"key":"instance_id","value":"","description":"The instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 446299,\n    \"pending_count\": 13\n  },\n  \"message\": \"Pushing 13 tracking(s) to 17TRACK — track progress in the job tray.\"\n}"}]}]},{"name":"BigCommerce","item":[{"name":"Refresh Orders from BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Start a background refresh that downloads orders from BigCommerce into SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe `mode` field controls which orders are fetched:\n- `latest` (default) - orders modified since the most recent local order\n- `from_start_date` - orders modified since the integration's configured start date\n- `date_range` - orders modified within the `date_from` / `date_to` range\n- `all` - every order in the store\n\nThe job runs asynchronously. The response includes a `tracked_job_log_id` you can use to poll job progress.\n\nRoute name: big-commerce.orders.refresh-tracked","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-01-01\",\n  \"date_to\": \"2026-01-31\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5120\n  },\n  \"message\": \"Order refresh job has been queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Latest Order Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get a summary of the most recently synced BigCommerce order plus counts of how many local BigCommerce orders exist and how many are linked to SKU.io sales orders. Useful for deciding whether a refresh is needed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"118\",\n    \"latest_order_date\": \"2026-05-14T09:21:33.000000Z\",\n    \"latest_order_status\": \"Shipped\",\n    \"total_orders\": 1240,\n    \"with_sku_order\": 1180,\n    \"without_sku_order\": 60\n  }\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Archive multiple BigCommerce orders by their local IDs. Orders that are already archived are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.bulk-archive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513,\n    4514\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Restore multiple archived BigCommerce orders by their local IDs. Orders that are already active are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.bulk-unarchive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders unarchived successfully\",\n  \"unarchived_count\": 2\n}"}]},{"name":"Bulk Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Permanently delete multiple local BigCommerce order records by their local IDs. This removes the local copies only - orders in the BigCommerce store are not affected. Linked SKU.io sales orders are not deleted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.bulk-delete","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders deleted successfully\",\n  \"deleted_count\": 2\n}"}]},{"name":"Bulk Delete Linked SKU.io Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Delete the SKU.io sales orders linked to the given BigCommerce orders, keeping the BigCommerce order records intact. Set `archive_orders` to true to also archive the BigCommerce orders after their linked sales orders are removed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.bulk-delete-sku-orders","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ],\n  \"archive_orders\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 SKU orders deleted successfully and BigCommerce orders archived\",\n  \"deleted_count\": 2\n}"}]},{"name":"Update Linked SKU.io Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Re-apply BigCommerce order data to the linked SKU.io sales orders (statuses, totals, addresses, lines).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nTarget orders either with `ids` (local BigCommerce order IDs) or by setting `update_all_orders` to true. When `use_jobs` is true (default) the updates are processed asynchronously on the queue; set it to false to process synchronously within the request.\n\nRoute name: big-commerce.orders.update-sku-orders","body":{"mode":"raw","raw":"{\n  \"update_all_orders\": false,\n  \"ids\": [\n    4512,\n    4513\n  ],\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"Sku.io sales orders successfully updated\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Get the paginated activity history for a single BigCommerce order - status changes, sync events, and edits, with the user who caused each change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.activity-log"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"BigCommerceOrder\",\n      \"subject_id\": 4512,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"Shipped\"\n        },\n        \"old\": {\n          \"status\": \"Awaiting Fulfillment\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:25:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/big-commerce/1/orders/4512/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/big-commerce/1/orders/4512/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/orders/4512/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/orders/4512/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/big-commerce/1/orders/4512/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 6,\n  \"total\": 6\n}"}]},{"name":"Get Raw Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Fetch the raw order payload for a single order directly from the BigCommerce API (live request, not the locally cached copy).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.raw"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order\": {\n      \"id\": 118,\n      \"status\": \"Shipped\",\n      \"status_id\": 2,\n      \"date_created\": \"Thu, 14 May 2026 09:21:33 +0000\",\n      \"date_modified\": \"Fri, 15 May 2026 10:02:11 +0000\",\n      \"subtotal_ex_tax\": \"49.90\",\n      \"total_inc_tax\": \"58.30\",\n      \"currency_code\": \"USD\",\n      \"payment_method\": \"Credit Card\",\n      \"payment_status\": \"captured\",\n      \"items_total\": 3,\n      \"items_shipped\": 3,\n      \"billing_address\": {\n        \"first_name\": \"Jane\",\n        \"last_name\": \"Smith\",\n        \"email\": \"jane@example.com\",\n        \"city\": \"Austin\",\n        \"state\": \"Texas\",\n        \"country_iso2\": \"US\"\n      }\n    }\n  }\n}"}]},{"name":"Archive Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Archive a single BigCommerce order. Archived orders are hidden from active listings but remain stored and can be restored later.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.archive","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Restore a single archived BigCommerce order to the active list.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.unarchive","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Delete Linked SKU.io Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Delete the SKU.io sales order linked to a BigCommerce order, keeping the BigCommerce order record intact. Pass `archive_order=true` to also archive the BigCommerce order afterwards.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.delete-sku-order"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully and BigCommerce order archived\",\n  \"archived_order\": true\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"50","description":"BigCommerce order ID"}]},"description":"Get a single cached ShipStation order with the resolved SKU fulfillment link.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- `include_json` (optional, `1`/`true`): include the raw ShipStation `json_object`, per-item `product_links`, and the `merged_away` tombstone. The detail page always sends `include_json=1`.\n\nResponse notes:\n- `merged_away` (only when `include_json` is set): non-null ONLY when this order was absorbed by a carrier-side merge into a surviving order and then removed at ShipStation (its id 404s). It carries the surviving order's reference + a `survivor_detail_route` to its detail page. Null for ordinary orders.\n- `sku_fulfillment`: the linked SalesOrderFulfillment (or FulfillmentOrder fallback), null when unlinked."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"50","description":"BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 92889,\n    \"integration_instance_id\": 4,\n    \"shipstation_order_id\": 536921166,\n    \"order_key\": \"SKUio_local_63676_1\",\n    \"order_number\": \"#63676.1\",\n    \"external_url\": \"https://ship15.shipstation.com/orders/all-orders-search-result?quickSearch=%2363676.1\",\n    \"order_status\": \"awaiting_shipment\",\n    \"order_status_label\": \"Awaiting Shipment\",\n    \"order_status_color\": \"warning\",\n    \"customer_email\": \"rachel@example.com\",\n    \"order_date\": \"2026-06-23T13:07:03+00:00\",\n    \"ship_date\": null,\n    \"ship_by_date\": null,\n    \"carrier_code\": null,\n    \"service_code\": null,\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"shipments\": [],\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-06-29T10:05:16+00:00\",\n    \"created_at\": \"2026-06-23T13:07:03+00:00\",\n    \"updated_at\": \"2026-06-29T11:00:48+00:00\",\n    \"merged_away\": {\n      \"provider_label\": \"ShipStation\",\n      \"survivor_reference\": \"#63676.2\",\n      \"survivor_external_id\": 536921189,\n      \"survivor_internal_id\": 92890,\n      \"survivor_detail_route\": \"/integrations/shipstation/4/orders/92890\"\n    },\n    \"json_object\": {\n      \"orderId\": 536921166,\n      \"orderNumber\": \"#63676.1\",\n      \"orderStatus\": \"awaiting_shipment\",\n      \"advancedOptions\": {\n        \"mergedOrSplit\": null,\n        \"mergedIds\": null\n      }\n    },\n    \"product_links\": {}\n  }\n}"}]},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]},"description":"Permanently delete a single local BigCommerce order record. This removes the local copy only - the order in the BigCommerce store is not affected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.orders.destroy"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local BigCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order deleted successfully\"\n}"}]},{"name":"List Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Earliest order creation date (must be before the inventory start date).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Query the BigCommerce store live for orders created before your SKU.io inventory start date, so historical orders can be selectively imported without affecting inventory.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach returned order carries an `eligible` flag with an `eligibility_reason` (cancelled and refunded orders are not eligible) and an `already_imported` flag for orders that already exist locally.\n\nBoth dates must be before the inventory start date. Returns up to 2,500 matching orders per query.\n\nRoute name: big-commerce.pre-start-date-orders.query"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Earliest order creation date (must be before the inventory start date).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"bigcommerce_order_id\": 118,\n      \"name\": \"#118\",\n      \"email\": \"jane@example.com\",\n      \"created_at\": \"Mon, 03 Nov 2025 15:22:10 +0000\",\n      \"fulfillment_status\": \"FULFILLED\",\n      \"financial_status\": \"captured\",\n      \"total_price\": \"58.30\",\n      \"currency\": \"USD\",\n      \"fulfillments\": [\n        {\n          \"id\": null,\n          \"created_at\": \"Wed, 05 Nov 2025 09:00:00 +0000\",\n          \"status\": \"shipped\",\n          \"tracking_number\": null\n        }\n      ],\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Water Bottle 750ml\",\n          \"sku\": \"WB-750-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"24.95\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Search Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=118","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. Field to search by: order_number, order_id, or email.","disabled":true},{"key":"search_term","value":"118","description":"Required. Value to search for (max 255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Search the BigCommerce store for specific pre-start-date orders by order number, order ID, or customer email. Returns the same response format as the list endpoint, including eligibility and already-imported flags.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.pre-start-date-orders.search"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=118","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. Field to search by: order_number, order_id, or email.","disabled":true},{"key":"search_term","value":"118","description":"Required. Value to search for (max 255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"bigcommerce_order_id\": 118,\n      \"name\": \"#118\",\n      \"email\": \"jane@example.com\",\n      \"created_at\": \"Mon, 03 Nov 2025 15:22:10 +0000\",\n      \"fulfillment_status\": \"FULFILLED\",\n      \"financial_status\": \"captured\",\n      \"total_price\": \"58.30\",\n      \"currency\": \"USD\",\n      \"fulfillments\": [\n        {\n          \"id\": null,\n          \"created_at\": \"Wed, 05 Nov 2025 09:00:00 +0000\",\n          \"status\": \"shipped\",\n          \"tracking_number\": null\n        }\n      ],\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Water Bottle 750ml\",\n          \"sku\": \"WB-750-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"24.95\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Import selected pre-start-date orders from BigCommerce by their BigCommerce order IDs (max 10,000 per request). Because each order is fetched individually from BigCommerce, the import runs asynchronously as a background job. The response returns a tracked_job_log_id you can poll to follow progress and the per-order outcome (imported, marked, skipped, or error). Orders that already exist locally are marked as pre-start-date imports instead of duplicated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.pre-start-date-orders.import","body":{"mode":"raw","raw":"{\n  \"bigcommerce_order_ids\": [\n    118,\n    119\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8842\n  },\n  \"message\": \"Importing 2 pre-start-date orders — track progress in the job tray.\"\n}"}]},{"name":"Refresh Products from BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Start a background refresh that downloads the product catalog from BigCommerce into SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. The response includes a `tracked_job_log_id` you can use to poll job progress.\n\nRoute name: big-commerce.products.refresh-tracked","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5121\n  },\n  \"message\": \"Product refresh job has been queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Latest Product Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get a summary of the most recently updated BigCommerce product plus counts of total, mapped, and unmapped products for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Stainless Water Bottle 750ml\",\n    \"latest_product_date\": \"2026-05-20T08:13:29.000000Z\",\n    \"total_products\": 320,\n    \"mapped_products\": 295,\n    \"unmapped_products\": 25\n  }\n}"}]},{"name":"Get Raw Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Fetch the raw product payload for a single product directly from the BigCommerce API (live request, not the locally cached copy).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.raw"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"data\": {\n        \"id\": 812,\n        \"name\": \"Stainless Water Bottle 750ml\",\n        \"sku\": \"WB-750-SS\",\n        \"type\": \"physical\",\n        \"price\": 24.95,\n        \"inventory_level\": 132,\n        \"is_visible\": true,\n        \"availability\": \"available\",\n        \"upc\": \"812345678901\"\n      },\n      \"meta\": {}\n    }\n  }\n}"}]},{"name":"Get Product Match Suggestions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Find SKU.io products that likely correspond to a BigCommerce product. Returns an exact SKU match, a barcode/UPC match, and a list of fuzzy name-similarity matches - each with a `match_type` of sku, barcode, or fuzzy. Use the results to pick a product for the map endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.smart-match","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 55,\n      \"sku\": \"WB-750-SS\",\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"barcode\": \"812345678901\",\n      \"price\": \"24.95\",\n      \"type\": \"product\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 61,\n        \"sku\": \"WB-500-SS\",\n        \"name\": \"Stainless Water Bottle 500ml\",\n        \"barcode\": \"812345678902\",\n        \"price\": \"19.95\",\n        \"type\": \"product\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Map Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Map a BigCommerce product to an existing SKU.io product or subscription offering by creating (or updating) its product listing. Provide exactly one of `product_id` or `subscription_offering_id`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAfter mapping, a background job is dispatched to link any unmapped sales order lines that match the new listing.\n\nRoute name: big-commerce.products.map-single","body":{"mode":"raw","raw":"{\n  \"product_id\": 55\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"product_listing_id\": 977,\n    \"product\": {\n      \"id\": 55,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 977\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-04-02T16:40:12.000000Z\",\n    \"mapped_sku\": \"WB-750-SS\",\n    \"json_object\": {\n      \"id\": 812,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"price\": 24.95,\n      \"inventory_level\": 132,\n      \"is_visible\": true,\n      \"availability\": \"available\"\n    },\n    \"image_url\": \"https://cdn11.bigcommerce.com/s-abc123/images/stencil/original/products/812/bottle.jpg\",\n    \"created_at\": \"2026-03-28T11:05:44.000000Z\",\n    \"updated_at\": \"2026-05-20T08:13:29.000000Z\",\n    \"archived_at\": null,\n    \"status\": \"active\",\n    \"slug\": \"/stainless-water-bottle-750ml/\",\n    \"price\": 24.95,\n    \"featured\": false,\n    \"catalog_visibility\": true,\n    \"dimensions_length\": null,\n    \"dimensions_width\": 8,\n    \"dimensions_height\": 26,\n    \"sku\": \"WB-750-SS\",\n    \"big_commerce_id\": 812,\n    \"name\": \"Stainless Water Bottle 750ml\",\n    \"upc\": \"812345678901\",\n    \"type\": \"physical\",\n    \"base_price\": 24.95,\n    \"quantity\": 132,\n    \"weight\": 0.6,\n    \"brand\": \"HydraCo\",\n    \"is_bundled_product\": false\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Remove the mapping between a BigCommerce product and its SKU.io product by deleting the product listing. The BigCommerce product and the SKU.io product both remain.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.unmap-single"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"product_listing_id\": null,\n    \"product\": null,\n    \"subscription_offering\": null,\n    \"mapped_at\": null,\n    \"mapped_sku\": null,\n    \"json_object\": {\n      \"id\": 812,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"price\": 24.95,\n      \"inventory_level\": 132,\n      \"is_visible\": true,\n      \"availability\": \"available\"\n    },\n    \"image_url\": \"https://cdn11.bigcommerce.com/s-abc123/images/stencil/original/products/812/bottle.jpg\",\n    \"created_at\": \"2026-03-28T11:05:44.000000Z\",\n    \"updated_at\": \"2026-05-20T08:13:29.000000Z\",\n    \"archived_at\": null,\n    \"status\": \"active\",\n    \"slug\": \"/stainless-water-bottle-750ml/\",\n    \"price\": 24.95,\n    \"featured\": false,\n    \"catalog_visibility\": true,\n    \"dimensions_length\": null,\n    \"dimensions_width\": 8,\n    \"dimensions_height\": 26,\n    \"sku\": \"WB-750-SS\",\n    \"big_commerce_id\": 812,\n    \"name\": \"Stainless Water Bottle 750ml\",\n    \"upc\": \"812345678901\",\n    \"type\": \"physical\",\n    \"base_price\": 24.95,\n    \"quantity\": 132,\n    \"weight\": 0.6,\n    \"brand\": \"HydraCo\",\n    \"is_bundled_product\": false\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Create SKU.io Product from BigCommerce Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Create a new SKU.io product from an unmapped BigCommerce product and map it in one step. If a SKU.io product with the same SKU already exists, the BigCommerce product is linked to it instead (indicated by `linked_existing` in the response).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.create-sku-product","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"product_listing_id\": 977,\n    \"product\": {\n      \"id\": 55,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 977\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-04-02T16:40:12.000000Z\",\n    \"mapped_sku\": \"WB-750-SS\",\n    \"json_object\": {\n      \"id\": 812,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"price\": 24.95,\n      \"inventory_level\": 132,\n      \"is_visible\": true,\n      \"availability\": \"available\"\n    },\n    \"image_url\": \"https://cdn11.bigcommerce.com/s-abc123/images/stencil/original/products/812/bottle.jpg\",\n    \"created_at\": \"2026-03-28T11:05:44.000000Z\",\n    \"updated_at\": \"2026-05-20T08:13:29.000000Z\",\n    \"archived_at\": null,\n    \"status\": \"active\",\n    \"slug\": \"/stainless-water-bottle-750ml/\",\n    \"price\": 24.95,\n    \"featured\": false,\n    \"catalog_visibility\": true,\n    \"dimensions_length\": null,\n    \"dimensions_width\": 8,\n    \"dimensions_height\": 26,\n    \"sku\": \"WB-750-SS\",\n    \"big_commerce_id\": 812,\n    \"name\": \"Stainless Water Bottle 750ml\",\n    \"upc\": \"812345678901\",\n    \"type\": \"physical\",\n    \"base_price\": 24.95,\n    \"quantity\": 132,\n    \"weight\": 0.6,\n    \"brand\": \"HydraCo\",\n    \"is_bundled_product\": false\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Sync Product from BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/sync","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Re-fetch a single product from the BigCommerce API and update the locally cached copy with the latest data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.sync-single","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/sync","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"product_listing_id\": 977,\n    \"product\": {\n      \"id\": 55,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 977\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-04-02T16:40:12.000000Z\",\n    \"mapped_sku\": \"WB-750-SS\",\n    \"json_object\": {\n      \"id\": 812,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"price\": 24.95,\n      \"inventory_level\": 132,\n      \"is_visible\": true,\n      \"availability\": \"available\"\n    },\n    \"image_url\": \"https://cdn11.bigcommerce.com/s-abc123/images/stencil/original/products/812/bottle.jpg\",\n    \"created_at\": \"2026-03-28T11:05:44.000000Z\",\n    \"updated_at\": \"2026-05-20T08:13:29.000000Z\",\n    \"archived_at\": null,\n    \"status\": \"active\",\n    \"slug\": \"/stainless-water-bottle-750ml/\",\n    \"price\": 24.95,\n    \"featured\": false,\n    \"catalog_visibility\": true,\n    \"dimensions_length\": null,\n    \"dimensions_width\": 8,\n    \"dimensions_height\": 26,\n    \"sku\": \"WB-750-SS\",\n    \"big_commerce_id\": 812,\n    \"name\": \"Stainless Water Bottle 750ml\",\n    \"upc\": \"812345678901\",\n    \"type\": \"physical\",\n    \"base_price\": 24.95,\n    \"quantity\": 132,\n    \"weight\": 0.6,\n    \"brand\": \"HydraCo\",\n    \"is_bundled_product\": false\n  },\n  \"message\": \"Product synced successfully.\"\n}"}]},{"name":"List Orders for Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]},"description":"Get a paginated list of BigCommerce orders that contain a given product, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.orders"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"231","description":"Local BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4512,\n      \"integration_instance_id\": 1,\n      \"sku_sales_order\": {\n        \"id\": 887,\n        \"number\": \"SO-1042\",\n        \"order_status\": \"COMPLETED\",\n        \"fulfillment_status\": \"FULFILLED\",\n        \"payment_status\": \"PAID\"\n      },\n      \"json_object\": {\n        \"id\": 118,\n        \"status\": \"Shipped\",\n        \"status_id\": 2,\n        \"date_created\": \"Thu, 14 May 2026 09:21:33 +0000\",\n        \"currency_code\": \"USD\",\n        \"total_inc_tax\": \"58.30\"\n      },\n      \"big_commerce_id\": \"118\",\n      \"sku_sales_order_id\": 887,\n      \"customer_id\": \"42\",\n      \"external_id\": null,\n      \"currency_code\": \"USD\",\n      \"payment_status\": \"captured\",\n      \"total_tax\": \"4.35\",\n      \"total_inc_tax\": \"58.30\",\n      \"payment_method\": \"Credit Card\",\n      \"status\": \"Shipped\",\n      \"error_log\": null,\n      \"items_total\": 3,\n      \"items_shipped\": 3,\n      \"date_created\": \"2026-05-14T09:21:33.000000Z\",\n      \"date_modified\": \"2026-05-15T10:02:11.000000Z\",\n      \"updated_at\": \"2026-05-15T10:02:12.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Check Deletable Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Check which BigCommerce products can be deleted. Provide `ids` (local BigCommerce product IDs) or set `mode` to `all` to check every product for the integration instance. Each result includes a `deleteable` flag and a `reason` when deletion is blocked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.products.deleteable","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    231,\n    232\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 231,\n      \"deleteable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 232,\n      \"deleteable\": true,\n      \"reason\": false\n    }\n  ],\n  \"status\": \"Success\"\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get the product field mappings for a BigCommerce integration instance - which BigCommerce product fields populate which SKU.io product fields when products are created or updated from listings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response includes the default mappings, any custom overrides, the effective (merged) mappings, and the catalog of available fields on both sides.\n\nRoute name: big-commerce.mappings.show"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My BigCommerce Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"upc\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: upc to barcode\"\n      }\n    ],\n    \"available_bigcommerce_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Stock Keeping Unit\",\n        \"group\": \"Identifiers\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Product name/title\",\n        \"group\": \"Product Info\"\n      },\n      \"upc\": {\n        \"name\": \"upc\",\n        \"label\": \"UPC\",\n        \"type\": \"string\",\n        \"description\": \"Universal Product Code\",\n        \"group\": \"Identifiers\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Name\",\n        \"type\": \"string\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"upc\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: upc to barcode\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"upc\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: upc to barcode\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Replace the custom product field mappings for a BigCommerce integration instance. Each mapping pairs a BigCommerce `listing_field` with a SKU.io `sku_field`, with optional `parsers` applied to transform the value. Custom mappings override the defaults for the same field.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.mappings.update","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"upc\",\n      \"sku_field\": \"barcode\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My BigCommerce Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"upc\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: upc to barcode\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"upc\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: upc to barcode\"\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get a paginated list of fulfilled shipments for sales orders that originated from this BigCommerce store. Each item shows whether it has been submitted to BigCommerce (`sync_status` of submitted or pending).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAllowed sorts: id, fulfilled_at, created_at, submitted_to_sales_channel_at (default -id).\n\nRoute name: big-commerce.fulfillments.index"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3120,\n      \"fulfillment_number\": \"F-3120\",\n      \"fulfillment_type\": \"shipment\",\n      \"status\": \"FULFILLED\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"cost\": \"8.45\",\n      \"fulfilled_at\": \"2026-06-18T14:22:05+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-18T14:22:06+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 887,\n        \"sales_order_number\": \"SO-1042\"\n      },\n      \"bigcommerce_order\": {\n        \"id\": 4512,\n        \"big_commerce_id\": \"118\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 14,\n        \"name\": \"UPS Ground\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/big-commerce/1/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{base_url}}/api/big-commerce/1/fulfillments?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/fulfillments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/fulfillments?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/big-commerce/1/fulfillments?page=2\",\n  \"path\": \"{{base_url}}/api/big-commerce/1/fulfillments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"List Pending Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get a paginated list of fulfilled shipments that have not yet been submitted to BigCommerce. Pickup fulfillments and fulfillments on cancelled orders are excluded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.fulfillments.pending"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3120,\n      \"fulfillment_number\": \"F-3120\",\n      \"fulfillment_type\": \"shipment\",\n      \"status\": \"FULFILLED\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"cost\": \"8.45\",\n      \"fulfilled_at\": \"2026-06-18T14:22:05+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-18T14:22:06+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 887,\n        \"sales_order_number\": \"SO-1042\"\n      },\n      \"bigcommerce_order\": {\n        \"id\": 4512,\n        \"big_commerce_id\": \"118\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 14,\n        \"name\": \"UPS Ground\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/big-commerce/1/fulfillments/pending?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/big-commerce/1/fulfillments/pending?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/fulfillments/pending?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/fulfillments/pending?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/big-commerce/1/fulfillments/pending\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 3,\n  \"total\": 3\n}"}]},{"name":"Get Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get the count of fulfillments waiting to be submitted to BigCommerce, plus the automatic sync schedule. Pending fulfillments are submitted automatically every 10 minutes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.fulfillments.stats"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_sync_count\": 3,\n    \"sync_schedule\": {\n      \"interval\": 10,\n      \"unit\": \"minutes\",\n      \"description\": \"Fulfillments are automatically synced every 10 minutes\"\n    }\n  }\n}"}]},{"name":"Submit Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"salesOrderFulfillment","value":"3120","description":"Sales order fulfillment ID"}]},"description":"Submit a single fulfillment to BigCommerce, creating the shipment on the BigCommerce order with its tracking details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.fulfillments.submit-single","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"salesOrderFulfillment","value":"3120","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"The fulfillment submitted successfully\"\n}"}]},{"name":"Bulk Submit Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Submit multiple fulfillments to BigCommerce by their IDs. The response reports how many were submitted and how many failed, with per-fulfillment error details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.fulfillments.submit-bulk","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3120,\n    3121\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 2,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"2 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"Submit All Pending Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Submit every pending fulfillment for the integration instance to BigCommerce in one call. The response reports how many were submitted and how many failed, with per-fulfillment error details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.fulfillments.submit-all","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 3,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"3 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"List Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get a paginated side-by-side comparison of SKU.io quantities vs BigCommerce quantities, one row per product listing per BigCommerce inventory location. Each row includes the variance and a status of synced, variance, or needs_recalc.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAllowed sorts: id, sku_quantity, sales_channel_quantity, created_at, updated_at (default -id).\n\nRoute name: big-commerce.inventory.index"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9021,\n      \"product_listing_id\": 977,\n      \"document_id\": 231,\n      \"listing_sku\": \"WB-750-SS\",\n      \"title\": \"Stainless Water Bottle 750ml\",\n      \"product\": {\n        \"id\": 55,\n        \"sku\": \"WB-750-SS\",\n        \"name\": \"Stainless Water Bottle 750ml\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"1\",\n      \"location_name\": \"Main Location\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 132,\n      \"sales_channel_quantity\": 128,\n      \"variance\": 4,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-20T04:00:11+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-20T04:05:32+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-19T04:05:30+00:00\",\n      \"created_at\": \"2026-05-01T00:00:00+00:00\",\n      \"updated_at\": \"2026-06-20T04:05:32+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/big-commerce/1/inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{base_url}}/api/big-commerce/1/inventory?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/inventory?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/big-commerce/1/inventory?page=2\",\n  \"path\": \"{{base_url}}/api/big-commerce/1/inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"Get Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get aggregate inventory sync statistics for the integration instance: total SKU/location rows, how many are in sync, how many have a variance, how many need recalculation, and the timestamps of the last fetch from BigCommerce and last sync to BigCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.inventory.summary"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 480,\n    \"in_sync\": 440,\n    \"with_variance\": 32,\n    \"needs_recalculation\": 8,\n    \"last_fetch_at\": \"2026-06-20T04:05:32.000000Z\",\n    \"last_sync_at\": \"2026-06-19T04:05:30.000000Z\"\n  }\n}"}]},{"name":"List Inventory Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get the BigCommerce inventory locations known for the integration instance, with each location's ID, name, and active state. Location IDs can be used with the inventory comparison filter.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.inventory.locations"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"1\",\n      \"name\": \"Main Location\",\n      \"is_active\": true\n    },\n    {\n      \"id\": \"2\",\n      \"name\": \"West Coast Warehouse\",\n      \"is_active\": false\n    }\n  ]\n}"}]},{"name":"Recache Inventory Quantities","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Start a background job that recalculates SKU.io inventory quantities for every product listing mapped to this BigCommerce store. Run this when the comparison shows rows needing recalculation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the recache progress endpoint to poll for completion.\n\nRoute name: big-commerce.inventory.recache","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5120\n  }\n}"}]},{"name":"Get Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of an inventory recache job using the `tracked_job_log_id` returned when the job was queued. The response includes the job status, item counts, and completion percentage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.inventory.recache-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5120,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"BigCommerce Inventory Recache\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Sync Inventory to BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Start a background job that pushes SKU.io inventory quantities to BigCommerce for every mapped product listing, updating quantities at each mapped location.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the sync progress endpoint to poll for completion.\n\nRoute name: big-commerce.inventory.sync","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5122\n  }\n}"}]},{"name":"Get Inventory Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5122","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of an inventory sync job using the `tracked_job_log_id` returned when the job was queued.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.inventory.sync-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5122","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5122,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"BigCommerce Inventory Sync\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Fetch Live Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Start a background job that fetches current inventory quantities from BigCommerce for every mapped product listing and refreshes the local comparison cache.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the fetch progress endpoint to poll for completion.\n\nRoute name: big-commerce.inventory.fetch-live","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetch live inventory job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5123\n  }\n}"}]},{"name":"Get Live Inventory Fetch Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5123","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of a live inventory fetch job using the `tracked_job_log_id` returned when the job was queued.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.inventory.fetch-live-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5123","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5123,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"BigCommerce Live Inventory Fetch\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Get Integration Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Get the paginated activity history for a BigCommerce integration instance - covering the instance itself plus its orders, products, locations, and transactions - with the user who caused each change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.activity-log"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"BigCommerceOrder\",\n      \"subject_id\": 4512,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"Shipped\"\n        },\n        \"old\": {\n          \"status\": \"Awaiting Fulfillment\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:25:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/big-commerce/1/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{base_url}}/api/big-commerce/1/activity-log?page=3\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/big-commerce/1/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/big-commerce/1/activity-log?page=2\",\n  \"path\": \"{{base_url}}/api/big-commerce/1/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 42\n}"}]},{"name":"List Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/transactions?filter[search]=&filter[event]=&filter[status]=&filter[date_from]=&filter[date_to]=&page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","transactions"],"query":[{"key":"filter[search]","value":"","description":"Optional. Search by order number or gateway.","disabled":true},{"key":"filter[event]","value":"","description":"Optional. Filter by transaction event type (e.g. purchase, capture, refund).","disabled":true},{"key":"filter[status]","value":"","description":"Optional. Filter by transaction status (e.g. ok, error).","disabled":true},{"key":"filter[date_from]","value":"","description":"Optional. Filter transactions from this date (YYYY-MM-DD).","disabled":true},{"key":"filter[date_to]","value":"","description":"Optional. Filter transactions up to this date (YYYY-MM-DD).","disabled":true},{"key":"page","value":"1","description":"Page number for pagination.","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get paginated list of BigCommerce order transactions for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filters for search, event type, status, and date range.\n\nRoute name: big-commerce.transactions.index"}},{"name":"Refresh Transactions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/transactions/refresh","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","transactions","refresh"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Dispatch a background job to re-fetch transactions from BigCommerce for the given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponds immediately with a success message. The job runs asynchronously on the salesOrderProcessing queue.\n\nRoute name: big-commerce.transactions.refresh"}},{"name":"Get Webhook Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhooks","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhooks"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get webhook configurations for all available BigCommerce topics for the given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the registration status (enabled/disabled) for each webhook scope.\n\nRoute name: big-commerce.webhooks.index"}},{"name":"Enable Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhooks/enable","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhooks","enable"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Register a webhook with BigCommerce for the given scope on the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- scope (string): The BigCommerce webhook scope to enable, e.g. store/order/created\n\nRoute name: big-commerce.webhooks.enable","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/order/created\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Disable Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhooks/disable","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhooks","disable"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete a registered webhook from BigCommerce for the given scope on the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- scope (string): The BigCommerce webhook scope to disable, e.g. store/order/created\n\nRoute name: big-commerce.webhooks.disable","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/order/created\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Create All Webhooks","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhooks/create-all","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhooks","create-all"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Create all supported webhooks at once for the integration instance. Skips scopes that are already registered.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.webhooks.create-all"}},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhook-events?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhook-events"],"query":[{"key":"page","value":"1","description":"Page number for pagination.","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a paginated list of webhook events for a specific BigCommerce integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: big-commerce.webhook-events.index"}},{"name":"Get Webhook Processing Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhook-events","stats"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get processing statistics for webhook events on the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns counts by status (pending, processing, completed, failed).\n\nRoute name: big-commerce.webhook-events.stats"}},{"name":"Process Pending Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhook-events/process","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhook-events","process"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Trigger manual processing of pending webhook events for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptional fields:\n- scope (string): Filter to a specific webhook scope\n- limit (integer): Maximum number of events to process (0 = no limit)\n\nRoute name: big-commerce.webhook-events.process","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/order/created\",\n  \"limit\": 50\n}","options":{"raw":{"language":"json"}}}}},{"name":"Retry Failed Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhook-events/retry-failed","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhook-events","retry-failed"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Retry all failed webhook events for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptional fields:\n- limit (integer): Maximum number of events to retry (0 = no limit)\n\nRoute name: big-commerce.webhook-events.retry-failed","body":{"mode":"raw","raw":"{\n  \"limit\": 25\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete All Webhook Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{id}/webhook-events/delete-all","host":["{{baseUrl}}"],"path":["api","big-commerce",":id","webhook-events","delete-all"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Delete all webhook events for the given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is a destructive action — all event records for the instance will be removed.\n\nRoute name: big-commerce.webhook-events.delete-all"}},{"name":"Order Created Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/order-created","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","order-created"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when a new order is created.\n\nRequires BigCommerce webhook signature verification (VerifyBigCommerceWebhook middleware).\nDispatches a background job for async processing.\n\nRoute name: bigcommerce.order_created","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/order/created\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"order\",\n    \"id\": 100\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Order Updated Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/order-updated","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","order-updated"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when an order is updated.\n\nRoute name: bigcommerce.order_updated","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/order/updated\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"order\",\n    \"id\": 100,\n    \"status\": {\n      \"previous_status_id\": 7,\n      \"new_status_id\": 2\n    }\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Product Created Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/product-created","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","product-created"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when a product is created.\n\nRoute name: bigcommerce.product_created","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/product/created\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"product\",\n    \"id\": 500\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Product Updated Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/product-updated","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","product-updated"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when a product is updated.\n\nRoute name: bigcommerce.product_updated","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/product/updated\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"product\",\n    \"id\": 500\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Shipment Created Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/shipment-created","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","shipment-created"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when a shipment is created.\n\nRoute name: bigcommerce.shipment_created","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/shipment/created\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"shipment\",\n    \"id\": 200,\n    \"orderId\": 100\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Shipment Updated Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/bc-webhook/{id}/shipment-updated","host":["{{baseUrl}}"],"path":["api","webhooks","bc-webhook",":id","shipment-updated"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by BigCommerce when a shipment is updated.\n\nRoute name: bigcommerce.shipment_updated","body":{"mode":"raw","raw":"{\n  \"scope\": \"store/shipment/updated\",\n  \"store_id\": \"12345\",\n  \"data\": {\n    \"type\": \"shipment\",\n    \"id\": 200,\n    \"orderId\": 100\n  },\n  \"hash\": \"abcdef1234567890\",\n  \"created_at\": 1617000000,\n  \"producer\": \"stores/abcde\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce","host":["{{baseUrl}}"],"path":["api","big-commerce"]},"description":"List all BigCommerce integration instances (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- search: string — full-text search\n- sort: string — column name (prefix with - for descending, e.g. -created_at)\n- limit: integer — records per page (default 10)\n- page: integer — page number\n- archived: 0|1 — include archived instances (default 0)\n- included[]: JSON-encoded array of additional columns to include\n- excluded[]: JSON-encoded array of columns to exclude\n- table_specifications: 1 — return only table column specifications"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce","host":["{{baseUrl}}"],"path":["api","big-commerce"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\"data\": [{\"id\": 1, \"integration_id\": 5, \"name\": \"My BigCommerce Store\", \"connection_status\": \"connected\", \"is_automatic_sync_enabled\": true, \"integration_settings\": {\"store_hash\": \"abc123xyz\", \"start_date\": \"2024-01-01\", \"store_id\": 1, \"auto_link_products\": true, \"auto_create_products\": false}, \"created_at\": \"2024-01-15T00:00:00.000000Z\", \"updated_at\": \"2024-06-01T00:00:00.000000Z\", \"integration_name\": \"BigCommerce\", \"store\": {\"id\": 1, \"name\": \"Main Store\"}}, \"total\": 1, \"per_page\": 10, \"current_page\": 1, \"last_page\": 1]}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce","host":["{{baseUrl}}"],"path":["api","big-commerce"]},"description":"Create a new BigCommerce integration instance. After creation, automatically dispatches jobs to refresh products and orders from BigCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, unique): Human-readable name for this integration instance\n- integration_id (required, integer): ID of the BigCommerce integration type\n- connection_settings.access_token (required, string): BigCommerce API access token\n- integration_settings.store_hash (required, string, not a URL): BigCommerce store hash identifier\n- integration_settings.start_date (required, string): Date to start syncing orders/products from (YYYY-MM-DD)\n- integration_settings.store_id (required, integer): Internal store ID to associate with\n- integration_settings.auto_link_products (required, boolean): Automatically link BigCommerce products to SKU products\n- integration_settings.auto_create_products (required, boolean): Automatically create SKU products from BigCommerce products\n- integration_settings.sales_nominal_code_id (nullable, integer): Nominal code ID for sales accounting\n- integration_settings.cogs_nominal_code_id (nullable, integer): Nominal code ID for cost of goods sold\n- integration_settings.shipping_revenue_nominal_code_id (nullable, integer): Nominal code ID for shipping revenue\n- integration_settings.shipping_refund_nominal_code_id (nullable, integer): Nominal code ID for shipping refunds\n- integration_settings.sales_returns_allowances_nominal_code_id (nullable, integer): Nominal code ID for returns\n- integration_settings.sync_sales_order_invoices_to_accounting (boolean, default true): Sync invoices to accounting\n- integration_settings.sync_sales_credit_to_accounting (boolean, default true): Sync credits to accounting\n- integration_settings.proforma_marketplace_cost_percentage (nullable, float): Marketplace cost percentage\n- integration_settings.proforma_payment_cost_percentage (nullable, float): Payment cost percentage\n- integration_settings.batch_period_sales_order_fulfillments (nullable, string): Batch period override for fulfillments\n- integration_settings.batch_period_customer_returns (nullable, string): Batch period override for customer returns\n- is_automatic_sync_enabled (boolean, default false): Enable automatic synchronization","body":{"mode":"raw","raw":"{\n  \"name\": \"My BigCommerce Store\",\n  \"integration_id\": 5,\n  \"connection_settings\": {\n    \"access_token\": \"abc123xyz_access_token\"\n  },\n  \"integration_settings\": {\n    \"store_hash\": \"abc123xyz\",\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 1,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce","host":["{{baseUrl}}"],"path":["api","big-commerce"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_id\": 5,\n    \"name\": \"My BigCommerce Store\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-01-15T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T00:00:00.000000Z\"\n  },\n  \"message\": null\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Get a single BigCommerce integration instance with salesChannel and integration relationships loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_id\": 5,\n    \"name\": \"My BigCommerce Store\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true,\n    \"connection_settings\": {\n      \"access_token\": \"***masked***\"\n    },\n    \"integration_settings\": {\n      \"store_hash\": \"abc123xyz\",\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 1,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true\n    },\n    \"created_at\": \"2024-01-15T00:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T00:00:00.000000Z\",\n    \"integration_name\": \"BigCommerce\",\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    }\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Update a BigCommerce integration instance. Supports both PUT (full update) and PATCH (partial update — merges connection_settings and integration_settings with existing values).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields are optional for PATCH. For PUT, provide all settings fields.\n\nSide effects:\n- If start_date changes, updates the sales channel date\n- If pricing.masterOfPrice changes, dispatches a job to re-cache product listing prices\n- If inventory settings change, invalidates the entire inventory cache\n- If accounting sync settings change, updates related accounting transactions","body":{"mode":"raw","raw":"{\n  \"name\": \"My BigCommerce Store Updated\",\n  \"integration_settings\": {\n    \"store_hash\": \"abc123xyz\",\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 1,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My BigCommerce Store Updated\",\n    \"is_automatic_sync_enabled\": true,\n    \"integration_settings\": {\n      \"store_hash\": \"abc123xyz\",\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 1,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true\n    },\n    \"updated_at\": \"2024-06-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Partial Update Integration Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Partially update a BigCommerce integration instance. Settings are deep-merged with existing values — only send the fields you want to change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My BigCommerce Store\",\n    \"is_automatic_sync_enabled\": true,\n    \"updated_at\": \"2024-06-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Delete a BigCommerce integration instance. Dispatches a background job to clean up associated data asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Store Mapped Warehouse Locations","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]},"description":"Map BigCommerce locations to internal warehouses. Updates the warehouse_id for each BigCommerce location.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- warehouse_mappings (required, array): Array of location-to-warehouse mappings\n- warehouse_mappings.*.location_id (required, integer): BigCommerce location ID (must exist in big_commerce_locations)\n- warehouse_mappings.*.warehouse_id (nullable, integer): Internal warehouse ID (must exist in warehouses table, or null to unmap)","body":{"mode":"raw","raw":"{\n  \"warehouse_mappings\": [\n    {\n      \"location_id\": 101,\n      \"warehouse_id\": 2\n    },\n    {\n      \"location_id\": 102,\n      \"warehouse_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Warehouse mappings updated successfully.\"\n}"}]},{"name":"Download Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integration_instance}/download-locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integration_instance","download-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]},"description":"Sync BigCommerce locations synchronously (runs a background job inline) and return the current list of BigCommerce locations along with configured inventory locations from the integration settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integration_instance}/download-locations","host":["{{baseUrl}}"],"path":["api","big-commerce",":integration_instance","download-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"bigCommerceLocations\": [\n      {\n        \"id\": 1,\n        \"location_id\": 101,\n        \"integration_instance_id\": 1,\n        \"name\": \"Main Warehouse\",\n        \"code\": \"MAIN\",\n        \"type\": \"PHYSICAL\",\n        \"warehouse_id\": 2,\n        \"created_at\": \"2024-01-15T00:00:00.000000Z\"\n      }\n    ],\n    \"inventoryLocations\": [\n      {\n        \"location_id\": 101,\n        \"warehouse_id\": 2\n      }\n    ]\n  }\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Get the BigCommerce OAuth authorization URL for connecting the integration. Redirect the user to this URL to begin the OAuth flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://login.bigcommerce.com/oauth2/authorize?client_id=abc123&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fbig-commerce%2Fcallback&response_type=code&scope=store_v2_products+store_v2_orders\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products?search=&sort=name&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products"],"query":[{"key":"search","value":"","description":"Search term for product name or SKU","disabled":true},{"key":"sort","value":"name","description":"Column to sort by (prefix with - for descending, e.g. -name)","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived products: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of additional columns: [\"product\", \"subscription_offering\", \"mapped_at\", \"mapped_sku\", \"json_object\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"List BigCommerce products for a specific integration instance (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe response uses the list view format with table specifications. Available optional columns (via included[]):\n- product: Linked SKU product details (id, name, sku, listing_id)\n- subscription_offering: Linked subscription offering (id, name, sku)\n- mapped_at: Date the product was mapped to a SKU product\n- mapped_sku: SKU of the mapped product\n- json_object: Full raw BigCommerce product JSON data\n- integration_instance_id: Integration instance ID\n- product_listing_id: Product listing ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products?search=&sort=name&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products"],"query":[{"key":"search","value":"","description":"Search term for product name or SKU","disabled":true},{"key":"sort","value":"name","description":"Column to sort by (prefix with - for descending, e.g. -name)","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived products: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of additional columns: [\"product\", \"subscription_offering\", \"mapped_at\", \"mapped_sku\", \"json_object\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"big_commerce_id\": 45678,\n      \"sku\": \"BLUE-WIDGET-M\",\n      \"name\": \"Blue Widget Medium\",\n      \"slug\": \"blue-widget-medium\",\n      \"type\": \"physical\",\n      \"status\": \"active\",\n      \"featured\": false,\n      \"price\": 29.99,\n      \"weight\": 0.5,\n      \"integration_instance_id\": 1,\n      \"product_listing_id\": 55,\n      \"product\": {\n        \"id\": 100,\n        \"name\": \"Blue Widget\",\n        \"sku\": \"BW-001\",\n        \"listing_id\": 55\n      },\n      \"mapped_sku\": \"BW-001\",\n      \"mapped_at\": \"2024-03-01T00:00:00.000000Z\",\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-20T00:00:00.000000Z\",\n      \"updated_at\": \"2024-05-10T00:00:00.000000Z\"\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"10","description":"BigCommerce product ID"}]},"description":"Get a single BigCommerce product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"},{"key":"product","value":"10","description":"BigCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"big_commerce_id\": 45678,\n    \"sku\": \"BLUE-WIDGET-M\",\n    \"name\": \"Blue Widget Medium\",\n    \"slug\": \"blue-widget-medium\",\n    \"type\": \"physical\",\n    \"status\": \"active\",\n    \"featured\": false,\n    \"catalog_visibility\": \"visible\",\n    \"price\": 29.99,\n    \"weight\": 0.5,\n    \"dimensions_length\": 10,\n    \"dimensions_width\": 5,\n    \"dimensions_height\": 3,\n    \"integration_instance_id\": 1,\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-20T00:00:00.000000Z\",\n    \"updated_at\": \"2024-05-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Create SKU Products from BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Create SKU.io products from selected BigCommerce products. Products are created asynchronously via queue.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (array, optional): Array of BigCommerce product IDs to create SKU products from. Required if create_all_products is false.\n- create_all_products (boolean, default false): Create SKU products for all BigCommerce products in this integration.\n- mappings (optional, array): Product mapping overrides to persist.\n- filters (optional, object): list view filters to use instead of explicit ids.\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11,\n    12\n  ],\n  \"create_all_products\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be created shortly.\"\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Queue a job to refresh all products from BigCommerce for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be refreshed shortly.\"\n}"}]},{"name":"Map Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Map BigCommerce products to SKU.io products. Creates product listings linking BigCommerce listings to internal products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_listing_id\": \"BLUE-WIDGET-M\",\n      \"product_id\": 100\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\",\n  \"message\": null\n}"}]},{"name":"Export Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter exported products by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Export BigCommerce products as a CSV or Excel file. Supports the same list view filter parameters as the list endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download (text/csv or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter exported products by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,sku,name,status,price\n10,BLUE-WIDGET-M,Blue Widget Medium,active,29.99"}]},{"name":"Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Archive BigCommerce products (soft-delete). Products are marked as archived and hidden from default listings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of BigCommerce product IDs to archive. Must belong to this integration instance.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11,\n    12\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Unarchive previously archived BigCommerce products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of BigCommerce product IDs to unarchive. Must belong to this integration instance.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11,\n    12\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Check which of the given BigCommerce products can be archived. Returns a collection indicating whether each product is archiveable.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of BigCommerce product IDs to check.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11,\n    12\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"archiveable\": true\n    },\n    {\n      \"id\": 11,\n      \"archiveable\": false,\n      \"reason\": \"Product has pending orders\"\n    }\n  ]\n}"}]},{"name":"Delete Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Permanently delete BigCommerce products from SKU.io (does not delete from BigCommerce). Use archiveable endpoint first to check if deletion is safe.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of BigCommerce product IDs to delete. Must belong to this integration instance.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products deleted successfully.\"\n}"}]},{"name":"Import Product Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Import product mapping data from a file (CSV/Excel). Queues a background job to process the mappings asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"file\": \"base64_encoded_csv_content\",\n  \"mapping_type\": \"listings\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, mappings will be imported shortly.\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders?search=&sort=-date_created&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders"],"query":[{"key":"search","value":"","description":"Search term for order ID, status, etc.","disabled":true},{"key":"sort","value":"-date_created","description":"Column to sort by (prefix with - for descending)","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived orders: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of columns: [\"sku_sales_order\", \"json_object\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"List BigCommerce orders for a specific integration instance (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAvailable optional columns (via included[]):\n- sku_sales_order: Linked SKU sales order (id, number)\n- json_object: Full raw BigCommerce order JSON data\n- integration_instance_id: Integration instance ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders?search=&sort=-date_created&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders"],"query":[{"key":"search","value":"","description":"Search term for order ID, status, etc.","disabled":true},{"key":"sort","value":"-date_created","description":"Column to sort by (prefix with - for descending)","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived orders: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of columns: [\"sku_sales_order\", \"json_object\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 50,\n      \"big_commerce_id\": \"BC-10001\",\n      \"status\": \"shipped\",\n      \"currency_code\": \"USD\",\n      \"subtotal_ex_tax\": \"45.00\",\n      \"subtotal_inc_tax\": \"45.00\",\n      \"total_ex_tax\": \"52.00\",\n      \"total_inc_tax\": \"52.00\",\n      \"total_tax\": \"0.00\",\n      \"base_shipping_cost\": \"7.00\",\n      \"items_total\": 2,\n      \"items_shipped\": 2,\n      \"payment_method\": \"Credit Card\",\n      \"payment_status\": \"captured\",\n      \"date_created\": \"2024-05-01T00:00:00.000000Z\",\n      \"integration_instance_id\": 1,\n      \"sku_sales_order\": {\n        \"id\": 500,\n        \"number\": \"SO-001234\"\n      },\n      \"archived_at\": null,\n      \"created_at\": \"2024-05-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-05-03T00:00:00.000000Z\"\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Create SKU Orders from BigCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Create SKU.io sales orders from selected BigCommerce orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (array, optional): Array of BigCommerce order IDs to create SKU orders from.\n- create_all_orders (boolean, default false): Create SKU orders for all BigCommerce orders.\n- filters (optional, object): list view filters to use instead of explicit ids.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    50,\n    51,\n    52\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Sku.io sales orders successfully created\"\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Queue a job to refresh all orders from BigCommerce for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, orders will be refreshed shortly.\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Refresh a single BigCommerce order by its unique identifier (BigCommerce order ID). Fetches the latest data from BigCommerce API and returns the updated order resource.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- uniqueId (required, string): The BigCommerce order unique ID (e.g., 'BC-10001')","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"BC-10001\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 50,\n    \"big_commerce_id\": \"BC-10001\",\n    \"status\": \"shipped\",\n    \"currency_code\": \"USD\",\n    \"total_inc_tax\": \"52.00\",\n    \"integration_instance_id\": 1,\n    \"updated_at\": \"2024-05-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Export Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Export BigCommerce orders as a CSV or Excel file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/orders/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","orders","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,big_commerce_id,status,total_inc_tax,currency_code\n50,BC-10001,shipped,52.00,USD"}]},{"name":"Fulfill Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]},"description":"Submit a fulfillment to BigCommerce for a given SKU.io sales order fulfillment. Sends shipment/tracking information back to BigCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_order_fulfillment_id (required, integer): ID of the SKU.io sales order fulfillment to push to BigCommerce.","body":{"mode":"raw","raw":"{\n  \"sales_order_fulfillment_id\": 123\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/big-commerce/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","big-commerce",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"BigCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]}]},{"name":"Stores","item":[{"name":"Get Store","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/stores/{store}","host":["{{baseUrl}}"],"path":["api","v2","stores",":store"],"variable":[{"key":"store","value":"","description":"The store ID."}]},"description":"Returns a single store (the Store detail page's header/overview), including its address fields and associated sales channels. `is_default` indicates whether this store is the tenant's default outbound-email sender. Archived stores are resolvable by this endpoint.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/stores/{store}","host":["{{baseUrl}}"],"path":["api","v2","stores",":store"],"variable":[{"key":"store","value":"","description":"The store ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"is_default\": false,\n    \"name\": \"Main Store\",\n    \"logo_url\": \"https://cdn.example.com/logos/main-store.png\",\n    \"custom_jrxml_file\": null,\n    \"custom_message\": \"Thank you for your order!\",\n    \"company\": \"Acme Corporation\",\n    \"company_name\": \"Acme Corporation\",\n    \"email\": \"orders@acme.com\",\n    \"po_email\": \"purchasing@acme.com\",\n    \"phone\": \"+1-555-123-4567\",\n    \"fax\": null,\n    \"address1\": \"123 Main Street\",\n    \"address2\": \"Suite 400\",\n    \"address3\": null,\n    \"city\": \"New York\",\n    \"province\": \"New York\",\n    \"province_code\": \"NY\",\n    \"zip\": \"10001\",\n    \"country\": \"United States\",\n    \"country_code\": \"US\",\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"sales_channels\": [\n      {\n        \"id\": 1,\n        \"name\": \"Amazon US\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shopify\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Store Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/stores/{store}/stats","host":["{{baseUrl}}"],"path":["api","v2","stores",":store","stats"],"variable":[{"key":"store","value":"","description":"The store ID."}]},"description":"Dashboard KPIs for the Store detail page: connected sales-channel count, assigned-customer count, 90-day order count and revenue, the store's outbound-sending identity (email/PO email, sender domain and its verification status), and the store's linked sales channels, email templates (each with a friendly `context_label`, e.g. \"Bulk Sales Order\"), and PDF templates.\n\n`sending.domain_verification_status` is one of `pending`, `verifying`, `verified`, `failed` (null when the store has no email). `sending.is_default_sender` is true when this store is the tenant default sender.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/stores/{store}/stats","host":["{{baseUrl}}"],"path":["api","v2","stores",":store","stats"],"variable":[{"key":"store","value":"","description":"The store ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sales_channels_count\": 3,\n    \"customers_count\": 128,\n    \"orders\": {\n      \"count_90d\": 342,\n      \"revenue_90d\": 45230.75\n    },\n    \"sending\": {\n      \"email\": \"orders@acme.com\",\n      \"po_email\": \"purchasing@acme.com\",\n      \"domain\": \"acme.com\",\n      \"domain_verification_status\": \"verified\",\n      \"domain_verified\": true,\n      \"domain_usable\": true,\n      \"is_default_sender\": true\n    },\n    \"sales_channels\": [\n      {\n        \"id\": 1,\n        \"name\": \"Amazon US\",\n        \"integration_instance_id\": 10,\n        \"integration_name\": \"Amazon\",\n        \"status\": \"synced\",\n        \"status_label\": \"Synced\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shopify\",\n        \"integration_instance_id\": 11,\n        \"integration_name\": \"Shopify\",\n        \"status\": \"pending\",\n        \"status_label\": \"Pending\"\n      }\n    ],\n    \"email_templates\": [\n      {\n        \"id\": 5,\n        \"name\": \"Order Confirmation\",\n        \"type\": \"order\",\n        \"context\": \"sales_order\",\n        \"context_label\": \"Sales Order\",\n        \"event\": \"order_placed\",\n        \"enabled\": true,\n        \"is_system_template\": false\n      }\n    ],\n    \"pdf_templates\": [\n      {\n        \"id\": 8,\n        \"name\": \"Acme Invoice\",\n        \"type\": \"invoice\",\n        \"description\": \"Branded invoice layout for Acme storefront\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Store Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/stores/{store}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","stores",":store","activity-log"],"variable":[{"key":"store","value":"","description":"The store ID."}]},"description":"Paginated, filterable audit log of the store's own events (create, edit, archive, restore). Each entry records the event, the changed attributes, and the user who made the change.\n\nSupports `filter[event]`, `filter[source]`, `filter[batch_uuid]`, and `filter[search]` (searches causer name, event, subject type, and change properties). Paginated with `page` and `per_page` (default 15).\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/stores/{store}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","stores",":store","activity-log"],"variable":[{"key":"store","value":"","description":"The store ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9012,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Store\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"email\": \"orders@acme.com\"\n        },\n        \"old\": {\n          \"email\": \"hello@acme.com\"\n        }\n      },\n      \"causer_name\": \"Jane Merchant\",\n      \"created_at\": \"2026-07-18T14:05:00.000000Z\"\n    },\n    {\n      \"id\": 9008,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"Store\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"name\": \"Main Store\"\n        }\n      },\n      \"causer_name\": \"Jane Merchant\",\n      \"created_at\": \"2026-07-01T09:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/v2/stores/1/activity-log?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/v2/stores/1/activity-log?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/v2/stores/1/activity-log\"\n}"}]},{"name":"Create Store","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores","host":["{{baseUrl}}"],"path":["api","stores"]},"description":"Creates a new store. Also creates an associated address record.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, max:255, unique)\n- email (required, valid email, max:255)\n- po_email (optional, comma-separated email addresses, max:255)\n- company_name (optional, string, max:255)\n- logo_url (optional)\n- download_logo (optional, boolean — download logo from logo_url)\n- custom_jrxml_file (optional — custom packing slip template)\n- custom_message (optional — message printed on packing slips)\n- address1 (optional, string, max:255)\n- address2 (optional, string, max:255)\n- address3 (optional, string, max:255)\n- city (optional, string, max:255)\n- province (optional, string, max:255)\n- province_code (optional, string, max:255)\n- zip (optional, string, max:255)\n- country (optional, string, max:255)\n- country_code (optional, string, max:2)\n- phone (optional, string, max:255)\n- fax (optional, string, max:255)\n\n**Requires permission:** `stores.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"West Coast Store\",\n  \"email\": \"west@acme.com\",\n  \"po_email\": \"west-purchasing@acme.com\",\n  \"company_name\": \"Acme West LLC\",\n  \"logo_url\": null,\n  \"download_logo\": false,\n  \"custom_jrxml_file\": null,\n  \"custom_message\": \"Thank you for shopping with us!\",\n  \"address1\": \"456 Pacific Ave\",\n  \"address2\": null,\n  \"address3\": null,\n  \"city\": \"Los Angeles\",\n  \"province\": \"California\",\n  \"province_code\": \"CA\",\n  \"zip\": \"90001\",\n  \"country\": \"United States\",\n  \"country_code\": \"US\",\n  \"phone\": \"+1-310-555-0100\",\n  \"fax\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stores","host":["{{baseUrl}}"],"path":["api","stores"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"is_default\": false,\n    \"name\": \"West Coast Store\",\n    \"logo_url\": null,\n    \"company_name\": \"Acme West LLC\",\n    \"email\": \"west@acme.com\",\n    \"po_email\": \"west-purchasing@acme.com\",\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T12:00:00.000000Z\"\n  },\n  \"message\": \"store created successfully\"\n}"}]},{"name":"Bulk Delete Stores","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/stores","host":["{{baseUrl}}"],"path":["api","stores"]},"description":"Bulk deletes multiple stores by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/stores","host":["{{baseUrl}}"],"path":["api","stores"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 stores deleted successfully\"\n}"}]},{"name":"Update Store","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/{id}","host":["{{baseUrl}}"],"path":["api","stores",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing store and its address.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields from Create are accepted. For PUT requests, name and email use 'sometimes|required' validation.","body":{"mode":"raw","raw":"{\n  \"name\": \"West Coast Store Updated\",\n  \"email\": \"west-updated@acme.com\",\n  \"phone\": \"+1-310-555-9999\",\n  \"city\": \"San Francisco\",\n  \"province\": \"California\",\n  \"province_code\": \"CA\",\n  \"zip\": \"94105\",\n  \"country\": \"United States\",\n  \"country_code\": \"US\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/{id}","host":["{{baseUrl}}"],"path":["api","stores",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"is_default\": false,\n    \"name\": \"West Coast Store Updated\",\n    \"email\": \"west-updated@acme.com\",\n    \"archived_at\": null,\n    \"updated_at\": \"2024-03-01T14:00:00.000000Z\"\n  },\n  \"message\": \"store West Coast Store Updated updated successfully\"\n}"}]},{"name":"Delete Store","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/stores/{id}","host":["{{baseUrl}}"],"path":["api","stores",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a store. Returns an error if the store is linked to other records.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/stores/{id}","host":["{{baseUrl}}"],"path":["api","stores",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"store West Coast Store Updated deleted successfully\"\n}"}]},{"name":"Archive Store","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/stores/{id}/archive","host":["{{baseUrl}}"],"path":["api","stores",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a store. Returns a warning if already archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/{id}/archive","host":["{{baseUrl}}"],"path":["api","stores",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Main Store\",\n    \"archived_at\": \"2024-03-01T15:00:00.000000Z\"\n  },\n  \"message\": \"store Main Store archived successfully\"\n}"}]},{"name":"Unarchive Store","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/stores/{id}/unarchive","host":["{{baseUrl}}"],"path":["api","stores",":id","unarchive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a store. Returns a warning if not currently archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/{id}/unarchive","host":["{{baseUrl}}"],"path":["api","stores",":id","unarchive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Main Store\",\n    \"archived_at\": null\n  },\n  \"message\": \"store Main Store unarchived successfully\"\n}"}]},{"name":"Set Default Store","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/stores/{id}/set-default","host":["{{baseUrl}}"],"path":["api","stores",":id","set-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Set this store as the tenant default. It becomes the fallback From/sender for outbound email whose context has no store of its own (e.g. an account-level customer statement); a store carried by the order or customer still takes precedence. Returns the updated store.\n\nAuthentication: Requires Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/{id}/set-default","host":["{{baseUrl}}"],"path":["api","stores",":id","set-default"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Main Store\",\n    \"archived_at\": \"2024-03-01T15:00:00.000000Z\"\n  },\n  \"message\": \"store Main Store archived successfully\"\n}"}]},{"name":"Bulk Archive Stores","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/archive","host":["{{baseUrl}}"],"path":["api","stores","archive"]},"description":"Bulk archives multiple stores by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/archive","host":["{{baseUrl}}"],"path":["api","stores","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 stores archived successfully\"\n}"}]},{"name":"Bulk Unarchive Stores","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/unarchive","host":["{{baseUrl}}"],"path":["api","stores","unarchive"]},"description":"Bulk unarchives multiple stores by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/stores/unarchive","host":["{{baseUrl}}"],"path":["api","stores","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 stores unarchived successfully\"\n}"}]},{"name":"Check Stores Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/deletable","host":["{{baseUrl}}"],"path":["api","stores","deletable"]},"description":"Checks which stores can be safely deleted.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stores/deletable","host":["{{baseUrl}}"],"path":["api","stores","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Main Store\",\n      \"deletable\": false,\n      \"reason\": {\n        \"sales_channels\": \"This store is used by sales channels.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"West Coast Store\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Import Stores","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/import","host":["{{baseUrl}}"],"path":["api","stores","import"]},"description":"Imports stores in bulk from JSON data.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.import`","body":{"mode":"raw","raw":"{\n  \"data\": [\n    {\n      \"name\": \"Import Store 1\",\n      \"email\": \"store1@acme.com\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stores/import","host":["{{baseUrl}}"],"path":["api","stores","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Stores imported successfully\"\n}"}]},{"name":"Preview Import Stores","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stores/import/preview","host":["{{baseUrl}}"],"path":["api","stores","import","preview"]},"description":"Previews a store import without committing changes.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `stores.import`","body":{"mode":"raw","raw":"{\n  \"data\": [\n    {\n      \"name\": \"Preview Store 1\",\n      \"email\": \"preview1@acme.com\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stores/import/preview","host":["{{baseUrl}}"],"path":["api","stores","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"name\": \"Preview Store 1\",\n      \"action\": \"create\",\n      \"email\": \"preview1@acme.com\"\n    }\n  ]\n}"}]}]},{"name":"Sales Channels","item":[{"name":"List Inbound Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns paginated inbound API events for a channel partner instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 100,\n      \"integration_instance_id\": 1,\n      \"endpoint\": \"channel.orders.store\",\n      \"http_method\": \"POST\",\n      \"processing_status\": \"processed\",\n      \"processing_error\": null,\n      \"processing_attempts\": 1,\n      \"ip_address\": \"203.0.113.5\",\n      \"user_agent\": \"MyStorefront/1.0\",\n      \"linked_resource_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"linked_resource_id\": 500,\n      \"unique_id\": \"order-ext-123\",\n      \"created_at\": \"2024-06-01T08:00:00.000000Z\",\n      \"processed_at\": \"2024-06-01T08:00:01.000000Z\",\n      \"processing_started_at\": \"2024-06-01T08:00:00.500000Z\",\n      \"processing_completed_at\": \"2024-06-01T08:00:01.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Get Inbound Event Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events/stats","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events","stats"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns event processing statistics and distinct endpoint list for a channel partner.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/{id}/inbound-events/stats","host":["{{baseUrl}}"],"path":["api","channel-partners",":id","inbound-events","stats"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 142,\n    \"processed\": 138,\n    \"failed\": 4,\n    \"processing\": 0,\n    \"pending\": 0,\n    \"endpoints\": [\n      \"channel.orders.store\",\n      \"channel.orders.update\"\n    ]\n  }\n}"}]},{"name":"Get Inbound Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single inbound event with full request/response payloads and headers.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/{id}","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 100,\n    \"integration_instance_id\": 1,\n    \"integration_instance_name\": \"My Storefront API\",\n    \"endpoint\": \"channel.orders.store\",\n    \"http_method\": \"POST\",\n    \"processing_status\": \"processed\",\n    \"processing_error\": null,\n    \"processing_attempts\": 1,\n    \"ip_address\": \"203.0.113.5\",\n    \"user_agent\": \"MyStorefront/1.0\",\n    \"request_payload\": {\n      \"sales_order_number\": \"EXT-001\",\n      \"order_date\": \"2024-06-01\"\n    },\n    \"response_payload\": {\n      \"message\": \"sales order created successfully.\"\n    },\n    \"request_headers\": {\n      \"content-type\": \"application/json\"\n    },\n    \"linked_resource_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"linked_resource_id\": 500,\n    \"unique_id\": \"order-ext-123\",\n    \"created_at\": \"2024-06-01T08:00:00.000000Z\",\n    \"processed_at\": \"2024-06-01T08:00:01.000000Z\"\n  }\n}"}]},{"name":"Reprocess Inbound Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/{id}/reprocess","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events",":id","reprocess"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Reprocesses a single failed inbound event. Cannot reprocess already-processed events.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/{id}/reprocess","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events",":id","reprocess"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Event queued for reprocessing.\",\n  \"data\": {\n    \"id\": 100,\n    \"processing_status\": \"processing\",\n    \"processing_attempts\": 2\n  }\n}"}]},{"name":"Bulk Reprocess Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events","bulk-reprocess"]},"description":"Bulk reprocesses multiple inbound events by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of event IDs to reprocess (min 1)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    100,\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events","bulk-reprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 event(s) queued for reprocessing.\"\n}"}]},{"name":"Bulk Delete Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events","bulk-delete"]},"description":"Bulk deletes inbound events by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required): Array of event IDs to delete (min 1)"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/channel-partners/inbound-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","channel-partners","inbound-events","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 event(s) deleted.\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Lists sales orders for the authenticated channel (filtered to the integration instance's sales channel).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token (channel:read ability). Use {{channel-token}} variable.\n\nRate limits: 500 requests per 60 seconds."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 500,\n      \"sales_order_number\": \"SO-2024-500\",\n      \"customer_po_number\": \"EXT-001\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"customer_name\": \"John Doe\",\n      \"order_date\": \"2024-06-01T08:00:00.000000Z\",\n      \"ship_by_date\": \"2024-06-05T00:00:00.000000Z\",\n      \"deliver_by_date\": null,\n      \"product_subtotal\": 150,\n      \"requested_shipping_method\": \"standard\",\n      \"sales_channel_id\": 3,\n      \"fulfillment_channel\": null,\n      \"created_at\": \"2024-06-01T08:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T08:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 142\n}"}]},{"name":"Create Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel/orders","host":["{{baseUrl}}"],"path":["api","channel","orders"]},"description":"Creates a new sales order from a channel integration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token (channel:write ability).\n\nRate limits: 500 requests per 60 seconds.\n\nAll inbound events are automatically captured for audit/replay.\n\nFields:\n- sales_order_number (required, unique per channel): External order identifier\n- order_date (required): Order date\n- ship_by_date (optional): Must be >= order_date\n- hold_until_date (optional): \"Do not ship before\" release date for preorders / scheduled holds. Must be >= order_date.\n- deliver_by_date (optional): Must be >= order_date\n- customer_po_number (optional): Customer's PO reference\n- requested_shipping_method (optional): Requested shipping service\n- shipping_charge (optional): Shipping amount\n- customer (optional): Customer info — must have EITHER id OR name, not both\n  - customer.id: Existing customer ID\n  - customer.name: Customer name\n  - customer.email: Email\n  - customer.phone: Phone\n  - customer.company: Company name\n- billing_address (optional): Billing address object\n- shipping_address (optional): Shipping address object\n  - *.name, *.company, *.address1, *.address2, *.city, *.province_code, *.zip, *.country_code, *.phone\n- sales_order_lines (required, min 1): Order lines\n  - lines.*.sku (required): Product SKU (must exist)\n  - lines.*.quantity (required): Quantity (min 1)\n  - lines.*.unit_price (optional): Unit price\n  - lines.*.description (optional): Line description\n- notes (optional): Array of note strings\n- tags (optional): Array of tag strings\n- sales_rep (optional): Sales rep — must have EITHER id OR name, not both\n  - sales_rep.id: Existing active sales rep ID\n  - sales_rep.name: Sales rep name","body":{"mode":"raw","raw":"{\n  \"sales_order_number\": \"EXT-ORDER-2024-001\",\n  \"order_date\": \"2024-06-01\",\n  \"ship_by_date\": \"2024-06-05\",\n  \"hold_until_date\": \"2024-06-03\",\n  \"deliver_by_date\": \"2024-06-07\",\n  \"customer_po_number\": \"CUST-PO-001\",\n  \"requested_shipping_method\": \"standard\",\n  \"shipping_charge\": 9.99,\n  \"customer\": {\n    \"name\": \"John Doe\",\n    \"email\": \"john.doe@example.com\",\n    \"company\": \"Acme Corp\"\n  },\n  \"billing_address\": {\n    \"name\": \"John Doe\",\n    \"address1\": \"123 Main St\",\n    \"address2\": \"Apt 4B\",\n    \"city\": \"New York\",\n    \"province_code\": \"NY\",\n    \"zip\": \"10001\",\n    \"country_code\": \"US\",\n    \"phone\": \"+1-212-555-0100\"\n  },\n  \"shipping_address\": {\n    \"name\": \"John Doe\",\n    \"address1\": \"123 Main St\",\n    \"city\": \"New York\",\n    \"province_code\": \"NY\",\n    \"zip\": \"10001\",\n    \"country_code\": \"US\"\n  },\n  \"sales_order_lines\": [\n    {\n      \"sku\": \"WIDGET-PRO-001\",\n      \"quantity\": 2,\n      \"unit_price\": 75,\n      \"description\": \"Widget Pro x2\"\n    }\n  ],\n  \"notes\": [\n    \"Please ship as soon as possible\"\n  ],\n  \"tags\": [\n    \"vip\",\n    \"priority\"\n  ],\n  \"sales_rep\": {\n    \"name\": \"Jane Smith\",\n    \"email\": \"jane@sku.io\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/channel/orders","host":["{{baseUrl}}"],"path":["api","channel","orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales order created successfully.\",\n  \"data\": {\n    \"id\": 501,\n    \"sales_order_number\": \"EXT-ORDER-2024-001\",\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"order_date\": \"2024-06-01T00:00:00.000000Z\",\n    \"sales_order_lines\": [\n      {\n        \"id\": 1002,\n        \"product\": {\n          \"id\": 10,\n          \"name\": \"Widget Pro\",\n          \"sku\": \"WIDGET-PRO-001\"\n        },\n        \"quantity\": 2,\n        \"unit_price\": 75\n      }\n    ],\n    \"tags\": [\n      \"vip\",\n      \"priority\"\n    ]\n  }\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/orders/{id}","host":["{{baseUrl}}"],"path":["api","channel","orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single sales order for the authenticated channel with fulfillment and address details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nReturns 403 if the order does not belong to the authenticated channel."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/orders/{id}","host":["{{baseUrl}}"],"path":["api","channel","orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-2024-500\",\n    \"order_status\": \"open\",\n    \"fulfillment_status\": \"unfulfilled\",\n    \"order_date\": \"2024-06-01T08:00:00.000000Z\",\n    \"billing_address\": {\n      \"name\": \"John Doe\",\n      \"address1\": \"123 Main St\",\n      \"city\": \"New York\",\n      \"zip\": \"10001\",\n      \"country_code\": \"US\"\n    },\n    \"shipping_address\": {\n      \"name\": \"John Doe\",\n      \"address1\": \"123 Main St\",\n      \"city\": \"New York\",\n      \"zip\": \"10001\",\n      \"country_code\": \"US\"\n    },\n    \"sales_order_lines\": [\n      {\n        \"id\": 1001,\n        \"product\": {\n          \"id\": 10,\n          \"name\": \"Widget Pro\",\n          \"sku\": \"WIDGET-PRO-001\"\n        },\n        \"quantity\": 2,\n        \"unit_price\": 75\n      }\n    ],\n    \"tags\": []\n  }\n}"}]},{"name":"Update Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/channel/orders/{id}","host":["{{baseUrl}}"],"path":["api","channel","orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a sales order for the authenticated channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nReturns 403 if the order does not belong to the authenticated channel.","body":{"mode":"raw","raw":"{\n  \"ship_by_date\": \"2024-06-06\",\n  \"hold_until_date\": \"2024-06-03\",\n  \"requested_shipping_method\": \"express\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/channel/orders/{id}","host":["{{baseUrl}}"],"path":["api","channel","orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"sales order updated successfully.\",\n  \"data\": {\n    \"id\": 500,\n    \"sales_order_number\": \"SO-2024-500\",\n    \"order_status\": \"open\",\n    \"requested_shipping_method\": \"express\",\n    \"ship_by_date\": \"2024-06-06T00:00:00.000000Z\"\n  }\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/products?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Returns paginated products visible to the authenticated channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nRate limits: 2000 requests per 60 minutes."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/products?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10,\n      \"name\": \"Widget Pro\",\n      \"sku\": \"WIDGET-PRO-001\",\n      \"barcode\": \"123456789012\",\n      \"price\": 75\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 50\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/products/{id}","host":["{{baseUrl}}"],"path":["api","channel","products",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single product by ID for the authenticated channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nRate limits: 2000 requests per 60 minutes."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/products/{id}","host":["{{baseUrl}}"],"path":["api","channel","products",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"Widget Pro\",\n    \"sku\": \"WIDGET-PRO-001\",\n    \"barcode\": \"123456789012\",\n    \"price\": 75,\n    \"description\": \"The best widget\",\n    \"weight\": 0.5\n  }\n}"}]},{"name":"List Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/inventory?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","inventory"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Returns paginated inventory levels for the authenticated channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nRate limits: 2000 requests per 60 minutes."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/inventory?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","inventory"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"sku\": \"WIDGET-PRO-001\",\n      \"available_quantity\": 85,\n      \"on_hand_quantity\": 100,\n      \"allocated_quantity\": 15\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 50\n}"}]},{"name":"List Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/customers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","customers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Returns paginated customers for the authenticated channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nRate limits: 2000 requests per 60 minutes."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/customers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","channel","customers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 50,\n      \"name\": \"John Doe\",\n      \"email\": \"john.doe@example.com\",\n      \"company\": \"Acme Corp\",\n      \"channel_id\": 1,\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"per_page\": 15,\n  \"total\": 30\n}"}]},{"name":"Get Customer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/channel/customers/{id}","host":["{{baseUrl}}"],"path":["api","channel","customers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single customer with addresses and default sales rep.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires channel integration token.\n\nRate limits: 2000 requests per 60 minutes."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/channel/customers/{id}","host":["{{baseUrl}}"],"path":["api","channel","customers",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 50,\n    \"name\": \"John Doe\",\n    \"email\": \"john.doe@example.com\",\n    \"company\": \"Acme Corp\",\n    \"channel_id\": 1,\n    \"billing_address\": {\n      \"id\": 200,\n      \"name\": \"John Doe\",\n      \"address1\": \"123 Main St\",\n      \"city\": \"New York\",\n      \"province\": \"NY\",\n      \"zip\": \"10001\",\n      \"country_code\": \"US\",\n      \"phone\": \"+1-212-555-0100\"\n    },\n    \"shipping_address\": null,\n    \"addresses\": [],\n    \"default_pricing_tier\": null,\n    \"default_sales_rep\": null\n  }\n}"}]}]},{"name":"Store Email Templates","item":[{"name":"List Store Email Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates?page=1&limit=15&sort=subject&search=","host":["{{baseUrl}}"],"path":["api","store-email-templates"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"subject","description":"Sort field (prefix with - for descending)","disabled":true},{"key":"search","value":"","description":"Search by subject or type","disabled":true}]},"description":"Returns a paginated listing of store email templates.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort fields: subject, type, store_id, enabled, sent_type, is_system_template, created_at, updated_at, archived_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/store-email-templates?page=1&limit=15&sort=subject&search=","host":["{{baseUrl}}"],"path":["api","store-email-templates"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"15","description":"Records per page","disabled":true},{"key":"sort","value":"subject","description":"Sort field (prefix with - for descending)","disabled":true},{"key":"search","value":"","description":"Search by subject or type","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"store_id\": 3,\n      \"type\": \"purchase_order\",\n      \"subject\": \"Your Purchase Order #{{order_number}}\",\n      \"title\": \"Your Purchase Order #{{order_number}}\",\n      \"enabled\": true,\n      \"attach_pdf\": true,\n      \"sent_type\": \"automatically\",\n      \"is_system_template\": true,\n      \"cc\": [\n        \"purchasing@company.com\"\n      ],\n      \"archived_at\": null,\n      \"updated_at\": \"2024-05-15T09:00:00.000000Z\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 5\n}"}]},{"name":"Create Store Email Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates"]},"description":"Creates a new store email template (always non-system).\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- store_id (required): store ID (must exist)\n- context (required): bound entity — one of sales_order, purchase_order, sales_credit, vendor_credit, bulk_purchase_order, warehouse_transfer. Determines available variables and attachable documents.\n- event (required): trigger within the context (e.g. confirmation, updated, fulfilled, submitted, issued, manual). The legacy `type` column is derived from context+event server-side.\n- name (optional): human label for the template\n- subject (required): subject line, max 255\n- html_body (required): HTML body (supports {{ }} merge variables)\n- enabled (optional): boolean. For automatic events only one template per (store, context, event) stays enabled.\n- sent_type (optional): automatically | manually\n- cc (optional): array of email addresses\n- attachments (optional): array of document keys valid for the context (e.g. po_pdf, po_csv, po_xlsx, invoice_pdf, credit_note_pdf, vendor_credit_pdf)\n\n**Requires permission:** `email_templates.create`","body":{"mode":"raw","raw":"{\n  \"store_id\": 3,\n  \"context\": \"purchase_order\",\n  \"event\": \"manual\",\n  \"name\": \"Standard supplier PO email\",\n  \"subject\": \"Order {{purchase_order_number}} from {{company_name}}\",\n  \"html_body\": \"<html><body><p>Dear {{supplier_name}}, please find our order attached.</p></body></html>\",\n  \"enabled\": true,\n  \"sent_type\": \"manually\",\n  \"cc\": [\n    \"ops@example.com\"\n  ],\n  \"attachments\": [\n    \"po_pdf\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/store-email-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 12,\n    \"store_id\": 3,\n    \"type\": \"user_purchase_order\",\n    \"context\": \"purchase_order\",\n    \"event\": \"manual\",\n    \"name\": \"Standard supplier PO email\",\n    \"subject\": \"Order {{purchase_order_number}} from {{company_name}}\",\n    \"title\": \"Order {{purchase_order_number}} from {{company_name}}\",\n    \"enabled\": true,\n    \"attach_pdf\": false,\n    \"attachments\": [\n      \"po_pdf\"\n    ],\n    \"sent_type\": \"manually\",\n    \"html_body\": \"<html><body><p>Dear {{supplier_name}}, please find our order attached.</p></body></html>\",\n    \"is_system_template\": false,\n    \"cc\": [\n      \"ops@example.com\"\n    ],\n    \"created_at\": \"2026-05-28T12:00:00.000000Z\",\n    \"updated_at\": \"2026-05-28T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Bulk Delete Store Email Templates","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates"]},"description":"Bulk deletes multiple store email templates by ID array or current list view filters.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `email_templates.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/store-email-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Templates deleted successfully\"\n}"}]},{"name":"List User Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/user-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates","user-templates"]},"description":"Returns only non-system (user-created) email templates. Excludes system templates that are managed by the application.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/store-email-templates/user-templates","host":["{{baseUrl}}"],"path":["api","store-email-templates","user-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 8,\n      \"store_id\": 3,\n      \"type\": \"purchase_order\",\n      \"subject\": \"Custom PO Template\",\n      \"title\": \"Custom PO Template\",\n      \"enabled\": true,\n      \"attach_pdf\": false,\n      \"sent_type\": \"manually\",\n      \"is_system_template\": false,\n      \"cc\": [],\n      \"archived_at\": null,\n      \"updated_at\": \"2024-06-01T10:00:00.000000Z\",\n      \"created_at\": \"2024-06-01T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Template Contexts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/contexts","host":["{{baseUrl}}"],"path":["api","store-email-templates","contexts"]},"description":"Returns the email-template context catalog: for each context (bound entity) its label, available events (automatic/manual), merge variables, and attachable documents. The editor and send dialogs use this as the single source of truth for what a template can contain.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/store-email-templates/contexts","host":["{{baseUrl}}"],"path":["api","store-email-templates","contexts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purchase_order\": {\n      \"label\": \"Purchase Order\",\n      \"events\": [\n        {\n          \"key\": \"submitted\",\n          \"label\": \"PO Submitted\",\n          \"trigger\": \"automatic\",\n          \"description\": \"Sends automatically to the supplier every time a purchase order is submitted.\"\n        },\n        {\n          \"key\": \"updated\",\n          \"label\": \"PO Updated\",\n          \"trigger\": \"automatic\",\n          \"description\": \"Sends automatically every time a submitted purchase order is changed.\"\n        },\n        {\n          \"key\": \"manual\",\n          \"label\": \"Manual Send\",\n          \"trigger\": \"manual\",\n          \"description\": \"Never sends on its own. You choose this template from the purchase order screen when you want to email the supplier.\"\n        }\n      ],\n      \"variables\": [\n        {\n          \"token\": \"{{purchase_order_number}}\",\n          \"label\": \"Purchase Order ID\",\n          \"group\": \"Details\",\n          \"is_table\": false\n        },\n        {\n          \"token\": \"{{purchase_order_lines}}\",\n          \"label\": \"Order Item List\",\n          \"group\": \"Line Items\",\n          \"is_table\": true\n        }\n      ],\n      \"documents\": [\n        {\n          \"key\": \"po_pdf\",\n          \"label\": \"PO PDF\",\n          \"mime\": \"application/pdf\"\n        },\n        {\n          \"key\": \"po_csv\",\n          \"label\": \"PO CSV\",\n          \"mime\": \"text/csv\"\n        },\n        {\n          \"key\": \"po_xlsx\",\n          \"label\": \"PO XLSX\",\n          \"mime\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Get Store Email Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single store email template with its HTML body.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1,\n    \"store_id\": 3,\n    \"type\": \"purchase_order\",\n    \"subject\": \"Your Purchase Order #{{order_number}}\",\n    \"title\": \"Your Purchase Order #{{order_number}}\",\n    \"enabled\": true,\n    \"attach_pdf\": true,\n    \"sent_type\": \"automatically\",\n    \"html_body\": \"<html><body><h1>Purchase Order</h1><p>Dear {{supplier_name}},</p></body></html>\",\n    \"is_system_template\": true,\n    \"cc\": [\n      \"purchasing@company.com\"\n    ],\n    \"archived_at\": null,\n    \"updated_at\": \"2024-05-15T09:00:00.000000Z\",\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Store Email Template","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing store email template.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAccepts the same fields as create (context, event, name, subject, html_body, enabled, sent_type, cc, attachments). Enabling an automatic-event template disables any other enabled template in the same (store, context, event) slot.","body":{"mode":"raw","raw":"{\n  \"context\": \"purchase_order\",\n  \"event\": \"manual\",\n  \"name\": \"Standard supplier PO email\",\n  \"subject\": \"Updated subject {{purchase_order_number}}\",\n  \"html_body\": \"<html><body><p>Updated body.</p></body></html>\",\n  \"enabled\": true,\n  \"attachments\": [\n    \"po_pdf\",\n    \"po_csv\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 1,\n    \"subject\": \"Updated: Your PO #{{order_number}}\",\n    \"enabled\": false,\n    \"sent_type\": \"manually\",\n    \"updated_at\": \"2024-06-15T14:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Store Email Template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a single store email template.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Deleted successfully\"\n}"}]},{"name":"Archive Store Email Template","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}/archive","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a single store email template. Idempotent — returns a warning if already archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}/archive","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"StoreEmailTemplate archived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"archived_at\": \"2024-06-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Unarchive Store Email Template","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a single store email template.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/store-email-templates/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","store-email-templates",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"StoreEmailTemplate unarchived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"archived_at\": null\n  }\n}"}]},{"name":"Bulk Archive Store Email Templates","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/archive","host":["{{baseUrl}}"],"path":["api","store-email-templates","archive"]},"description":"Bulk archives multiple store email templates by ID array or current list view filters.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `email_templates.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/store-email-templates/archive","host":["{{baseUrl}}"],"path":["api","store-email-templates","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Templates archived successfully\"\n}"}]},{"name":"Bulk Unarchive Store Email Templates","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/unarchive","host":["{{baseUrl}}"],"path":["api","store-email-templates","unarchive"]},"description":"Bulk unarchives multiple store email templates by ID array or current list view filters.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `email_templates.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/store-email-templates/unarchive","host":["{{baseUrl}}"],"path":["api","store-email-templates","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Templates unarchived successfully\"\n}"}]},{"name":"Check Templates Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/deletable","host":["{{baseUrl}}"],"path":["api","store-email-templates","deletable"]},"description":"Checks whether each provided store email template ID can be safely deleted.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `email_templates.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/store-email-templates/deletable","host":["{{baseUrl}}"],"path":["api","store-email-templates","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"deletable\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 2,\n      \"deletable\": false,\n      \"reason\": \"System template\"\n    }\n  ]\n}"}]},{"name":"Preview Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/preview","host":["{{baseUrl}}"],"path":["api","store-email-templates","preview"]},"description":"Previews a template with rendered variable substitutions. For bulk_purchase_order type, uses the bulk preview renderer.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- id: Order or entity ID to use for variable substitution\n- type: Template type (e.g. purchase_order, purchase_order_updated, bulk_purchase_order)\n- subject: Subject line template string\n- body: HTML body template string\n- variables (optional): Boolean — if true, returns variable placeholders instead of rendered values","body":{"mode":"raw","raw":"{\n  \"id\": 42,\n  \"type\": \"purchase_order\",\n  \"subject\": \"Your PO #{{order_number}}\",\n  \"body\": \"<p>Dear {{supplier_name}},</p><p>Your PO is attached.</p>\",\n  \"variables\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/store-email-templates/preview","host":["{{baseUrl}}"],"path":["api","store-email-templates","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"subject\": \"Your PO #PO-2024-0042\",\n  \"body\": \"<p>Dear ACME Supplies,</p><p>Your PO is attached.</p>\"\n}"}]},{"name":"Send Templated Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/store-email-templates/send","host":["{{baseUrl}}"],"path":["api","store-email-templates","send"]},"description":"Send an email to the customer (sales order) or supplier (purchase order, vendor credit) using a store email template.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- order_type (required): SalesOrder | PurchaseOrder | VendorCredit\n- order_id (required): ID of the record to email\n- subject (required): rendered subject line\n- html_body (required): rendered HTML email body\n- cc (optional): array of CC email addresses (null/blank entries are dropped)\n- attachments (optional): array of document keys to attach (resolved per the entity's attachable-documents registry)\n- store_id (optional): ID of the store whose email address is used as the sender (\"from\"). When omitted, falls back to the record's own store, then the tenant's default (oldest active) store.\n\nErrors:\n- 422 store_sender_missing: no store with a sender email address is configured. The error payload includes errors.store[0].data.configure_route pointing to where stores are managed.","body":{"mode":"raw","raw":"{\n  \"order_type\": \"VendorCredit\",\n  \"order_id\": 11,\n  \"subject\": \"Message regarding vendor credit VC-00009\",\n  \"html_body\": \"<html><body><p>Please find the credit attached.</p></body></html>\",\n  \"cc\": [\n    \"buyer@example.com\"\n  ],\n  \"attachments\": [\n    \"vendor_credit_pdf\"\n  ],\n  \"store_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/store-email-templates/send","host":["{{baseUrl}}"],"path":["api","store-email-templates","send"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Email sent successfully\"\n}"}]}]},{"name":"Sales Channel Product Templates","item":[{"name":"List Sales Channel Product Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates"]},"description":"Returns all sales channel product templates. Supports filtering by sales channel.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nAvailable filters:\n- filter[sales_channel_id]: Filter to templates for a specific sales channel (exact match)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 1,\n    \"sales_channel_id\": 5,\n    \"name\": \"Standard Shopify Template\",\n    \"template_data\": {\n      \"vendor\": \"My Brand\",\n      \"product_type\": \"Physical\",\n      \"tags\": [\n        \"new\",\n        \"featured\"\n      ]\n    },\n    \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n    \"updated_at\": \"2024-01-10T09:00:00.000000Z\"\n  }\n]"}]},{"name":"Create Sales Channel Product Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates"]},"description":"Creates a new sales channel product template that can be applied when pushing products to a sales channel.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sales_channel_id\": 5,\n  \"name\": \"Standard Shopify Template\",\n  \"template_data\": {\n    \"vendor\": \"My Brand\",\n    \"product_type\": \"Physical\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 2,\n  \"sales_channel_id\": 5,\n  \"name\": \"Standard Shopify Template\",\n  \"template_data\": {\n    \"vendor\": \"My Brand\",\n    \"product_type\": \"Physical\"\n  },\n  \"created_at\": \"2024-01-20T14:00:00.000000Z\",\n  \"updated_at\": \"2024-01-20T14:00:00.000000Z\"\n}"}]},{"name":"Get Sales Channel Product Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]},"description":"Returns a single sales channel product template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"sales_channel_id\": 5,\n  \"name\": \"Standard Shopify Template\",\n  \"template_data\": {\n    \"vendor\": \"My Brand\",\n    \"product_type\": \"Physical\",\n    \"tags\": [\n      \"new\"\n    ]\n  },\n  \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n  \"updated_at\": \"2024-01-10T09:00:00.000000Z\"\n}"}]},{"name":"Update Sales Channel Product Template","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]},"description":"Updates a sales channel product template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Template Name\",\n  \"template_data\": {\n    \"vendor\": \"New Brand\",\n    \"product_type\": \"Digital\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"sales_channel_id\": 5,\n  \"name\": \"Updated Template Name\",\n  \"template_data\": {\n    \"vendor\": \"New Brand\",\n    \"product_type\": \"Digital\"\n  },\n  \"created_at\": \"2024-01-10T09:00:00.000000Z\",\n  \"updated_at\": \"2024-01-20T15:00:00.000000Z\"\n}"}]},{"name":"Delete Sales Channel Product Template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]},"description":"Permanently deletes a sales channel product template.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-channel-product-templates/{sales_channel_product_template}","host":["{{baseUrl}}"],"path":["api","sales-channel-product-templates",":sales_channel_product_template"],"variable":[{"key":"sales_channel_product_template","value":"1","description":"Template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null\n}"}]},{"name":"Preview Sales Channel Product Template Against Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/sales-channels/{salesChannel}/product-templates/preview","host":["{{baseUrl}}"],"path":["api","v2","sales-channels",":salesChannel","product-templates","preview"],"variable":[{"key":"salesChannel","value":"1","description":"Sales channel ID the category belongs to."}]},"description":"Resolves a set of field mappings against a specific product and returns the value each channel field would receive — without saving a template. Use it to preview how a template will map a product's data (fields, attributes, static values, and expressions) before you create or update it.\n\nBody fields:\n- product_id (required, integer) — the product to resolve values for.\n- sales_channel_category_id (required, integer) — the channel category whose fields are being mapped. Must belong to the sales channel in the path.\n- field_mappings (optional, array) — the in-progress mappings to resolve. Each item: sales_channel_category_field_id (integer), source_type (one of product_field, product_attribute, static, expression), source_value (string), OR core_field_name (string) to target a core listing field (Title/Description/Price) by name. Blank or empty mappings are ignored and fall through to any existing channel mapping or default.\n\nThe response `values` object is keyed by channel field name; each entry has the resolved value and its provenance (override, template, channel_mapping, integration_mapping, channel_default, or blank).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"sales_channel_category_id\": 88,\n  \"field_mappings\": [\n    {\n      \"sales_channel_category_field_id\": 501,\n      \"source_type\": \"product_field\",\n      \"source_value\": \"brand\"\n    },\n    {\n      \"sales_channel_category_field_id\": 503,\n      \"source_type\": \"static\",\n      \"source_value\": \"Clear\"\n    },\n    {\n      \"core_field_name\": \"Description\",\n      \"source_type\": \"static\",\n      \"source_value\": \"Durable, water-resistant, built to last.\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/sales-channels/{salesChannel}/product-templates/preview","host":["{{baseUrl}}"],"path":["api","v2","sales-channels",":salesChannel","product-templates","preview"],"variable":[{"key":"salesChannel","value":"1","description":"Sales channel ID the category belongs to."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 42,\n      \"name\": \"Gel Strengthener Base Coat\",\n      \"sku\": \"LL-GSB-15\"\n    },\n    \"values\": {\n      \"Brand\": {\n        \"value\": \"Lumen Lab\",\n        \"provenance\": \"override\"\n      },\n      \"Color\": {\n        \"value\": \"Clear\",\n        \"provenance\": \"override\"\n      },\n      \"Title\": {\n        \"value\": \"Lumen Lab - Gel Strengthener Base Coat\",\n        \"provenance\": \"override\"\n      },\n      \"Material\": {\n        \"value\": null,\n        \"provenance\": \"blank\"\n      }\n    }\n  }\n}"}]}]},{"name":"eBay","item":[{"name":"List eBay Integrations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay","host":["{{baseUrl}}"],"path":["api","ebay"]},"description":"List every connected eBay integration instance on the account. Returns the full instance record for each connection, including its settings and sync state.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay","host":["{{baseUrl}}"],"path":["api","ebay"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"environment\": \"production\",\n      \"name\": \"eBay US Store\",\n      \"integration_id\": 4,\n      \"connection_settings\": {\n        \"access_token\": \"v^1.1#i^1#p^3#EXAMPLE\",\n        \"refresh_token\": \"v^1.1#i^1#r^1#EXAMPLE\"\n      },\n      \"integration_settings\": {\n        \"start_date\": \"2026-01-01 00:00:00\",\n        \"store_id\": 2,\n        \"auto_link_products\": true,\n        \"auto_create_products\": false,\n        \"sales_nominal_code_id\": 12,\n        \"cogs_nominal_code_id\": 15,\n        \"shipping_revenue_nominal_code_id\": 18,\n        \"shipping_refund_nominal_code_id\": 19,\n        \"sales_returns_allowances_nominal_code_id\": 21,\n        \"emailCustomers\": false,\n        \"proforma_marketplace_cost_percentage\": 12.9,\n        \"proforma_payment_cost_percentage\": 2.9,\n        \"sync_sales_order_invoices_to_accounting\": true,\n        \"sync_sales_credit_to_accounting\": true,\n        \"pricing\": {\n          \"masterOfPrice\": {\n            \"id\": \"neither\",\n            \"name\": \"Neither\"\n          }\n        },\n        \"inventory\": {\n          \"masterOfStock\": \"Neither\",\n          \"selectedWarehouses\": []\n        }\n      },\n      \"is_automatic_sync_enabled\": true,\n      \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n      \"updated_at\": \"2026-07-06T18:15:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create eBay Integration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay","host":["{{baseUrl}}"],"path":["api","ebay"]},"description":"Create a new eBay integration instance. The response includes a redirect_url pointing to the eBay consent page; open it to authorize the connection. After authorization completes, listings and orders are automatically imported in the background.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- name (string, required): Unique display name for the connection.\n- integration_id (integer, required): ID of the eBay integration definition.\n- integration_settings (object, required): Channel settings. Required keys: start_date (date string - orders created before this date are not imported), store_id (integer), auto_link_products (boolean), auto_create_products (boolean), sales_nominal_code_id, cogs_nominal_code_id, shipping_revenue_nominal_code_id, shipping_refund_nominal_code_id, sales_returns_allowances_nominal_code_id (integers or null). Optional keys: pricing (object with masterOfPrice {id, name} and pricing_tier_id), inventory (object with masterOfStock, selectedWarehouses), emailCustomers (boolean, default false), proforma_marketplace_cost_percentage (number or null), proforma_payment_cost_percentage (number or null), sync_sales_order_invoices_to_accounting (boolean, default true), sync_sales_credit_to_accounting (boolean, default true), batch_period_sales_order_fulfillments (string or null), batch_period_customer_returns (string or null).\n- connection_settings (object, optional): OAuth tokens (access_token, refresh_token, expiresAccessToken, expiresRefreshToken). Normally omitted - tokens are stored automatically when the OAuth authorization completes.\n- is_automatic_sync_enabled (boolean, optional, default false).\n- environment (string, optional): \"production\" or \"sandbox\".","body":{"mode":"raw","raw":"{\n  \"name\": \"eBay US Store\",\n  \"integration_id\": 4,\n  \"is_automatic_sync_enabled\": false,\n  \"environment\": \"production\",\n  \"integration_settings\": {\n    \"start_date\": \"2026-01-01\",\n    \"store_id\": 2,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": 12,\n    \"cogs_nominal_code_id\": 15,\n    \"shipping_revenue_nominal_code_id\": 18,\n    \"shipping_refund_nominal_code_id\": 19,\n    \"sales_returns_allowances_nominal_code_id\": 21,\n    \"emailCustomers\": false,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true,\n    \"pricing\": {\n      \"masterOfPrice\": {\n        \"id\": \"neither\",\n        \"name\": \"Neither\"\n      }\n    },\n    \"inventory\": {\n      \"masterOfStock\": \"Neither\",\n      \"selectedWarehouses\": []\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay","host":["{{baseUrl}}"],"path":["api","ebay"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"environment\": \"production\",\n    \"name\": \"eBay US Store\",\n    \"integration_id\": 4,\n    \"connection_settings\": {\n      \"access_token\": \"v^1.1#i^1#p^3#EXAMPLE\",\n      \"refresh_token\": \"v^1.1#i^1#r^1#EXAMPLE\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01 00:00:00\",\n      \"store_id\": 2,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 12,\n      \"cogs_nominal_code_id\": 15,\n      \"shipping_revenue_nominal_code_id\": 18,\n      \"shipping_refund_nominal_code_id\": 19,\n      \"sales_returns_allowances_nominal_code_id\": 21,\n      \"emailCustomers\": false,\n      \"proforma_marketplace_cost_percentage\": 12.9,\n      \"proforma_payment_cost_percentage\": 2.9,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"pricing\": {\n        \"masterOfPrice\": {\n          \"id\": \"neither\",\n          \"name\": \"Neither\"\n        }\n      },\n      \"inventory\": {\n        \"masterOfStock\": \"Neither\",\n        \"selectedWarehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:15:00.000000Z\"\n  },\n  \"redirect_url\": \"https://auth.ebay.com/oauth2/authorize?client_id=EXAMPLE&redirect_uri=EXAMPLE&response_type=code&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope&state=abc123\",\n  \"status\": \"success\"\n}"}]},{"name":"Get eBay Integration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get a single eBay integration instance, including its sales channel, store, and settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"integration_name\": \"eBay\",\n    \"sales_channel_id\": 9,\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"environment\": \"production\",\n    \"name\": \"eBay US Store\",\n    \"integration_id\": 4,\n    \"connection_settings\": {\n      \"access_token\": \"v^1.1#i^1#p^3#EXAMPLE\",\n      \"refresh_token\": \"v^1.1#i^1#r^1#EXAMPLE\",\n      \"expiresAccessToken\": 1751851200,\n      \"expiresRefreshToken\": 1799942400\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01 00:00:00\",\n      \"store_id\": 2,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 12,\n      \"cogs_nominal_code_id\": 15,\n      \"shipping_revenue_nominal_code_id\": 18,\n      \"shipping_refund_nominal_code_id\": 19,\n      \"sales_returns_allowances_nominal_code_id\": 21,\n      \"emailCustomers\": false,\n      \"proforma_marketplace_cost_percentage\": 12.9,\n      \"proforma_payment_cost_percentage\": 2.9,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"pricing\": {\n        \"masterOfPrice\": {\n          \"id\": \"neither\",\n          \"name\": \"Neither\"\n        }\n      },\n      \"inventory\": {\n        \"masterOfStock\": \"Neither\",\n        \"selectedWarehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:15:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update eBay Integration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Update an eBay integration instance. With PUT, a provided integration_settings object replaces the stored settings; use PATCH for merge semantics.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAll body fields are optional:\n- name (string): New display name.\n- integration_settings (object): Same shape as on create; every key is optional.\n- connection_settings (object): OAuth token fields.\n- is_automatic_sync_enabled (boolean): Toggle scheduled background sync.\n\nSide effects: changing start_date re-normalizes the stored date; changing store_id updates the linked sales channel; changing the pricing master triggers a price re-cache; changing inventory settings invalidates the inventory cache so quantities are recalculated.","body":{"mode":"raw","raw":"{\n  \"name\": \"eBay US Store\",\n  \"is_automatic_sync_enabled\": true,\n  \"integration_settings\": {\n    \"start_date\": \"2026-01-01\",\n    \"store_id\": 2,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": 12,\n    \"cogs_nominal_code_id\": 15,\n    \"shipping_revenue_nominal_code_id\": 18,\n    \"shipping_refund_nominal_code_id\": 19,\n    \"sales_returns_allowances_nominal_code_id\": 21,\n    \"inventory\": {\n      \"masterOfStock\": \"SKU\",\n      \"selectedWarehouses\": [\n        1,\n        2\n      ]\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"integration_name\": \"eBay\",\n    \"sales_channel_id\": 9,\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"environment\": \"production\",\n    \"name\": \"eBay US Store\",\n    \"integration_id\": 4,\n    \"connection_settings\": {\n      \"access_token\": \"v^1.1#i^1#p^3#EXAMPLE\",\n      \"refresh_token\": \"v^1.1#i^1#r^1#EXAMPLE\",\n      \"expiresAccessToken\": 1751851200,\n      \"expiresRefreshToken\": 1799942400\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01 00:00:00\",\n      \"store_id\": 2,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 12,\n      \"cogs_nominal_code_id\": 15,\n      \"shipping_revenue_nominal_code_id\": 18,\n      \"shipping_refund_nominal_code_id\": 19,\n      \"sales_returns_allowances_nominal_code_id\": 21,\n      \"emailCustomers\": false,\n      \"proforma_marketplace_cost_percentage\": 12.9,\n      \"proforma_payment_cost_percentage\": 2.9,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"pricing\": {\n        \"masterOfPrice\": {\n          \"id\": \"neither\",\n          \"name\": \"Neither\"\n        }\n      },\n      \"inventory\": {\n        \"masterOfStock\": \"Neither\",\n        \"selectedWarehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:15:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Partially Update eBay Integration","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Partially update an eBay integration instance using merge semantics: provided integration_settings and connection_settings keys are deep-merged into the stored values, so nested settings you omit are preserved. Exception: the inventory object is always replaced in full when provided (its warehouse and location lists are positional arrays).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAccepts the same body fields as the PUT update; all fields are optional.","body":{"mode":"raw","raw":"{\n  \"integration_settings\": {\n    \"inventory\": {\n      \"masterOfStock\": \"SKU\",\n      \"selectedWarehouses\": [\n        1\n      ]\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"integration_name\": \"eBay\",\n    \"sales_channel_id\": 9,\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"environment\": \"production\",\n    \"name\": \"eBay US Store\",\n    \"integration_id\": 4,\n    \"connection_settings\": {\n      \"access_token\": \"v^1.1#i^1#p^3#EXAMPLE\",\n      \"refresh_token\": \"v^1.1#i^1#r^1#EXAMPLE\",\n      \"expiresAccessToken\": 1751851200,\n      \"expiresRefreshToken\": 1799942400\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01 00:00:00\",\n      \"store_id\": 2,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 12,\n      \"cogs_nominal_code_id\": 15,\n      \"shipping_revenue_nominal_code_id\": 18,\n      \"shipping_refund_nominal_code_id\": 19,\n      \"sales_returns_allowances_nominal_code_id\": 21,\n      \"emailCustomers\": false,\n      \"proforma_marketplace_cost_percentage\": 12.9,\n      \"proforma_payment_cost_percentage\": 2.9,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"pricing\": {\n        \"masterOfPrice\": {\n          \"id\": \"neither\",\n          \"name\": \"Neither\"\n        }\n      },\n      \"inventory\": {\n        \"masterOfStock\": \"Neither\",\n        \"selectedWarehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:15:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete eBay Integration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Delete an eBay integration instance. The deletion runs as a background job that removes the connection and its channel data. Returns 204 immediately after the job is queued.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Get eBay Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get the eBay OAuth consent URL for this integration instance. Open the returned URL in a browser to grant (or re-grant) access. Use this to reconnect an integration whose refresh token has expired or been revoked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorization_url\": \"https://auth.ebay.com/oauth2/authorize?client_id=EXAMPLE&redirect_uri=EXAMPLE&response_type=code&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope&state=abc123\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List eBay Integration Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"List the audit history of eBay order records belonging to this integration instance, most recent first. Each entry describes a create/update event, the changed attributes, and who (or what) caused it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters:\n- filter[search]: matches the causer name, event name, or recorded properties.\n- filter[event]: exact event name (e.g. created, updated).\n- filter[source]: origin of the change (e.g. sync).\n- filter[batch_uuid]: all entries recorded by one batch operation."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"EbayOrder\",\n      \"subject_id\": 9101,\n      \"properties\": {\n        \"attributes\": {\n          \"orderFulfillmentStatus\": \"FULFILLED\"\n        },\n        \"old\": {\n          \"orderFulfillmentStatus\": \"IN_PROGRESS\"\n        },\n        \"source\": \"sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-29T10:11:02.000000Z\",\n      \"batch_uuid\": null\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/ebay/3/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{base_url}}/api/ebay/3/activity-log?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/ebay/3/activity-log?page=2\",\n  \"path\": \"{{base_url}}/api/ebay/3/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 48\n}"}]},{"name":"Get eBay Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Get a single locally-synced eBay listing, including its mapped product (when mapped) and the raw listing payload as last fetched from eBay.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- product (integer): The eBay listing record ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8121,\n    \"integration_instance_id\": 3,\n    \"product_listing_id\": 452,\n    \"product\": {\n      \"id\": 501,\n      \"name\": \"Acme Widget - Blue\",\n      \"sku\": \"WIDGET-BLUE\",\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 452\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-05-20T09:12:44.000000Z\",\n    \"mapped_sku\": \"WIDGET-BLUE\",\n    \"json_object\": {\n      \"ItemID\": \"110552983245\",\n      \"Title\": \"Acme Widget - Blue\",\n      \"PictureDetails\": {\n        \"GalleryURL\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\"\n      }\n    },\n    \"image_url\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\",\n    \"ItemID\": \"110552983245\",\n    \"SKU\": \"WIDGET-BLUE\",\n    \"ListingDuration\": \"GTC\",\n    \"ListingType\": \"FixedPriceItem\",\n    \"Title\": \"Acme Widget - Blue\",\n    \"QuantityAvailable\": 25,\n    \"CurrentPriceValue\": 19.99,\n    \"CurrentPriceCurrency\": \"USD\",\n    \"ListingStatus\": \"Active\",\n    \"BidCount\": null,\n    \"EndingReason\": null,\n    \"WatchCount\": 12,\n    \"StartTime\": \"2026-02-01T00:00:00.000Z\",\n    \"StartTimeUtc\": \"2026-02-01T00:00:00.000000Z\",\n    \"EndTime\": null,\n    \"EndTimeUtc\": null,\n    \"created_at\": \"2026-02-01T00:05:00.000000Z\",\n    \"updated_at\": \"2026-07-05T00:05:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Orders for eBay Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"List eBay orders that contain the given listing, most recent first. Returns 403 when the listing does not belong to the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9101,\n      \"integration_instance_id\": 3,\n      \"sku_sales_order\": {\n        \"id\": 7788,\n        \"number\": \"SO-10234\",\n        \"order_status\": \"completed\",\n        \"fulfillment_status\": \"fulfilled\",\n        \"payment_status\": \"paid\"\n      },\n      \"json_object\": {\n        \"orderId\": \"12-34567-89012\",\n        \"buyer\": {\n          \"username\": \"acme_buyer\"\n        }\n      },\n      \"orderId\": \"12-34567-89012\",\n      \"salesRecordReference\": \"1287\",\n      \"orderPaymentStatus\": \"PAID\",\n      \"orderFulfillmentStatus\": \"FULFILLED\",\n      \"totalValue\": 45.98,\n      \"totalCurrency\": \"USD\",\n      \"totalMarketplaceFeeValue\": 5.98,\n      \"totalMarketplaceFeeCurrency\": \"USD\",\n      \"creationDateUtc\": \"2026-06-28T15:04:11.000000Z\",\n      \"lastModifiedDateUtc\": \"2026-06-29T10:11:00.000000Z\",\n      \"error_log\": null,\n      \"archived_at\": null,\n      \"created_at\": \"2026-06-28T15:10:00.000000Z\",\n      \"updated_at\": \"2026-06-29T10:12:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 10,\n  \"total\": 14,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get eBay Listing Sync Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get summary statistics about the locally-synced eBay listings for an integration instance: the most recently updated listing, total listing count, and how many listings are mapped to products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Acme Widget - Blue\",\n    \"latest_product_date\": \"2026-07-05T00:05:00.000000Z\",\n    \"total_products\": 1245,\n    \"mapped_products\": 1100,\n    \"unmapped_products\": 145\n  }\n}"}]},{"name":"Refresh eBay Listings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Queue a background refresh that re-fetches listings from eBay for this integration instance. Returns immediately; listings are updated as the queued work completes. For a refresh whose progress can be polled, use the tracked refresh endpoint instead.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be refreshed shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Start Tracked eBay Listing Refresh","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Start a tracked background refresh of listings from eBay. Returns a tracked_job_log_id whose progress can be polled while the refresh runs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 2210\n  },\n  \"message\": \"Product refresh job has been queued\",\n  \"status\": \"success\"\n}"}]},{"name":"Map eBay Listing to Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Map a single eBay listing to an existing product or subscription offering. Creates (or updates) the product listing link and automatically queues re-mapping of any historical order lines that referenced the listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (exactly one of the two is required):\n- product_id (integer): ID of the product to map to. Required without subscription_offering_id.\n- subscription_offering_id (integer): ID of the subscription offering to map to. Required without product_id.","body":{"mode":"raw","raw":"{\n  \"product_id\": 501\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8121,\n    \"integration_instance_id\": 3,\n    \"product_listing_id\": 452,\n    \"product\": {\n      \"id\": 501,\n      \"name\": \"Acme Widget - Blue\",\n      \"sku\": \"WIDGET-BLUE\",\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 452\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-05-20T09:12:44.000000Z\",\n    \"mapped_sku\": \"WIDGET-BLUE\",\n    \"json_object\": {\n      \"ItemID\": \"110552983245\",\n      \"Title\": \"Acme Widget - Blue\",\n      \"PictureDetails\": {\n        \"GalleryURL\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\"\n      }\n    },\n    \"image_url\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\",\n    \"ItemID\": \"110552983245\",\n    \"SKU\": \"WIDGET-BLUE\",\n    \"ListingDuration\": \"GTC\",\n    \"ListingType\": \"FixedPriceItem\",\n    \"Title\": \"Acme Widget - Blue\",\n    \"QuantityAvailable\": 25,\n    \"CurrentPriceValue\": 19.99,\n    \"CurrentPriceCurrency\": \"USD\",\n    \"ListingStatus\": \"Active\",\n    \"BidCount\": null,\n    \"EndingReason\": null,\n    \"WatchCount\": 12,\n    \"StartTime\": \"2026-02-01T00:00:00.000Z\",\n    \"StartTimeUtc\": \"2026-02-01T00:00:00.000000Z\",\n    \"EndTime\": null,\n    \"EndTimeUtc\": null,\n    \"created_at\": \"2026-02-01T00:05:00.000000Z\",\n    \"updated_at\": \"2026-07-05T00:05:00.000000Z\"\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap eBay Listing","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Remove the product mapping from an eBay listing. The listing itself is untouched; only the link to the product is deleted. Returns 422 when the listing is not currently mapped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8121,\n    \"integration_instance_id\": 3,\n    \"product_listing_id\": null,\n    \"product\": null,\n    \"subscription_offering\": null,\n    \"mapped_at\": null,\n    \"mapped_sku\": null,\n    \"json_object\": {\n      \"ItemID\": \"110552983245\",\n      \"Title\": \"Acme Widget - Blue\",\n      \"PictureDetails\": {\n        \"GalleryURL\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\"\n      }\n    },\n    \"image_url\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\",\n    \"ItemID\": \"110552983245\",\n    \"SKU\": \"WIDGET-BLUE\",\n    \"ListingDuration\": \"GTC\",\n    \"ListingType\": \"FixedPriceItem\",\n    \"Title\": \"Acme Widget - Blue\",\n    \"QuantityAvailable\": 25,\n    \"CurrentPriceValue\": 19.99,\n    \"CurrentPriceCurrency\": \"USD\",\n    \"ListingStatus\": \"Active\",\n    \"BidCount\": null,\n    \"EndingReason\": null,\n    \"WatchCount\": 12,\n    \"StartTime\": \"2026-02-01T00:00:00.000Z\",\n    \"StartTimeUtc\": \"2026-02-01T00:00:00.000000Z\",\n    \"EndTime\": null,\n    \"EndTimeUtc\": null,\n    \"created_at\": \"2026-02-01T00:05:00.000000Z\",\n    \"updated_at\": \"2026-07-05T00:05:00.000000Z\"\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Bulk Map eBay Listings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Map multiple eBay listings to products in one call by SKU.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- mapping (array, required, min 1): One entry per listing to map. Each entry:\n  - sales_channel_listing_id (string, required): The eBay item ID of the listing.\n  - mapped_sku (string or null): SKU of the product to map to. Pass null to leave unmapped.\n  - product_listing_id (integer, optional): Existing listing-link ID to update.\n  - subscription_offering_id (integer, optional): Map to a subscription offering instead of a product.","body":{"mode":"raw","raw":"{\n  \"mapping\": [\n    {\n      \"sales_channel_listing_id\": \"110552983245\",\n      \"mapped_sku\": \"WIDGET-BLUE\"\n    },\n    {\n      \"sales_channel_listing_id\": \"110552983299\",\n      \"mapped_sku\": \"WIDGET-RED\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\",\n  \"status\": \"success\"\n}"}]},{"name":"Import eBay Listing Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Queue a background import of listing-to-product mappings from a previously uploaded CSV file. The CSV must contain the eBay item identifier column and the SKU to map each listing to.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- original_name (string, required): The original file name of the uploaded CSV.\n- stored_name (string, required): The storage name returned by the file upload.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"ebay-mappings.csv\",\n  \"stored_name\": \"imports/tmp/ebay-mappings-8f3a.csv\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, mappings will be imported shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Create Product from eBay Listing","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Create a product from a single eBay listing and map the listing to it. If a product with the listing SKU already exists, the listing is linked to that product instead of creating a duplicate (linked_existing is true in the response). Returns 422 when the listing is already mapped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8121,\n    \"integration_instance_id\": 3,\n    \"product_listing_id\": 452,\n    \"product\": {\n      \"id\": 501,\n      \"name\": \"Acme Widget - Blue\",\n      \"sku\": \"WIDGET-BLUE\",\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 452\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-05-20T09:12:44.000000Z\",\n    \"mapped_sku\": \"WIDGET-BLUE\",\n    \"json_object\": {\n      \"ItemID\": \"110552983245\",\n      \"Title\": \"Acme Widget - Blue\",\n      \"PictureDetails\": {\n        \"GalleryURL\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\"\n      }\n    },\n    \"image_url\": \"https://i.ebayimg.com/images/g/abc/s-l500.jpg\",\n    \"ItemID\": \"110552983245\",\n    \"SKU\": \"WIDGET-BLUE\",\n    \"ListingDuration\": \"GTC\",\n    \"ListingType\": \"FixedPriceItem\",\n    \"Title\": \"Acme Widget - Blue\",\n    \"QuantityAvailable\": 25,\n    \"CurrentPriceValue\": 19.99,\n    \"CurrentPriceCurrency\": \"USD\",\n    \"ListingStatus\": \"Active\",\n    \"BidCount\": null,\n    \"EndingReason\": null,\n    \"WatchCount\": 12,\n    \"StartTime\": \"2026-02-01T00:00:00.000Z\",\n    \"StartTimeUtc\": \"2026-02-01T00:00:00.000000Z\",\n    \"EndTime\": null,\n    \"EndTimeUtc\": null,\n    \"created_at\": \"2026-02-01T00:05:00.000000Z\",\n    \"updated_at\": \"2026-07-05T00:05:00.000000Z\"\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Bulk Create Products from eBay Listings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Queue background creation of products from eBay listings. Each targeted listing that resolves to a new SKU creates a product and maps the listing to it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- create_all_products (boolean, required): When true, targets every unmapped listing on the instance.\n- ids (array of integers): Listing IDs to create products for. Required when create_all_products is false and no filters are given.\n- mappings (array, optional): Field mappings used to build the new products. Each entry: listing_field (string), sku_field (string), parsers (array).\n- initial_mapping (boolean, optional, default false).\n\nReturns 400 when a targeted listing has no SKU to build a product from.","body":{"mode":"raw","raw":"{\n  \"create_all_products\": false,\n  \"ids\": [\n    8121,\n    8122\n  ],\n  \"initial_mapping\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be created shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive eBay Listings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Archive eBay listings. Listings that have channel orders are silently skipped (use the archiveable check to find out which ones qualify first).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers): Listing IDs to target. Required unless mode is \"all\".\n- mode (string): Pass \"all\" to target every listing on the integration instance instead of an explicit ID list.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive eBay Listings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Restore previously archived eBay listings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers): Listing IDs to target. Required unless mode is \"all\".\n- mode (string): Pass \"all\" to target every listing on the integration instance instead of an explicit ID list.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products unarchived successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Check eBay Listings Archiveable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Check which eBay listings can be archived. A listing with channel orders cannot be archived; the response gives a per-listing verdict and reason.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers): Listing IDs to target. Required unless mode is \"all\".\n- mode (string): Pass \"all\" to target every listing on the integration instance instead of an explicit ID list.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8121,\n      \"archiveable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 8122,\n      \"archiveable\": false,\n      \"reason\": \"Sales Channel Product has Sales Channel Orders\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete eBay Listings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Delete eBay listing records from the local catalog, together with their product mapping links. This does not end or modify the live listing on eBay.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers): Listing IDs to target. Required unless mode is \"all\".\n- mode (string): Pass \"all\" to target every listing on the integration instance instead of an explicit ID list.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Check eBay Listings Deleteable","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Check which eBay listings can be deleted. The response gives a per-listing verdict and reason.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers): Listing IDs to target. Required unless mode is \"all\".\n- mode (string): Pass \"all\" to target every listing on the integration instance instead of an explicit ID list.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8121,\n      \"deleteable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 8122,\n      \"deleteable\": true,\n      \"reason\": false\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Sync eBay Listing Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Push current stock quantities to eBay for the given listings. Quantities are computed from the warehouses selected in the integration inventory settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers, optional): Listing IDs to sync. Omit to sync every eligible listing.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8121,\n    8122\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\",\n  \"status\": \"success\"\n}"}]},{"name":"Hydrate eBay Listing Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/hydrate-product-template","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","hydrate-product-template"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Fill an eBay listing template with values from a product. Static template fields keep their configured value; dynamic fields are evaluated against the product. Returns both the resolved field list and the generated listing payload ready for publishing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- product_id (integer, required): The product to pull values from.\n- sales_channel_product_template_id (integer, required): The listing template to hydrate.","body":{"mode":"raw","raw":"{\n  \"product_id\": 501,\n  \"sales_channel_product_template_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/hydrate-product-template","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products","hydrate-product-template"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fields\": [\n      {\n        \"name\": \"Title\",\n        \"value\": \"Acme Widget - Blue\",\n        \"data_type\": \"string\",\n        \"validation_rules\": \"required|max:80\",\n        \"sort_order\": 1\n      },\n      {\n        \"name\": \"StartPrice\",\n        \"value\": \"19.99\",\n        \"data_type\": \"decimal\",\n        \"validation_rules\": \"required\",\n        \"sort_order\": 2\n      }\n    ],\n    \"payload\": \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><AddItemRequest>...</AddItemRequest>\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get eBay Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get the field mappings used when creating products from eBay listings. Returns the built-in default mappings, any custom overrides saved for this integration instance, and the effective (merged) mapping set, along with the catalogs of available eBay listing fields and product fields.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 3,\n    \"integration_name\": \"eBay US Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      }\n    ],\n    \"available_ebay_fields\": {\n      \"title\": {\n        \"name\": \"title\",\n        \"label\": \"Product Title\",\n        \"type\": \"string\",\n        \"description\": \"eBay listing title\",\n        \"group\": \"Product Info\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      }\n    ]\n  }\n}"}]},{"name":"Update eBay Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Replace the custom field mappings for this integration instance. Each mapping pairs an eBay listing field with the product field it populates; optional parsers transform the value on the way in.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- mappings (array, required): Each entry:\n  - listing_field (string, required): eBay listing field name.\n  - sku_field (string, required): Product field to populate.\n  - parsers (array, optional): Ordered transforms, each with a rule and args.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"title\",\n      \"sku_field\": \"name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": [\n        {\n          \"rule\": \"trim\",\n          \"args\": []\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 3,\n    \"integration_name\": \"eBay US Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"Start Tracked eBay Order Refresh","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Start a tracked background refresh of orders from eBay. Returns a tracked_job_log_id whose progress can be polled while the refresh runs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional):\n- mode (string): One of latest, from_start_date, date_range, all. Defaults to latest (fetch orders updated since the last sync). from_start_date fetches all orders created since the integration start date; date_range fetches orders created between date_from and date_to; all fetches everything.\n- date_from (date): Start of the creation-date window. Required in practice when mode is date_range.\n- date_to (date): End of the creation-date window (inclusive; extends to end of day).","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 2211\n  },\n  \"message\": \"Order refresh job has been queued\",\n  \"status\": \"success\"\n}"}]},{"name":"Get eBay Order Sync Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get summary statistics about the locally-synced eBay orders for an integration instance: the most recent order, total order count, and how many are linked to sales orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"12-34567-89012\",\n    \"latest_order_date\": \"2026-06-28T15:04:11.000000Z\",\n    \"latest_order_status\": \"PAID\",\n    \"total_orders\": 5230,\n    \"with_sku_order\": 5100,\n    \"without_sku_order\": 130\n  }\n}"}]},{"name":"Refresh eBay Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Re-fetch a single order from eBay and update the local record. Returns the refreshed order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- uniqueId (string, required): The eBay order ID (e.g. 12-34567-89012).","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"12-34567-89012\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9101,\n    \"integration_instance_id\": 3,\n    \"sku_sales_order\": {\n      \"id\": 7788,\n      \"number\": \"SO-10234\",\n      \"order_status\": \"completed\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"payment_status\": \"paid\"\n    },\n    \"json_object\": {\n      \"orderId\": \"12-34567-89012\",\n      \"buyer\": {\n        \"username\": \"acme_buyer\"\n      }\n    },\n    \"orderId\": \"12-34567-89012\",\n    \"salesRecordReference\": \"1287\",\n    \"orderPaymentStatus\": \"PAID\",\n    \"orderFulfillmentStatus\": \"FULFILLED\",\n    \"totalValue\": 45.98,\n    \"totalCurrency\": \"USD\",\n    \"totalMarketplaceFeeValue\": 5.98,\n    \"totalMarketplaceFeeCurrency\": \"USD\",\n    \"creationDateUtc\": \"2026-06-28T15:04:11.000000Z\",\n    \"lastModifiedDateUtc\": \"2026-06-29T10:11:00.000000Z\",\n    \"error_log\": null,\n    \"archived_at\": null,\n    \"created_at\": \"2026-06-28T15:10:00.000000Z\",\n    \"updated_at\": \"2026-06-29T10:12:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Raw eBay Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Fetch the order directly from the eBay Fulfillment API and return the live payload as eBay serves it (not the locally cached copy). Useful for verifying what eBay currently reports for the order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- order (integer): The local eBay order record ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order\": {\n      \"orderId\": \"12-34567-89012\",\n      \"creationDate\": \"2026-06-28T15:04:11.000Z\",\n      \"orderFulfillmentStatus\": \"FULFILLED\",\n      \"orderPaymentStatus\": \"PAID\",\n      \"buyer\": {\n        \"username\": \"acme_buyer\"\n      },\n      \"pricingSummary\": {\n        \"total\": {\n          \"value\": \"45.98\",\n          \"currency\": \"USD\"\n        }\n      },\n      \"lineItems\": [\n        {\n          \"lineItemId\": \"10045678901234\",\n          \"legacyItemId\": \"110552983245\",\n          \"sku\": \"WIDGET-BLUE\",\n          \"title\": \"Acme Widget - Blue\",\n          \"quantity\": 2\n        }\n      ]\n    }\n  },\n  \"fetched_at\": \"2026-07-06T18:30:00+00:00\"\n}"}]},{"name":"List eBay Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"List the audit history of a single eBay order, most recent first. Each entry describes an event, the changed attributes, and who (or what) caused it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters:\n- filter[search]: matches the causer name, event name, or recorded properties."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"EbayOrder\",\n      \"subject_id\": 9101,\n      \"properties\": {\n        \"attributes\": {\n          \"orderFulfillmentStatus\": \"FULFILLED\"\n        },\n        \"old\": {\n          \"orderFulfillmentStatus\": \"IN_PROGRESS\"\n        },\n        \"source\": \"sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-29T10:11:02.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log?page=2\",\n  \"path\": \"{{base_url}}/api/ebay/3/orders/9101/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 6\n}"}]},{"name":"Archive eBay Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Archive an eBay order record. Archived orders are excluded from listings and bulk operations by default. Returns whether the order was newly archived (archived: false means it was already archived).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive eBay Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Restore an archived eBay order record. Returns whether the order was newly restored (unarchived: false means it was already active).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"order","value":"501","description":"Order ID"}]},"description":"Retrieve a single Ebay order by its database ID. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"order","value":"501","description":"Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"integration_instance_id\": 42,\n    \"orderId\": \"12-34567-89012\",\n    \"legacyOrderId\": \"987654321\",\n    \"creationDateUtc\": \"2024-06-01T14:00:00.000Z\",\n    \"lastModifiedDateUtc\": \"2024-06-02T09:00:00.000Z\",\n    \"orderPaymentStatus\": \"PAID\",\n    \"orderFulfillmentStatus\": \"NOT_STARTED\",\n    \"totalValue\": 49.99,\n    \"totalCurrency\": \"USD\",\n    \"salesRecordReference\": \"SR-001\",\n    \"totalMarketplaceFeeValue\": 2.5,\n    \"totalMarketplaceFeeCurrency\": \"USD\",\n    \"json_object\": {\n      \"orderId\": \"12-34567-89012\",\n      \"buyer\": {\n        \"buyerRegistrationAddress\": {\n          \"fullName\": \"John Doe\"\n        }\n      },\n      \"pricingSummary\": {\n        \"total\": {\n          \"value\": \"49.99\",\n          \"currency\": \"USD\"\n        }\n      }\n    },\n    \"archived_at\": null,\n    \"created_at\": \"2024-06-01T14:00:00.000Z\",\n    \"updated_at\": \"2024-06-02T09:00:00.000Z\"\n  }\n}"}]},{"name":"Delete eBay Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Delete a single eBay order record from the local store. This does not affect the order on eBay, and any linked sales order is not removed by this call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order deleted successfully\"\n}"}]},{"name":"Delete Linked Sales Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Delete the sales order linked to an eBay order, keeping the eBay order record itself. Optionally archives the eBay order afterwards so it will not be re-created by order automation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- archive_order (boolean, default false): Archive the eBay order after deleting the linked sales order."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully and eBay order archived\",\n  \"archived_order\": true\n}"}]},{"name":"Bulk Delete eBay Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Delete multiple eBay order records from the local store in one call. Orders on eBay are unaffected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers, required): Local eBay order record IDs to delete.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    9101,\n    9102,\n    9103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders deleted successfully\",\n  \"count\": 3\n}"}]},{"name":"List Pre-Start-Date eBay Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders?created_at_min=2025-11-01","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-11-01","description":"Start of creation-date window (required, before inventory start date)","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Query eBay live for orders created before the account inventory start date, within a creation-date window. Returns lightweight order data with per-order eligibility flags so eligible orders can be selected for import. An inventory start date must be configured before using this endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- created_at_min (date, required): Start of the creation-date window. Must be before the inventory start date.\n- created_at_max (date, optional): End of the window. Must be before the inventory start date; defaults to the day before the inventory start date.\n- fulfillment_status (string, optional): One of NOT_STARTED, IN_PROGRESS, FULFILLED, any.\n\nUp to 2000 orders are scanned per query."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders?created_at_min=2025-11-01","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-11-01","description":"Start of creation-date window (required, before inventory start date)","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"ebay_order_id\": \"12-34567-89012\",\n      \"name\": \"1287\",\n      \"buyer_username\": \"acme_buyer\",\n      \"created_at\": \"2025-12-15T10:22:00.000Z\",\n      \"fulfillment_status\": \"FULFILLED\",\n      \"payment_status\": \"PAID\",\n      \"total_price\": \"45.98\",\n      \"currency\": \"USD\",\n      \"fulfillments\": [\n        {\n          \"id\": 0,\n          \"created_at\": null,\n          \"status\": \"SHIP_TO\",\n          \"tracking_number\": null\n        }\n      ],\n      \"line_items\": [\n        {\n          \"title\": \"Acme Widget - Blue\",\n          \"sku\": \"WIDGET-BLUE\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"19.99\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 12,\n    \"eligible_count\": 10,\n    \"already_imported_count\": 2\n  }\n}"}]},{"name":"Search Pre-Start-Date eBay Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders/search?search_by=ebay_order_id&search_term=12-34567-89012","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"ebay_order_id","description":"order_id, ebay_order_id, or buyer_username (required)","disabled":true},{"key":"search_term","value":"12-34567-89012","description":"Value to search for (required)","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Search eBay live for specific pre-start-date orders by order ID or buyer username. Returns the same shape as the windowed query, filtered to orders created before the inventory start date.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- search_by (string, required): One of order_id, ebay_order_id, buyer_username.\n- search_term (string, required, max 255): The value to search for. Buyer-username search scans up to one year of orders before the inventory start date and matches partial usernames."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders/search?search_by=ebay_order_id&search_term=12-34567-89012","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"ebay_order_id","description":"order_id, ebay_order_id, or buyer_username (required)","disabled":true},{"key":"search_term","value":"12-34567-89012","description":"Value to search for (required)","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"ebay_order_id\": \"12-34567-89012\",\n      \"name\": \"1287\",\n      \"buyer_username\": \"acme_buyer\",\n      \"created_at\": \"2025-12-15T10:22:00.000Z\",\n      \"fulfillment_status\": \"FULFILLED\",\n      \"payment_status\": \"PAID\",\n      \"total_price\": \"45.98\",\n      \"currency\": \"USD\",\n      \"fulfillments\": [\n        {\n          \"id\": 0,\n          \"created_at\": null,\n          \"status\": \"SHIP_TO\",\n          \"tracking_number\": null\n        }\n      ],\n      \"line_items\": [\n        {\n          \"title\": \"Acme Widget - Blue\",\n          \"sku\": \"WIDGET-BLUE\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"19.99\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date eBay Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Import selected pre-start-date orders from eBay. Each order is fetched with its own throttled API call, so the import runs as a queued background job rather than synchronously. Downloads the full order data for each ID and stores it locally; orders that already exist locally, were cancelled, or cannot be found on eBay are skipped with a per-order reason. Returns a tracked_job_log_id whose progress can be polled while the import runs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ebay_order_ids (array of strings, required, 1-10000 items): eBay order IDs to import.\n\nReturns 422 if the inventory start date has not been set.","body":{"mode":"raw","raw":"{\n  \"ebay_order_ids\": [\n    \"12-34567-89012\",\n    \"12-34567-89013\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 2212\n  },\n  \"message\": \"Importing 2 pre-start-date orders — track progress in the job tray.\"\n}"}]},{"name":"List eBay Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"List fulfilled shipments for sales orders that originated from this eBay integration, most recent first. Each row includes its eBay submission state (sync_status: submitted or pending).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters:\n- filter[search]: matches tracking number or sales order number.\n- filter[sync_status]: submitted (already pushed to eBay) or pending (not yet pushed).\n- filter[fulfillment_type]: fulfillment type (e.g. warehouse, dropship).\n- filter[date_from] / filter[date_to] (Y-m-d): fulfilled-at date range.\n- filter[warehouse_id]: fulfilling warehouse ID.\n\nAllowed sorts: id, fulfilled_at, created_at, submitted_to_sales_channel_at. Prefix with - for descending. Default sort: -id."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3312,\n      \"fulfillment_number\": \"F-10234-1\",\n      \"fulfillment_type\": \"warehouse\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"9400111899223197428490\",\n      \"cost\": 7.45,\n      \"fulfilled_at\": \"2026-07-01T16:20:00+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-07-01T16:21:03+00:00\",\n      \"carrier\": \"USPS\",\n      \"sales_order\": {\n        \"id\": 7788,\n        \"sales_order_number\": \"SO-10234\"\n      },\n      \"ebay_order\": {\n        \"id\": 9101,\n        \"orderId\": \"12-34567-89012\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/ebay/3/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{base_url}}/api/ebay/3/fulfillments?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/fulfillments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/fulfillments?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/ebay/3/fulfillments?page=2\",\n  \"path\": \"{{base_url}}/api/ebay/3/fulfillments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 48\n}"}]},{"name":"List Pending eBay Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"List fulfilled shipments that are waiting to be submitted to eBay (not yet pushed, order not cancelled, and not pickup-type). These are the fulfillments the automatic sync will submit next.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters:\n- filter[search]: matches tracking number or sales order number."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3312,\n      \"fulfillment_number\": \"F-10234-1\",\n      \"fulfillment_type\": \"warehouse\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"9400111899223197428490\",\n      \"cost\": 7.45,\n      \"fulfilled_at\": \"2026-07-01T16:20:00+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-07-01T16:21:03+00:00\",\n      \"carrier\": \"USPS\",\n      \"sales_order\": {\n        \"id\": 7788,\n        \"sales_order_number\": \"SO-10234\"\n      },\n      \"ebay_order\": {\n        \"id\": 9101,\n        \"orderId\": \"12-34567-89012\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/ebay/3/fulfillments/pending?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/ebay/3/fulfillments/pending?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/fulfillments/pending?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/fulfillments/pending?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/ebay/3/fulfillments/pending?page=2\",\n  \"path\": \"{{base_url}}/api/ebay/3/fulfillments/pending\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 4\n}"}]},{"name":"Get eBay Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get fulfillment submission statistics for the integration instance: how many fulfillments are pending submission to eBay and the automatic submission schedule.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_sync_count\": 4,\n    \"sync_schedule\": {\n      \"interval\": 10,\n      \"unit\": \"minutes\",\n      \"description\": \"Fulfillments are automatically synced every 10 minutes\"\n    }\n  }\n}"}]},{"name":"Submit eBay Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"","description":"The sales order fulfillment ID."}]},"description":"Submit a single fulfillment to eBay, uploading its tracking number and carrier so the buyer is notified. The fulfillment must be in fulfilled status and not yet submitted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- salesOrderFulfillment (integer): The fulfillment ID to submit."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"","description":"The sales order fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Fulfillment #F-10234-1 submitted successfully\"\n}"}]},{"name":"Bulk Submit eBay Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Submit multiple fulfillments to eBay in one call. Fulfillments that are already submitted, cancelled, or pickup-type are skipped. The response reports per-fulfillment failures.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers, required): Fulfillment IDs to submit.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3312,\n    3313\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": false,\n  \"data\": {\n    \"submitted\": 1,\n    \"failed\": 1\n  },\n  \"errors\": [\n    {\n      \"id\": 3313,\n      \"message\": \"Sales order is not linked to an eBay order\"\n    }\n  ],\n  \"message\": \"1 fulfillment(s) submitted, 1 failed\"\n}"}]},{"name":"Submit All Pending eBay Fulfillments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Submit every pending fulfillment for this integration instance to eBay. Equivalent to bulk-submitting the full pending list.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 4,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"4 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"Submit Sales Order Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Submit a sales order fulfillment to eBay by ID, uploading its tracking information. Body-based alternative to the path-based submit endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- sales_order_fulfillment_id (integer, required): The fulfillment ID to submit.","body":{"mode":"raw","raw":"{\n  \"sales_order_fulfillment_id\": 3312\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\",\n  \"status\": \"success\"\n}"}]},{"name":"List eBay Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"List the inventory comparison for this eBay integration: one row per mapped listing, showing the locally computed quantity (sku_quantity), the quantity eBay currently reports (sales_channel_quantity), the variance, and a sync status of synced, variance, or needs_recalc. eBay has a single stock pool, so every row belongs to one synthetic location whose ID equals the integration instance ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters:\n- filter[search]: matches listing SKU, listing title, product SKU, or offering name/SKU.\n- filter[status] (or status.is / status.is_one_of / status.is_not): synced, variance, or needs_recalc.\n- Operator filters use the form filter[column.operator]=value. Numeric operators (sku_quantity, sales_channel_quantity): is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty. Text operators (listing_sku, title, location_id): contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty. Date operators (sales_channel_quantity_updated_at, sales_channel_quantity_synced_at, created_at, updated_at): is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, past_week, past_month, past_year, days_ago, past_days. A bare filter[column]=value acts as an implicit \"is\".\n\nAllowed sorts: id, sku_quantity, sales_channel_quantity, created_at, updated_at. Default sort: -id."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5521,\n      \"product_listing_id\": 452,\n      \"document_id\": 8121,\n      \"listing_sku\": \"WIDGET-BLUE\",\n      \"title\": \"Acme Widget - Blue\",\n      \"product\": {\n        \"id\": 501,\n        \"sku\": \"WIDGET-BLUE\",\n        \"name\": \"Acme Widget - Blue\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": 3,\n      \"location_name\": \"eBay Store\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 25,\n      \"sales_channel_quantity\": 23,\n      \"variance\": 2,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-07-06T02:00:00+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-07-06T02:05:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-07-05T02:05:00+00:00\",\n      \"created_at\": \"2026-03-01T00:00:00+00:00\",\n      \"updated_at\": \"2026-07-06T02:05:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/ebay/3/inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 82,\n  \"last_page_url\": \"{{base_url}}/api/ebay/3/inventory?page=82\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{base_url}}/api/ebay/3/inventory?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{base_url}}/api/ebay/3/inventory?page=2\",\n  \"path\": \"{{base_url}}/api/ebay/3/inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 812\n}"}]},{"name":"Get eBay Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get aggregate inventory-sync statistics for the integration instance: total tracked listings, how many are in sync with eBay, how many have a quantity variance, how many need local recalculation, and the timestamps of the last live fetch and the last push to eBay.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 812,\n    \"in_sync\": 640,\n    \"with_variance\": 152,\n    \"needs_recalculation\": 20,\n    \"last_fetch_at\": \"2026-07-06T02:05:00.000000Z\",\n    \"last_sync_at\": \"2026-07-05T02:05:00.000000Z\"\n  }\n}"}]},{"name":"List eBay Inventory Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"List inventory locations for this integration. eBay has no multi-location inventory, so this always returns a single synthetic location whose ID equals the integration instance ID; it exists so eBay responses share the same shape as multi-location channels.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"eBay Store\",\n      \"is_active\": true\n    }\n  ]\n}"}]},{"name":"Start eBay Inventory Recache","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Start a tracked background job that recalculates the local (SKU.io side) quantities for every mapped listing on this integration. Run this when local quantities are flagged as needing recalculation. Returns a tracked_job_log_id to poll for progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 2210\n  }\n}"}]},{"name":"Get eBay Inventory Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]},"description":"Get the progress of a previously started inventory recache job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- trackedJobLogId (integer): The tracked_job_log_id returned when the job was started."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2210,\n    \"job_type\": \"ebay\",\n    \"queue\": \"default\",\n    \"job_name\": \"Recache eBay Inventory: eBay US Store\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 3,\n      \"type\": \"integration_instance\",\n      \"reference\": \"eBay US Store\"\n    },\n    \"related_model_reference\": \"eBay US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-07-06T18:20:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-07-06T18:20:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:20:30.000000Z\",\n    \"results\": null,\n    \"total_items\": 120,\n    \"processed_items\": 45,\n    \"progress_percentage\": 37.5,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Start eBay Inventory Sync","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Start a tracked background job that pushes local quantities to eBay for every mapped listing on this integration. Returns a tracked_job_log_id to poll for progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 2211\n  }\n}"}]},{"name":"Get eBay Inventory Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]},"description":"Get the progress of a previously started inventory sync job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- trackedJobLogId (integer): The tracked_job_log_id returned when the job was started."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2210,\n    \"job_type\": \"ebay\",\n    \"queue\": \"default\",\n    \"job_name\": \"Sync eBay Inventory: eBay US Store\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 3,\n      \"type\": \"integration_instance\",\n      \"reference\": \"eBay US Store\"\n    },\n    \"related_model_reference\": \"eBay US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-07-06T18:20:01.000000Z\",\n    \"completed_at\": \"2026-07-06T18:26:40.000000Z\",\n    \"duration\": 399,\n    \"created_at\": \"2026-07-06T18:20:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:20:30.000000Z\",\n    \"results\": null,\n    \"total_items\": 120,\n    \"processed_items\": 120,\n    \"progress_percentage\": 100,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Start eBay Live Inventory Fetch","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Start a tracked background job that fetches current live quantities from eBay and stores them for comparison against local quantities. Returns a tracked_job_log_id to poll for progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetch live inventory job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 2212\n  }\n}"}]},{"name":"Get eBay Live Inventory Fetch Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]},"description":"Get the progress of a previously started live inventory fetch job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameters:\n- integrationInstance (integer): The eBay integration instance ID.\n- trackedJobLogId (integer): The tracked_job_log_id returned when the job was started."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2210,\n    \"job_type\": \"ebay\",\n    \"queue\": \"default\",\n    \"job_name\": \"Fetch Live eBay Inventory: eBay US Store\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 3,\n      \"type\": \"integration_instance\",\n      \"reference\": \"eBay US Store\"\n    },\n    \"related_model_reference\": \"eBay US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-07-06T18:20:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-07-06T18:20:00.000000Z\",\n    \"updated_at\": \"2026-07-06T18:20:30.000000Z\",\n    \"results\": null,\n    \"total_items\": 120,\n    \"processed_items\": 45,\n    \"progress_percentage\": 37.5,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/integration-instances?page=1&limit=25","host":["{{baseUrl}}"],"path":["api","ebay","integration-instances"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true}]},"description":"List all Ebay integration instances with standard list query parameters. Requires Bearer token.\n\nSupports query params: page, limit, search, sort, archived, included[], excluded[]."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/integration-instances?page=1&limit=25","host":["{{baseUrl}}"],"path":["api","ebay","integration-instances"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"name\": \"My Ebay Store\",\n      \"integration_id\": 1,\n      \"is_automatic_sync_enabled\": false,\n      \"created_at\": \"2024-01-15T10:00:00.000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000Z\"\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 25,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"List Legacy Products (Integration)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true}],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"List all Ebay legacy product listings (the eBay listings grid) for a specific integration instance. Uses Spatie QueryBuilder — filters use the bracket format (filter[key]=value).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nArchived listings are hidden by default; send filter[archived] (or an archived condition inside filter_groups) to surface them.\n\nAuthentication: Requires Bearer token.\n\nQuery params: page, per_page (default 10), filter[search], filter[mapping_status] (mapped|unmapped), filter[ListingStatus], filter[ListingType], filter[archived], filter_groups (base64-encoded advanced filter tree), sort (default -id).\n\nResponse is a standard Laravel paginator (top-level data, current_page, last_page, per_page, total, links, etc.)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true}],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 101,\n      \"integration_instance_id\": 42,\n      \"ItemID\": \"123456789012\",\n      \"SKU\": \"PROD-001\",\n      \"Title\": \"Blue Widget - 10 Pack\",\n      \"ListingType\": \"FixedPriceItem\",\n      \"ListingStatus\": \"Active\",\n      \"QuantityAvailable\": 50,\n      \"CurrentPriceValue\": 24.99,\n      \"CurrentPriceCurrency\": \"USD\",\n      \"BidCount\": \"0\",\n      \"EndingReason\": null,\n      \"WatchCount\": 3,\n      \"StartTimeUtc\": \"2024-01-01T00:00:00.000Z\",\n      \"EndTimeUtc\": \"2024-07-01T00:00:00.000Z\",\n      \"json_object\": null,\n      \"created_at\": \"2024-01-01T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-15T08:30:00.000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/ebay/42/legacy-products?page=1\",\n  \"from\": 1,\n  \"last_page\": 15,\n  \"last_page_url\": \"https://example.sku.io/api/ebay/42/legacy-products?page=15\",\n  \"links\": [],\n  \"next_page_url\": \"https://example.sku.io/api/ebay/42/legacy-products?page=2\",\n  \"path\": \"https://example.sku.io/api/ebay/42/legacy-products\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 150\n}"}]},{"name":"Show Legacy Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]},"description":"Retrieve a single Ebay legacy product listing. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 42,\n    \"ItemID\": \"123456789012\",\n    \"SKU\": \"PROD-001\",\n    \"Title\": \"Blue Widget - 10 Pack\",\n    \"ListingType\": \"FixedPriceItem\",\n    \"ListingStatus\": \"Active\",\n    \"QuantityAvailable\": 50,\n    \"CurrentPriceValue\": 24.99,\n    \"CurrentPriceCurrency\": \"USD\",\n    \"BidCount\": \"0\",\n    \"EndingReason\": null,\n    \"WatchCount\": 3,\n    \"StartTimeUtc\": \"2024-01-01T00:00:00.000Z\",\n    \"EndTimeUtc\": \"2024-07-01T00:00:00.000Z\",\n    \"json_object\": {\n      \"ItemID\": \"123456789012\",\n      \"SKU\": \"PROD-001\"\n    },\n    \"created_at\": \"2024-01-01T00:00:00.000Z\",\n    \"updated_at\": \"2024-06-15T08:30:00.000Z\"\n  }\n}"}]},{"name":"Update Legacy Product","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]},"description":"Update an existing Ebay legacy product listing. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"SKU\": \"PROD-001-UPDATED\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 42,\n    \"ItemID\": \"123456789012\",\n    \"SKU\": \"PROD-001-UPDATED\",\n    \"Title\": \"Blue Widget - 10 Pack\",\n    \"ListingStatus\": \"Active\",\n    \"updated_at\": \"2024-06-20T09:00:00.000Z\"\n  }\n}"}]},{"name":"Delete Legacy Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]},"description":"Delete an Ebay legacy product listing. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/{product}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products",":product"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"},{"key":"product","value":"101","description":"Legacy product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Product deleted\"\n}"}]},{"name":"Create SKU Products from Listings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/create-sku-products","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Create SKU.io products from selected Ebay listings. Returns 400 if a listing is missing a SKU. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"overwrite\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/create-sku-products","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 3,\n    \"skipped\": 0\n  },\n  \"message\": \"Products created successfully\"\n}"}]},{"name":"Refresh Legacy Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","refresh"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Queue a job to refresh all legacy product listings from the Ebay API. Returns a tracked job log ID for progress monitoring. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","refresh"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 789\n  },\n  \"message\": \"Refresh job queued\"\n}"}]},{"name":"Map Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","map"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Map Ebay legacy listings to SKU.io products. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_product_id\": 101,\n      \"product_id\": 55\n    },\n    {\n      \"sales_channel_product_id\": 102,\n      \"product_id\": 56\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/map","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","map"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products mapped successfully\"\n}"}]},{"name":"Smart Match Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"42","description":"eBay integration instance ID"},{"key":"product","value":"1","description":"eBay legacy product ID"}]},"description":"Find suggested SKU product matches for a single eBay listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMatching strategy:\n- exact_match: SKU product whose sku == ebay_product.SKU\n- barcode_match: always null (eBay legacy products do not expose a UPC/barcode field)\n- similar_matches: up to 5 fuzzy matches by Title / SKU tokens\n\nArchived SKU products are excluded. Used by the listing detail page mapping modal.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"42","description":"eBay integration instance ID"},{"key":"product","value":"1","description":"eBay legacy product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 55,\n      \"sku\": \"EBAY-WIDGET-L\",\n      \"name\": \"Widget Large\",\n      \"barcode\": 12345678905,\n      \"price\": 19.99,\n      \"type\": \"simple\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 56,\n        \"sku\": \"EBAY-WIDGET-M\",\n        \"name\": \"Widget Medium\",\n        \"barcode\": 12345678912,\n        \"price\": 14.99,\n        \"type\": \"simple\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Raw Product from eBay","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"42","description":"eBay integration instance ID"},{"key":"product","value":"10","description":"eBay legacy product ID"}]},"description":"Fetch the raw eBay GetItem response for a single listing, live from eBay's Trading API. Powers the \"Load Raw Data from eBay\" button on the listing detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe data is not persisted — it reflects the live eBay state.\n\nReturns 403 if the product doesn't belong to the given integration instance. Returns 500 if eBay's API call fails (e.g. credentials not configured).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"42","description":"eBay integration instance ID"},{"key":"product","value":"10","description":"eBay legacy product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"ItemID\": \"254620010010\",\n      \"SKU\": \"EBY-NOTEBOOK-A5\",\n      \"Title\": \"Hardcover Lined Notebook A5 — Set of 2\",\n      \"ListingType\": \"FixedPriceItem\",\n      \"ListingStatus\": \"Active\",\n      \"QuantityAvailable\": 20,\n      \"CurrentPriceValue\": 11,\n      \"CurrentPriceCurrency\": \"USD\"\n    }\n  }\n}"}]},{"name":"Export Legacy Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/export","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","export"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Export all legacy product listings for an integration instance as a file download. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse: File download (CSV or Excel format)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/export","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","export"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,ItemID,SKU,Title,ListingStatus,CurrentPriceValue\n101,123456789012,PROD-001,Blue Widget,Active,24.99"}]},{"name":"Archive Legacy Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","archive"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Archive selected Ebay legacy product listings. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","archive"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived\"\n}"}]},{"name":"Unarchive Legacy Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","unarchive"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Unarchive selected Ebay legacy product listings. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","unarchive"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products unarchived\"\n}"}]},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/archiveable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","archiveable"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Check which of the given listings can be archived. Returns lists of archiveable and non-archiveable products. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/archiveable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","archiveable"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"archiveable\": [\n      101,\n      102\n    ],\n    \"not_archiveable\": [\n      103\n    ]\n  }\n}"}]},{"name":"Delete Legacy Products (Bulk)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","delete"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Bulk delete selected Ebay legacy product listings. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/delete","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","delete"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products deleted\"\n}"}]},{"name":"Check Deleteable Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/deleteable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","deleteable"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Check which of the given listings can be deleted (not linked to any Ebay orders). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/deleteable","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","deleteable"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleteable\": [\n      101,\n      102\n    ],\n    \"not_deleteable\": {\n      \"103\": \"Currently used by 2 Ebay Order(s)\"\n    }\n  }\n}"}]},{"name":"Import Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/import-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","import-mappings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Import field mapping configuration for linking Ebay listing fields to SKU.io product fields. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"SKU\",\n      \"sku_field\": \"sku\"\n    },\n    {\n      \"listing_field\": \"Title\",\n      \"sku_field\": \"item_name\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/import-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","import-mappings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Mappings imported successfully\"\n}"}]},{"name":"Sync Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/sync-inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Push current SKU.io inventory quantities to Ebay listings. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/sync-inventory","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"synced\": 45,\n    \"failed\": 0\n  },\n  \"message\": \"Inventory synced\"\n}"}]},{"name":"Hydrate Product Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/hydrate-product-template","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","hydrate-product-template"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Hydrate an Ebay listing template with data from a SKU.io product. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 55\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/hydrate-product-template","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","hydrate-product-template"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"Title\": \"Blue Widget - 10 Pack\",\n    \"SKU\": \"PROD-001\",\n    \"CurrentPriceValue\": 24.99,\n    \"CurrentPriceCurrency\": \"USD\"\n  }\n}"}]},{"name":"Get Suggested Categories","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/get-suggested-categories","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","get-suggested-categories"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Get Ebay category suggestions for a product query using the Ebay Taxonomy API. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- query (required, string): Search term for category suggestions\n- marketplace_id (required, string): Ebay marketplace ID. Valid values: EBAY_US, EBAY_GB, EBAY_AU, EBAY_CA, EBAY_DE, EBAY_FR, EBAY_IT, EBAY_ES","body":{"mode":"raw","raw":"{\n  \"query\": \"blue widget electronics\",\n  \"marketplace_id\": \"EBAY_US\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/get-suggested-categories","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","get-suggested-categories"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"category\": {\n        \"categoryId\": \"58058\",\n        \"categoryName\": \"Consumer Electronics\"\n      },\n      \"categoryTreeNodeLevel\": 1,\n      \"relevancy\": \"HIGH\"\n    },\n    {\n      \"category\": {\n        \"categoryId\": \"9355\",\n        \"categoryName\": \"Cell Phones & Accessories\"\n      },\n      \"categoryTreeNodeLevel\": 2,\n      \"relevancy\": \"MEDIUM\"\n    }\n  ]\n}"}]},{"name":"Build Payload","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/build-payload","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","build-payload"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Build the Ebay listing payload for one or more SKU.io products. Used to preview the data that will be sent to Ebay before publishing. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/build-payload","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","build-payload"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"55\": {\n      \"Title\": \"Blue Widget - 10 Pack\",\n      \"SKU\": \"PROD-001\",\n      \"StartPrice\": \"24.99\",\n      \"Currency\": \"USD\",\n      \"Quantity\": 50\n    }\n  }\n}"}]},{"name":"Publish Listings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/publish","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","publish"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Publish SKU.io products as new Ebay listings. Returns 400 if Ebay returns a bad request error. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/legacy-products/publish","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","legacy-products","publish"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"published\": 2,\n    \"failed\": 0\n  },\n  \"message\": \"Listings published successfully\"\n}"}]},{"name":"List Orders (Integration)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders?page=1&limit=25","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"List all Ebay orders for a specific integration instance with standard list query parameters. Returns paginated results.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSupports query params: page, limit, search, sort, archived, included[], excluded[], table_specifications."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders?page=1&limit=25","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true}],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"integration_instance_id\": 42,\n      \"orderId\": \"12-34567-89012\",\n      \"legacyOrderId\": \"987654321\",\n      \"creationDate\": \"2024-06-01T14:00:00.000Z\",\n      \"creationDateUtc\": \"2024-06-01T14:00:00.000Z\",\n      \"lastModifiedDate\": \"2024-06-02T09:00:00.000Z\",\n      \"lastModifiedDateUtc\": \"2024-06-02T09:00:00.000Z\",\n      \"orderPaymentStatus\": \"PAID\",\n      \"orderFulfillmentStatus\": \"NOT_STARTED\",\n      \"totalValue\": 49.99,\n      \"totalCurrency\": \"USD\",\n      \"salesRecordReference\": \"SR-001\",\n      \"totalMarketplaceFeeValue\": 2.5,\n      \"totalMarketplaceFeeCurrency\": \"USD\",\n      \"archived_at\": null,\n      \"created_at\": \"2024-06-01T14:00:00.000Z\",\n      \"updated_at\": \"2024-06-02T09:00:00.000Z\"\n    }\n  ],\n  \"total\": 320,\n  \"per_page\": 25,\n  \"current_page\": 1,\n  \"last_page\": 13\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Queue a job to refresh all orders from the Ebay API. Returns a tracked job log ID for progress monitoring. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 790\n  },\n  \"message\": \"Refresh job queued\"\n}"}]},{"name":"Create SKU Orders from Ebay","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Create SKU.io sales orders from selected Ebay orders. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"order_ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 3,\n    \"skipped\": 0\n  },\n  \"message\": \"SKU orders created successfully\"\n}"}]},{"name":"Export Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/export","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","export"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Export all Ebay orders for an integration instance as a file download. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse: File download (CSV or Excel format)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/export","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","export"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,orderId,legacyOrderId,orderPaymentStatus,orderFulfillmentStatus,totalValue,totalCurrency\n501,12-34567-89012,987654321,PAID,NOT_STARTED,49.99,USD"}]},{"name":"Bulk Archive eBay Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Archive multiple eBay orders in one request.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array of integers, required) — eBay order local DB IDs to archive. Orders belonging to other integration instances are ignored.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders archived successfully\",\n  \"archived_count\": 2\n}"}]},{"name":"Bulk Unarchive eBay Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Unarchive multiple eBay orders in one request.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array of integers, required) — eBay order local DB IDs to unarchive. Orders belonging to other integration instances are ignored.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders unarchived successfully\",\n  \"unarchived_count\": 2\n}"}]},{"name":"Update SKU Orders from Channel Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Update existing SKU orders from eBay channel orders. Accepts {ids} or {update_all_orders: true, filters?: &lt;canonical filter object>} - filters scope the update to the grid's matching orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    60,\n    61\n  ],\n  \"update_all_orders\": false,\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Product Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay-product-settings?product_id=55","host":["{{baseUrl}}"],"path":["api","ebay-product-settings"],"query":[{"key":"product_id","value":"55","description":"Required. The SKU.io product ID to get settings for.","disabled":true}]},"description":"Retrieve Ebay product settings for a specific SKU.io product. Returns all Ebay-specific settings (e.g., auction-until-sold configuration) for the product across all integration instances. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- product_id (required, integer): SKU.io product ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay-product-settings?product_id=55","host":["{{baseUrl}}"],"path":["api","ebay-product-settings"],"query":[{"key":"product_id","value":"55","description":"Required. The SKU.io product ID to get settings for.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"id\": 10,\n    \"integration_instance_id\": 42,\n    \"product_id\": 55,\n    \"auction_until_sold_enabled\": true,\n    \"auction_until_sold_price_reduction_percentage\": 5,\n    \"auction_until_sold_minimum_price\": 9.99\n  }\n]"}]},{"name":"Save Product Settings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay-product-settings","host":["{{baseUrl}}"],"path":["api","ebay-product-settings"]},"description":"Create or update Ebay product settings for a SKU.io product. Upserts by product_id and integration_instance_id. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- id (optional, integer): Setting ID for updates\n- integration_instance_id (required, integer): Ebay integration instance ID\n- product_id (required, integer): SKU.io product ID\n- auction_until_sold_enabled (required, boolean): Enable auction-until-sold feature\n- auction_until_sold_price_reduction_percentage (required, float): Price reduction % for re-listing\n- auction_until_sold_minimum_price (required, float): Minimum price floor for auction-until-sold","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 42,\n  \"product_id\": 55,\n  \"auction_until_sold_enabled\": true,\n  \"auction_until_sold_price_reduction_percentage\": 5,\n  \"auction_until_sold_minimum_price\": 9.99\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay-product-settings","host":["{{baseUrl}}"],"path":["api","ebay-product-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"null"}]},{"name":"Get Blemished Auto-List Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/blemished-auto-list-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","blemished-auto-list-settings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Get the blemished auto-list configuration for an eBay integration instance. When a return is dispositioned as a new blemished SKU and its inventory lands, an enabled configuration automatically lists that SKU on eBay as an auction-until-sold listing using the selected default template. Returns default values when no configuration has been saved yet. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/blemished-auto-list-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","blemished-auto-list-settings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 42,\n    \"enabled\": true,\n    \"sales_channel_product_template_id\": 3,\n    \"sales_channel_product_template_name\": \"Blemished Auction\",\n    \"ebay_site_id\": 0,\n    \"starting_price_discount_percentage\": 30,\n    \"auction_until_sold_enabled\": true,\n    \"auction_until_sold_price_reduction_percentage\": 10,\n    \"auction_until_sold_minimum_price_percentage\": 50,\n    \"updated_at\": \"2026-07-11T05:26:53.000000Z\"\n  }\n}"}]},{"name":"Update Blemished Auto-List Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/blemished-auto-list-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","blemished-auto-list-settings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]},"description":"Create or update the blemished auto-list configuration for an eBay integration instance. Requires Bearer token.\n\nBody fields:\n- enabled (boolean, required): master switch for automatic listing of new blemished SKUs.\n- sales_channel_product_template_id (integer, required when enabled): default listing template. Its ListingType must be an auction (Chinese) template.\n- ebay_site_id (integer, required): eBay site. 0 = United States, 100 = eBay Motors.\n- starting_price_discount_percentage (number, optional, 0-99): markdown applied to the template start price (e.g. 30 lists at 70% of the template price). Omit to use the template price as-is.\n- auction_until_sold_enabled (boolean, required): whether auto-listed items relist until sold.\n- auction_until_sold_price_reduction_percentage (number, optional, 0-99): price reduction applied on each relist.\n- auction_until_sold_minimum_price_percentage (number, optional, 0-100): floor as a percentage of the start price.\n\nReturns 422 if enabling without a template, or if the selected template is not an auction template.","body":{"mode":"raw","raw":"{\n  \"enabled\": true,\n  \"sales_channel_product_template_id\": 3,\n  \"ebay_site_id\": 0,\n  \"starting_price_discount_percentage\": 30,\n  \"auction_until_sold_enabled\": true,\n  \"auction_until_sold_price_reduction_percentage\": 10,\n  \"auction_until_sold_minimum_price_percentage\": 50\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/blemished-auto-list-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","blemished-auto-list-settings"],"variable":[{"key":"integrationInstance","value":"42","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 42,\n    \"enabled\": true,\n    \"sales_channel_product_template_id\": 3,\n    \"sales_channel_product_template_name\": \"Blemished Auction\",\n    \"ebay_site_id\": 0,\n    \"starting_price_discount_percentage\": 30,\n    \"auction_until_sold_enabled\": true,\n    \"auction_until_sold_price_reduction_percentage\": 10,\n    \"auction_until_sold_minimum_price_percentage\": 50,\n    \"updated_at\": \"2026-07-11T05:26:53.000000Z\"\n  }\n}"}]},{"name":"Uncovered Blemished Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay-global-reports/uncovered-blemished-products","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","uncovered-blemished-products"]},"description":"Get a list of blemished/refurbished products that do not have an active Ebay listing covering them. Used for identifying inventory gaps in Ebay auction-until-sold programs. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay-global-reports/uncovered-blemished-products","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","uncovered-blemished-products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 55,\n      \"sku\": \"PROD-001-B\",\n      \"name\": \"Blue Widget (Blemished)\",\n      \"quantity_available\": 12,\n      \"ebay_listings\": []\n    },\n    {\n      \"product_id\": 56,\n      \"sku\": \"PROD-002-B\",\n      \"name\": \"Red Widget (Blemished)\",\n      \"quantity_available\": 5,\n      \"ebay_listings\": []\n    }\n  ]\n}"}]},{"name":"Listed Blemished Products Out of Stock","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay-global-reports/listed-blemished-products-out-of-stock","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","listed-blemished-products-out-of-stock"]},"description":"Get blemished products that currently have active Ebay listings but are out of stock. Useful for identifying listings that should be ended or revised due to zero inventory. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay-global-reports/listed-blemished-products-out-of-stock","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","listed-blemished-products-out-of-stock"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 60,\n      \"sku\": \"PROD-005-B\",\n      \"name\": \"Green Widget (Blemished)\",\n      \"quantity_available\": 0,\n      \"ebay_listings\": [\n        {\n          \"ItemID\": \"999888777666\",\n          \"Title\": \"Green Widget Blemished\",\n          \"ListingStatus\": \"Active\",\n          \"QuantityAvailable\": 1\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"List Blemished Auto-List eBay Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay-global-reports/blemished-auto-list-instances","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","blemished-auto-list-instances"]},"description":"Return the eBay integration instances that have blemished auto-listing enabled. Use this to determine which instance a blemished product should be listed on before calling Auto-List Blemished Products. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay-global-reports/blemished-auto-list-instances","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","blemished-auto-list-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 42,\n      \"name\": \"eBay US\"\n    }\n  ]\n}"}]},{"name":"Auto-List Blemished Products on eBay","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay-global-reports/uncovered-blemished-products/list","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","uncovered-blemished-products","list"]},"description":"Queue auto-listing of the given blemished products on an eBay integration instance that has blemished auto-listing enabled. Each product is listed as an auction-until-sold listing; products that are already listed, out of stock, or not blemished are skipped. Processing runs in the background and the response returns an id for tracking progress. Requires Bearer token.\n\nBody fields:\n- product_ids (array of integers, required, max 100): blemished product ids to list. Larger sets must be listed in batches of 100.\n- integration_instance_id (integer, required): the eBay instance to list on. Must have blemished auto-listing enabled.\n\nReturns 422 if the instance does not have blemished auto-listing enabled.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56\n  ],\n  \"integration_instance_id\": 42\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay-global-reports/uncovered-blemished-products/list","host":["{{baseUrl}}"],"path":["api","ebay-global-reports","uncovered-blemished-products","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9931,\n    \"queued_count\": 2\n  }\n}"}]},{"name":"List Payouts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns a paginated list of eBay Managed Payments payouts synced for the integration instance. Each payout includes the settlement amount, a normalized summary split (sales, refunds, fees, shipping labels, charges, disputes, adjustments, and net), the accounting status, and the number of transaction lines.\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: status, currency, accounting_status (text), amount (numeric), payout_date (date), created_at (datetime). filter[search] matches the payout ID and currency.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric), and is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, days_ago, past_days (date/datetime). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, legacy_resource_id, payout_date, amount, status, accounting_status (prefix with - for descending; default -payout_date). Pagination defaults to 10 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 12,\n      \"legacy_resource_id\": \"5f4a8d90-1c7b-4f2e-9b3a-2d8e6f0a1b23\",\n      \"payout_date\": \"2026-07-10\",\n      \"status\": \"succeeded\",\n      \"currency\": \"USD\",\n      \"amount\": 1842.55,\n      \"summary\": {\n        \"sales_gross\": 2010.4,\n        \"refunds_gross\": -95,\n        \"fees_total\": -61.15,\n        \"shipping_labels\": -11.7,\n        \"charges\": 0,\n        \"disputes\": 0,\n        \"adjustments\": 0,\n        \"net\": 1842.55\n      },\n      \"accounting_status\": \"pending\",\n      \"transaction_count\": 46,\n      \"ebay_created_at\": \"2026-07-10T04:02:11+00:00\",\n      \"created_at\": \"2026-07-10T06:15:42+00:00\",\n      \"updated_at\": \"2026-07-11T06:15:40+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payouts?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payouts?page=3\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payouts?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/ebay/1/payouts\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 27\n}"}]},{"name":"Get Payout Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/filter-options","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns the available filter values for the payouts list: every payout status and accounting status the system recognises, plus the settlement currencies present in the synced payouts for the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/filter-options","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"statuses\": [\n      \"initiated\",\n      \"retryable_failed\",\n      \"terminal_failed\",\n      \"reversed\",\n      \"succeeded\",\n      \"funds_on_hold\",\n      \"pending\"\n    ],\n    \"accounting_statuses\": [\n      \"pending\",\n      \"ready\",\n      \"posted\",\n      \"held\",\n      \"error\"\n    ],\n    \"currencies\": [\n      \"GBP\",\n      \"USD\"\n    ]\n  }\n}"}]},{"name":"Sync Payouts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Queues a background sync that imports eBay Managed Payments payouts and their transaction lines from eBay for the integration instance. Returns a tracked_job_log_id that can be used to monitor the progress of the sync.\n\nThe request body is optional. With no body, the sync runs the default incremental (cursor-based) window. Supply mode to control the range: latest (incremental, default), from_start_date (from the instance start date to now), date_range (bounded by date_from/date_to), or all (full backfill). date_from and date_to are Y-m-d dates and apply when mode is date_range (date_to must be on or after date_from).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4431\n  },\n  \"message\": \"Payout sync job has been queued\"\n}"}]},{"name":"Get Payout","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/{payout}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts",":payout"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payout","value":"12","description":"Payout ID"}]},"description":"Returns the full detail of a single payout, including the raw summary breakdown, the payout instrument, and every transaction line with its per-fee breakdown and linked local order where resolved. Returns 403 if the payout does not belong to the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payouts/{payout}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payouts",":payout"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payout","value":"12","description":"Payout ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"legacy_resource_id\": \"5f4a8d90-1c7b-4f2e-9b3a-2d8e6f0a1b23\",\n    \"payout_date\": \"2026-07-10\",\n    \"status\": \"succeeded\",\n    \"currency\": \"USD\",\n    \"amount\": 1842.55,\n    \"summary\": {\n      \"sales_gross\": 2010.4,\n      \"refunds_gross\": -95,\n      \"fees_total\": -61.15,\n      \"shipping_labels\": -11.7,\n      \"charges\": 0,\n      \"disputes\": 0,\n      \"adjustments\": 0,\n      \"net\": 1842.55\n    },\n    \"summary_json\": {\n      \"sales_gross\": 2010.4,\n      \"refunds_gross\": -95,\n      \"fees_total\": -61.15,\n      \"shipping_labels\": -11.7\n    },\n    \"accounting_status\": \"pending\",\n    \"base_currency_rate\": null,\n    \"payout_instrument\": \"Bank account ****6789\",\n    \"receipt_json\": null,\n    \"ebay_created_at\": \"2026-07-10T04:02:11+00:00\",\n    \"ebay_updated_at\": \"2026-07-10T09:30:00+00:00\",\n    \"created_at\": \"2026-07-10T06:15:42+00:00\",\n    \"updated_at\": \"2026-07-11T06:15:40+00:00\",\n    \"transactions\": [\n      {\n        \"id\": 501,\n        \"legacy_transaction_id\": \"9911-0288-4471\",\n        \"ebay_payout_id\": 12,\n        \"transaction_type\": \"sale\",\n        \"booking_entry\": \"CREDIT\",\n        \"financial_code\": \"sale\",\n        \"amount\": 129.99,\n        \"total_fee_amount\": 17.06,\n        \"fees_json\": [\n          {\n            \"feeType\": \"final_value_fee\",\n            \"amount\": 15.79\n          },\n          {\n            \"feeType\": \"international_fee\",\n            \"amount\": 1.27\n          }\n        ],\n        \"memo\": null,\n        \"status\": \"FUNDS_AVAILABLE_FOR_PAYOUT\",\n        \"ebay_order_id\": 845,\n        \"order\": {\n          \"id\": 845,\n          \"order_id\": \"12-08765-43210\",\n          \"link_reference\": \"12-08765-43210\",\n          \"link_type_label\": \"eBay Order\",\n          \"link_id\": 845\n        },\n        \"created_at\": \"2026-07-10T06:15:43+00:00\",\n        \"updated_at\": \"2026-07-10T06:15:43+00:00\"\n      },\n      {\n        \"id\": 502,\n        \"legacy_transaction_id\": \"9911-0288-4472\",\n        \"ebay_payout_id\": 12,\n        \"transaction_type\": \"non_sale_charge\",\n        \"booking_entry\": \"DEBIT\",\n        \"financial_code\": \"non_sale_charge: international-fee\",\n        \"amount\": -11.7,\n        \"total_fee_amount\": 0,\n        \"fees_json\": null,\n        \"memo\": \"International fee\",\n        \"status\": \"FUNDS_AVAILABLE_FOR_PAYOUT\",\n        \"ebay_order_id\": null,\n        \"created_at\": \"2026-07-10T06:15:43+00:00\",\n        \"updated_at\": \"2026-07-10T06:15:43+00:00\"\n      }\n    ],\n    \"transaction_count\": 2,\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"My eBay Store\",\n      \"country\": \"US\"\n    }\n  }\n}"}]},{"name":"List Payout Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-transactions","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns a paginated list of eBay Managed Payments payout transaction lines across every payout synced for the integration instance — the line-level detail behind the payout summaries. Each line includes its transaction type, financial code, booking entry (CREDIT/DEBIT), gross amount, total fee amount, an itemized fee breakdown (fees_json), status, and cross-link blocks for the parent payout and (when matched) the eBay order.\n\nAuthentication: Requires Bearer token.\n\nFilters: filter[search] matches the internal ID, eBay transaction ID, financial code, memo, or linked order (eBay order ID or internal order ID). filter[financial_code], filter[transaction_type], filter[booking_entry], filter[ebay_payout_id], and filter[id] are exact-match filters.\n\nAllowed sorts: id, amount, total_fee_amount, created_at (prefix with - for descending; default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-transactions","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 8815,\n      \"legacy_transaction_id\": \"9d2f1c40-5b7a-4e2c-8f3d-1a2b3c4d5e6f\",\n      \"ebay_payout_id\": 12,\n      \"transaction_type\": \"SALE\",\n      \"booking_entry\": \"CREDIT\",\n      \"financial_code\": \"sale\",\n      \"amount\": 84.5,\n      \"total_fee_amount\": 11.02,\n      \"fees_json\": [\n        {\n          \"feeType\": \"FINAL_VALUE_FEE_FIXED_PER_ORDER\",\n          \"amount\": 0.4\n        },\n        {\n          \"feeType\": \"FINAL_VALUE_FEE_VARIABLE_PER_ORDER\",\n          \"amount\": 10.62\n        }\n      ],\n      \"transaction_memo\": null,\n      \"transaction_status\": \"FUNDS_AVAILABLE_FOR_PAYOUT\",\n      \"memo\": null,\n      \"status\": \"FUNDS_AVAILABLE_FOR_PAYOUT\",\n      \"ebay_order_id\": 5521,\n      \"payout\": {\n        \"ebay_payout_id\": 12,\n        \"legacy_resource_id\": \"5f4a8d90-1c7b-4f2e-9b3a-2d8e6f0a1b23\",\n        \"payout_date\": \"2026-07-10\",\n        \"link_reference\": \"5f4a8d90-1c7b-4f2e-9b3a-2d8e6f0a1b23\",\n        \"link_type_label\": \"eBay Payout\",\n        \"link_id\": 12,\n        \"link_route\": \"/integrations/ebay/finance/payout/12\"\n      },\n      \"order\": {\n        \"id\": 5521,\n        \"order_id\": \"12-34567-89012\",\n        \"link_reference\": \"12-34567-89012\",\n        \"link_type_label\": \"eBay Order\",\n        \"link_id\": 5521,\n        \"link_route\": \"/integrations/ebay/orders/5521\"\n      },\n      \"created_at\": \"2026-07-10T06:15:42+00:00\",\n      \"updated_at\": \"2026-07-10T06:15:42+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-transactions?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-transactions?page=5\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-transactions?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-transactions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 68\n}"}]},{"name":"Get Payout Transaction Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-transactions/filter-options","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-transactions","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns the distinct filter values present in the synced payout transactions for the integration instance: every transaction type and every financial code, so a client can populate the transaction filters.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-transactions/filter-options","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-transactions","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"transaction_types\": [\n      \"NON_SALE_CHARGE\",\n      \"REFUND\",\n      \"SALE\",\n      \"SHIPPING_LABEL\"\n    ],\n    \"financial_codes\": [\n      \"refund\",\n      \"sale\",\n      \"shipping_label\"\n    ]\n  }\n}"}]},{"name":"List Global Payout Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups"]},"description":"Returns every global (workspace-wide) payout mapping group, ordered by sort order. Global groups apply to all eBay integration instances unless an instance defines its own groups. If no global groups exist yet, the two defaults (eBay Sales as an invoice group and eBay Fees as a bill group) are created and returned.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_instance_id\": null,\n      \"name\": \"eBay Sales\",\n      \"document_type\": \"invoice\",\n      \"sort_order\": 0,\n      \"mappings_count\": 7,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"integration_instance_id\": null,\n      \"name\": \"eBay Fees\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 1,\n      \"mappings_count\": 3,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Global Payout Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups"]},"description":"Creates a global payout mapping group that applies to every eBay integration instance. Type mappings assigned to the group are combined into a single financial document of the group's document type when a payout is posted.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Marketplace Charges\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 3,\n  \"integration_instance_id\": null,\n  \"name\": \"Marketplace Charges\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2,\n  \"created_at\": \"2026-07-17T11:20:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:20:00.000000Z\"\n}"}]},{"name":"Reorder Global Payout Mapping Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups","reorder"]},"description":"Reorders the global payout mapping groups. Pass the full list of global group IDs in the desired order; each group's sort order is updated to match its position in the list.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): mapping group IDs in the desired display order. Each ID must reference an existing payout mapping group.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups","reorder"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Groups reordered successfully.\"\n}"}]},{"name":"Update Global Payout Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Updates the name, document type, or sort order of a global payout mapping group.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"eBay Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"integration_instance_id\": null,\n  \"name\": \"eBay Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0,\n  \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:45:00.000000Z\"\n}"}]},{"name":"Delete Global Payout Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Deletes a global payout mapping group. Type mappings that referenced the group are kept but left without a group assignment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Payout Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns the payout mapping groups visible to the integration instance: the instance's own groups first, followed by the global groups. If no global groups exist yet, the two defaults (eBay Sales as an invoice group and eBay Fees as a bill group) are created first.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"integration_instance_id\": 1,\n      \"name\": \"US Store Charges\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 0,\n      \"mappings_count\": 2,\n      \"created_at\": \"2026-07-17T10:12:00.000000Z\",\n      \"updated_at\": \"2026-07-17T10:12:00.000000Z\"\n    },\n    {\n      \"id\": 1,\n      \"integration_instance_id\": null,\n      \"name\": \"eBay Sales\",\n      \"document_type\": \"invoice\",\n      \"sort_order\": 0,\n      \"mappings_count\": 7,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"integration_instance_id\": null,\n      \"name\": \"eBay Fees\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 1,\n      \"mappings_count\": 3,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Payout Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Creates a payout mapping group scoped to the integration instance. Instance groups are listed ahead of the global defaults and can be used to separate the instance's payout lines into their own financial documents.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Marketplace Charges\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 6,\n  \"integration_instance_id\": 1,\n  \"name\": \"Marketplace Charges\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2,\n  \"created_at\": \"2026-07-17T11:20:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:20:00.000000Z\"\n}"}]},{"name":"Reorder Payout Mapping Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Reorders the payout mapping groups scoped to the integration instance. Pass the full list of the instance's group IDs in the desired order; each group's sort order is updated to match its position in the list. Global groups are not affected.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): mapping group IDs in the desired display order. Each ID must reference an existing payout mapping group.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Groups reordered successfully.\"\n}"}]},{"name":"Update Payout Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Updates the name, document type, or sort order of a payout mapping group scoped to the integration instance.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"eBay Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 5,\n  \"integration_instance_id\": 1,\n  \"name\": \"eBay Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0,\n  \"created_at\": \"2026-07-17T10:12:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:45:00.000000Z\"\n}"}]},{"name":"Delete Payout Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Deletes a payout mapping group scoped to the integration instance. Type mappings that referenced the group are kept but left without a group assignment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Payout Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns the resolved payout type mappings for the integration instance: per-instance override rows plus the global default rows they have not overridden. Each row maps a financial code (a normalized transaction type, expanded with its memo for non-sale charges) to a general-ledger account and an optional mapping group; is_override indicates an instance-specific row. eBay payout transactions carry no separate source type, so source_type is typically empty and the reason is taken from the transaction memo. Before listing, any financial codes newly seen in the instance's synced payout transactions are registered as unmapped global rows so they can be configured.\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: type, source_type, reason, financial_code, typical_amount_sign, mapping_status (mapped/unmapped), group_status (assigned/unassigned) (text), created_at, updated_at (datetime). filter[search] matches type, source type, reason, and financial code.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric), and is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, days_ago, past_days (date/datetime). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: type, source_type, financial_code, created_at (prefix with - for descending; default financial_code). Pagination defaults to 10 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 7,\n      \"integration_instance_id\": 1,\n      \"type\": \"sale\",\n      \"source_type\": null,\n      \"reason\": null,\n      \"financial_code\": \"sale\",\n      \"typical_amount_sign\": \"positive\",\n      \"ebay_payout_mapping_group_id\": 1,\n      \"nominalCode\": {\n        \"id\": 210,\n        \"code\": \"4000\",\n        \"name\": \"Sales Revenue\"\n      },\n      \"mappingGroup\": {\n        \"id\": 1,\n        \"name\": \"eBay Sales\",\n        \"document_type\": \"invoice\"\n      },\n      \"is_override\": true,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:05:00.000000Z\"\n    },\n    {\n      \"id\": 3,\n      \"integration_instance_id\": null,\n      \"type\": \"non_sale_charge\",\n      \"source_type\": null,\n      \"reason\": \"International fee\",\n      \"financial_code\": \"non_sale_charge: international-fee\",\n      \"typical_amount_sign\": \"negative\",\n      \"ebay_payout_mapping_group_id\": null,\n      \"nominalCode\": null,\n      \"mappingGroup\": null,\n      \"is_override\": false,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-type-mappings?page=1\",\n  \"from\": 1,\n  \"last_page\": 2,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-type-mappings?page=2\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-type-mappings?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/ebay/1/payout-type-mappings\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 14\n}"}]},{"name":"Update Payout Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Updates individual payout type mappings, assigning or clearing the general-ledger account and mapping group of each. Fields omitted from a mapping entry are left unchanged; pass null to clear an assignment.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- mappings (required, array, min 1): mapping updates to apply.\n- mappings[].id (required, integer): ID of an existing payout type mapping that is global or belongs to this integration instance.\n- mappings[].nominal_code_id (optional, nullable, integer): general-ledger account to assign; must reference an existing account. Pass null to clear.\n- mappings[].ebay_payout_mapping_group_id (optional, nullable, integer): payout mapping group to assign; must reference an existing group that is global or belongs to this instance. Pass null to clear.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"id\": 7,\n      \"nominal_code_id\": 210,\n      \"ebay_payout_mapping_group_id\": 1\n    },\n    {\n      \"id\": 3,\n      \"nominal_code_id\": 305\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payout type mappings updated successfully.\"\n}"}]},{"name":"Bulk Assign Payout Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Assigns a general-ledger account and/or a mapping group to several payout type mappings at once. At least one of nominal_code_id or ebay_payout_mapping_group_id must be provided; pass null to clear that assignment on all selected mappings. Only mappings scoped to the integration instance are updated - global rows are not modified.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): payout type mapping IDs to update. Each ID must reference an existing payout type mapping.\n- nominal_code_id (optional, nullable, integer): general-ledger account to assign to all selected mappings; must reference an existing account.\n- ebay_payout_mapping_group_id (optional, nullable, integer): payout mapping group to assign to all selected mappings; must reference an existing group that is global or belongs to this instance.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    7,\n    9\n  ],\n  \"nominal_code_id\": 210,\n  \"ebay_payout_mapping_group_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3\n  },\n  \"message\": \"3 type mapping(s) updated successfully.\"\n}"}]},{"name":"Get Payout Finance Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Returns the resolved payout finance settings for the integration instance: the fallback revenue and expense accounts used for unmapped payout lines, the clearing account payouts settle against, the accounting sync mode (per_order or per_payout; default per_order), and the optional payout accounting start date before which payouts are not posted. Fallback and clearing accounts fall back to the workspace-wide values when the instance has none of its own.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}"}]},{"name":"Update Payout Finance Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]},"description":"Updates the payout finance settings for the integration instance. All fields are optional; omitted fields keep their current values, and nullable fields can be set to null to clear them. Returns the resolved settings after the update.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- fallback_revenue_nominal_code_id (optional, nullable, integer): account for unmapped revenue lines; must reference an existing general-ledger account.\n- fallback_expense_nominal_code_id (optional, nullable, integer): account for unmapped expense lines; must reference an existing general-ledger account.\n- clearing_nominal_code_id (optional, nullable, integer): clearing account that payout documents settle against; must reference an existing general-ledger account.\n- accounting_sync_mode (optional, string): one of per_order, per_payout.\n- payout_accounting_start_date (optional, nullable, date): payouts dated before this are not posted to accounting.","body":{"mode":"raw","raw":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/ebay/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","ebay",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"eBay integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}"}]}]},{"name":"Faire","item":[{"name":"List Faire Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances","host":["{{baseUrl}}"],"path":["api","faire","instances"]},"description":"List all Faire integration instances for this account.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:**\nReturns a collection of Faire integration instances. Each instance includes:\n- `id` - Internal instance ID\n- `name` - Display name for the instance\n- `is_active` - Whether the instance is active\n- `fulfillment_mode` - Fulfillment mode: `fbm` (fulfilled by merchant) or `fbf` (fulfilled by Faire)\n- `order_import_start_date` - Date from which orders are imported\n- `warehouse_id` - Linked internal warehouse ID\n- `last_orders_sync` - ISO timestamp of last order sync\n- `last_products_sync` - ISO timestamp of last product sync\n- `created_at` / `updated_at` - ISO timestamps"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances","host":["{{baseUrl}}"],"path":["api","faire","instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Faire Main Store\",\n      \"is_authorized\": true,\n      \"auth_method\": \"oauth\",\n      \"granted_scopes\": [\n        \"READ_PRODUCTS\",\n        \"WRITE_PRODUCTS\",\n        \"READ_ORDERS\",\n        \"WRITE_ORDERS\",\n        \"READ_BRAND\",\n        \"READ_RETAILER\",\n        \"READ_INVENTORIES\",\n        \"WRITE_INVENTORIES\",\n        \"READ_SHIPMENTS\",\n        \"READ_REVIEWS\"\n      ],\n      \"is_automatic_sync_enabled\": true,\n      \"fulfillment_mode\": \"fbm\",\n      \"order_import_start_date\": \"2024-01-01\",\n      \"auto_create_products\": false,\n      \"default_shipping_method_id\": 12,\n      \"default_shipping_method\": {\n        \"id\": 12,\n        \"method_name\": \"UPS Ground\",\n        \"full_name\": \"UPS — Ground\",\n        \"carrier_name\": \"UPS\"\n      },\n      \"inventory\": {\n        \"masterOfStock\": \"sku.io\",\n        \"selectedWarehouses\": [\n          3\n        ],\n        \"inventoryModificationRules\": null\n      },\n      \"last_orders_sync\": \"2026-04-24T10:00:00+00:00\",\n      \"last_products_sync\": \"2026-04-24T09:00:00+00:00\",\n      \"orders_count\": 142,\n      \"products_count\": 27,\n      \"created_at\": \"2026-01-15T12:00:00+00:00\",\n      \"updated_at\": \"2026-04-24T10:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Faire Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances","host":["{{baseUrl}}"],"path":["api","faire","instances"]},"description":"Create a new Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Required Fields:**\n- `name` - Display name for this instance (max 255 chars)\n- `fulfillment_mode` - `fbm` (fulfilled by merchant) or `fbf` (fulfilled by Faire)\n\n**Optional Fields:**\n- `order_import_start_date` - Only import orders created on or after this date\n- `warehouse_id` - Link to an internal warehouse for inventory and fulfillment\n\n**OAuth Authorization:**\nAfter creation, the instance is unauthorized (`is_authorized: false`). The frontend must:\n1. Call `GET /api/faire/instances/{id}/authorization-url` to obtain the Faire OAuth redirect URL.\n2. Redirect the user (who **must be a Faire brand admin**) to that URL.\n3. Faire redirects back to `GET /faire/callback`, which exchanges the authorization code for a long-lived access token and persists it.\n\n**Response:**\nReturns the created integration instance with `is_authorized: false` and `granted_scopes: []`.","body":{"mode":"raw","raw":"{\n  \"name\": \"Faire Main Store\",\n  \"fulfillment_mode\": \"fbm\",\n  \"order_import_start_date\": \"2024-01-01\",\n  \"warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances","host":["{{baseUrl}}"],"path":["api","faire","instances"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Faire Main Store\",\n    \"is_authorized\": false,\n    \"auth_method\": null,\n    \"granted_scopes\": [],\n    \"is_automatic_sync_enabled\": false,\n    \"fulfillment_mode\": \"fbm\",\n    \"order_import_start_date\": \"2024-01-01\",\n    \"auto_create_products\": false,\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"selectedWarehouses\": [],\n      \"inventoryModificationRules\": null\n    },\n    \"last_orders_sync\": null,\n    \"last_products_sync\": null,\n    \"orders_count\": 0,\n    \"products_count\": 0,\n    \"created_at\": \"2026-04-30T12:00:00+00:00\",\n    \"updated_at\": \"2026-04-30T12:00:00+00:00\"\n  }\n}"}]},{"name":"Get Faire Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Retrieve details of a specific Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Response:**\nReturns full integration instance details including sync timestamps and configuration."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Faire Main Store\",\n    \"is_authorized\": true,\n    \"auth_method\": \"oauth\",\n    \"granted_scopes\": [\n      \"READ_PRODUCTS\",\n      \"WRITE_PRODUCTS\",\n      \"READ_ORDERS\",\n      \"WRITE_ORDERS\",\n      \"READ_BRAND\",\n      \"READ_RETAILER\",\n      \"READ_INVENTORIES\",\n      \"WRITE_INVENTORIES\",\n      \"READ_SHIPMENTS\",\n      \"READ_REVIEWS\"\n    ],\n    \"is_automatic_sync_enabled\": true,\n    \"fulfillment_mode\": \"fbm\",\n    \"order_import_start_date\": \"2024-01-01\",\n    \"auto_create_products\": false,\n    \"default_shipping_method_id\": 12,\n    \"default_shipping_method\": {\n      \"id\": 12,\n      \"method_name\": \"UPS Ground\",\n      \"full_name\": \"UPS — Ground\",\n      \"carrier_name\": \"UPS\"\n    },\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"selectedWarehouses\": [\n        3\n      ],\n      \"inventoryModificationRules\": null\n    },\n    \"last_orders_sync\": \"2026-04-24T10:00:00+00:00\",\n    \"last_products_sync\": \"2026-04-24T09:00:00+00:00\",\n    \"orders_count\": 142,\n    \"products_count\": 27,\n    \"created_at\": \"2026-01-15T12:00:00+00:00\",\n    \"updated_at\": \"2026-04-24T10:00:00+00:00\"\n  }\n}"}]},{"name":"Update Faire Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Update an existing Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Partial Updates:**\nAll fields are optional (use `sometimes` validation). Only the fields you provide will be updated:\n- `name` - New display name (max 255 chars)\n- `order_import_start_date` - New import start date (or null to remove)\n- `is_automatic_sync_enabled` - Toggle automatic background sync (boolean)\n- `auto_create_products` - Auto-create local products from Faire feed (boolean)\n- `default_shipping_method_id` - ID of the shipping method applied to every sales order imported from Faire. Faire never provides a shipping method on its orders, so this default is used for all imports. Pass `null` to clear the default. The response includes a hydrated `default_shipping_method` object (id, method_name, full_name, carrier_name) when set.\n- `inventory.masterOfStock` - `sku.io` or `Neither`\n- `inventory.selectedWarehouses[]` - Array of warehouse IDs whose stock contributes to the Faire inventory feed\n- `inventory.inventoryModificationRules` - Min/max/buffer rules for the published inventory quantities\n- `financial_line_type_overrides` - Optional object overriding the FinancialLineType used for the Faire-specific lines created on each imported order. All keys are optional; pass `null` to clear an override. **Classification is enforced** on each branch — see below:\n  - `commission` - FinancialLineType ID (must be a `cost` type). Applied to the marketplace fee Faire deducts on each order. Default branch creates/uses `Faire Commission` (cost).\n  - `payout_fee` - FinancialLineType ID (must be a `cost` type). Applied to the per-payout processing fee Faire takes. Default branch creates/uses `Faire Payout Fee` (cost).\n  - `payout_protection_fee` - FinancialLineType ID (must be a `cost` type). Applied when Faire deducts a payout-protection insurance charge on an order. Default branch creates/uses `Faire Payout Protection Fee` (cost).\n  - `damaged_and_missing_items` - FinancialLineType ID (must be a `cost` type). Applied when Faire deducts an adjustment for damaged or missing items on a delivered order. Default branch creates/uses `Faire Damaged & Missing Items` (cost).\n  - `covered_shipping` - FinancialLineType ID (must be a `revenue` type). Applied when Faire reimburses shipping cost on covered orders. Default branch creates/uses `Faire-Covered Shipping` (revenue).\n  - **Validation:** Mismatched classification (e.g., a revenue type passed for `commission`) returns `422` with `errors.financial_line_type_overrides.<branch>`.\n\n**Note:** `fulfillment_mode` is fixed at creation time and ignored on update.\n\n**Response:**\nReturns the updated integration instance, including the resolved `financial_line_type_overrides` object (each branch is either `null` if no override is configured, or `{ id, name, classification }`).","body":{"mode":"raw","raw":"{\n  \"name\": \"Faire Main Store - Updated\",\n  \"order_import_start_date\": \"2024-03-01\",\n  \"is_automatic_sync_enabled\": true,\n  \"auto_create_products\": false,\n  \"default_shipping_method_id\": 12,\n  \"inventory\": {\n    \"masterOfStock\": \"sku.io\",\n    \"selectedWarehouses\": [\n      3,\n      5\n    ]\n  },\n  \"financial_line_type_overrides\": {\n    \"commission\": 12,\n    \"payout_fee\": null,\n    \"payout_protection_fee\": 14,\n    \"damaged_and_missing_items\": 15,\n    \"covered_shipping\": 17\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Faire Main Store\",\n    \"is_authorized\": true,\n    \"auth_method\": \"oauth\",\n    \"granted_scopes\": [\n      \"READ_PRODUCTS\",\n      \"WRITE_PRODUCTS\",\n      \"READ_ORDERS\",\n      \"WRITE_ORDERS\",\n      \"READ_BRAND\",\n      \"READ_RETAILER\",\n      \"READ_INVENTORIES\",\n      \"WRITE_INVENTORIES\",\n      \"READ_SHIPMENTS\",\n      \"READ_REVIEWS\"\n    ],\n    \"is_automatic_sync_enabled\": true,\n    \"fulfillment_mode\": \"fbm\",\n    \"order_import_start_date\": \"2024-01-01\",\n    \"auto_create_products\": false,\n    \"default_shipping_method_id\": 12,\n    \"default_shipping_method\": {\n      \"id\": 12,\n      \"method_name\": \"UPS Ground\",\n      \"full_name\": \"UPS — Ground\",\n      \"carrier_name\": \"UPS\"\n    },\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"selectedWarehouses\": [\n        3\n      ],\n      \"inventoryModificationRules\": null\n    },\n    \"financial_line_type_overrides\": {\n      \"commission\": {\n        \"id\": 12,\n        \"name\": \"Marketplace Commissions\",\n        \"classification\": \"cost\"\n      },\n      \"payout_fee\": null,\n      \"payout_protection_fee\": {\n        \"id\": 14,\n        \"name\": \"Marketplace Insurance\",\n        \"classification\": \"cost\"\n      },\n      \"damaged_and_missing_items\": {\n        \"id\": 15,\n        \"name\": \"Order Adjustments\",\n        \"classification\": \"cost\"\n      },\n      \"covered_shipping\": {\n        \"id\": 17,\n        \"name\": \"Shipping Income\",\n        \"classification\": \"revenue\"\n      }\n    },\n    \"last_orders_sync\": \"2026-04-24T10:00:00+00:00\",\n    \"last_products_sync\": \"2026-04-24T09:00:00+00:00\",\n    \"orders_count\": 142,\n    \"products_count\": 27,\n    \"created_at\": \"2026-01-15T12:00:00+00:00\",\n    \"updated_at\": \"2026-04-24T10:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Faire Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Delete a Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance to delete\n\n**Important:**\n- This action permanently deletes the instance and all associated data\n- Cannot be undone\n\n**Response:**\nReturns a success message."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Integration deleted successfully\"\n}"}]},{"name":"Preview Financial Line Backfill","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/financial-line-overrides/preview-backfill","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","financial-line-overrides","preview-backfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Preview how many past Faire-imported FinancialLine rows would be re-keyed if the supplied override map were applied. **Does not modify any data.**\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body:**\n- `overrides` (object, required) - Same shape as the `financial_line_type_overrides` field on the update endpoint. Each branch is optional; pass `null` to indicate \"no override\" for that branch.\n  - `commission` (int|null) - FinancialLineType ID, must be a `cost` type when supplied.\n  - `payout_fee` (int|null) - FinancialLineType ID, must be a `cost` type when supplied.\n  - `payout_protection_fee` (int|null) - FinancialLineType ID, must be a `cost` type when supplied.\n  - `damaged_and_missing_items` (int|null) - FinancialLineType ID, must be a `cost` type when supplied.\n  - `covered_shipping` (int|null) - FinancialLineType ID, must be a `revenue` type when supplied.\n\n**Validation:**\nClassification mismatch returns `422` with `errors.overrides.<branch>` — same guard as the update endpoint.\n\n**Use case:**\nThe Faire settings UI calls this when the user changes any override and presses Save, so the confirmation modal can show \"X record(s) will be backfilled\" before they decide whether to run the backfill or just save the new override forward.\n\n**Response:**\nReturns a `{ commission, payout_fee, payout_protection_fee, damaged_and_missing_items, covered_shipping, total }` object. Each number is the count of past Faire FinancialLine rows that would be re-keyed for that branch under the supplied overrides; `total` is their sum. Branches not present in the overrides map (or sent as `null`) report `0`.","body":{"mode":"raw","raw":"{\n  \"overrides\": {\n    \"commission\": 12,\n    \"payout_fee\": null,\n    \"payout_protection_fee\": 14,\n    \"damaged_and_missing_items\": 15,\n    \"covered_shipping\": 17\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/financial-line-overrides/preview-backfill","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","financial-line-overrides","preview-backfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"commission\": 142,\n    \"payout_fee\": 0,\n    \"payout_protection_fee\": 87,\n    \"damaged_and_missing_items\": 6,\n    \"covered_shipping\": 19,\n    \"total\": 254\n  }\n}"}]},{"name":"Apply Financial Line Backfill","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/financial-line-overrides/backfill","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","financial-line-overrides","backfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Re-key past Faire-imported FinancialLine rows to the override types that are **already persisted** on the integration instance. **No request body** — the overrides are read off `integration_settings.financial_line_type_overrides`, which is set via the Update Faire Instance endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Branches covered:**\n`commission`, `payout_fee`, `payout_protection_fee`, `damaged_and_missing_items` (all `cost`), `covered_shipping` (`revenue`).\n\n**Behavior per row:**\n- Updates `financial_line_type_id` to the override's ID.\n- Copies the override's `nominal_code_id` onto the row (so accounting export reflects the new mapping).\n- Does **not** change line `amount`, `currency`, or any other monetary field.\n- Branches with no override configured (or set to `null`) are skipped entirely — those past rows keep their existing default Faire types.\n\n**Typical flow:**\n1. User changes overrides in the Faire settings UI.\n2. UI calls `PUT /api/faire/instances/{id}` with the new `financial_line_type_overrides` (this also passes the classification guard).\n3. UI calls `POST .../financial-line-overrides/preview-backfill` to show the count to the user.\n4. If the user confirms, UI calls **this** endpoint to apply the change to historical rows.\n\n**Response:**\nReturns a `{ commission, payout_fee, payout_protection_fee, damaged_and_missing_items, covered_shipping, total }` object where each number is the count of rows actually updated (i.e., rows whose existing type differed from the override). `total` is the sum across branches."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/financial-line-overrides/backfill","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","financial-line-overrides","backfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"commission\": 142,\n    \"payout_fee\": 0,\n    \"payout_protection_fee\": 87,\n    \"damaged_and_missing_items\": 6,\n    \"covered_shipping\": 19,\n    \"total\": 254\n  }\n}"}]},{"name":"Get OAuth Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/oauth/config","host":["{{baseUrl}}"],"path":["api","faire","oauth","config"]},"description":"Return the public OAuth metadata used by the frontend to render the authorization flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response fields:**\n- `scopes` - Faire OAuth scopes the app requests\n- `redirect_url` - The redirect URL registered with Faire (where Faire sends users back after authorization)\n- `authorize_url` - Faire's authorization endpoint base URL\n\n**Auth:** Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/oauth/config","host":["{{baseUrl}}"],"path":["api","faire","oauth","config"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"scopes\": [\n      \"READ_PRODUCTS\",\n      \"WRITE_PRODUCTS\",\n      \"READ_ORDERS\",\n      \"WRITE_ORDERS\",\n      \"READ_BRAND\",\n      \"READ_RETAILER\",\n      \"READ_INVENTORIES\",\n      \"WRITE_INVENTORIES\",\n      \"READ_SHIPMENTS\",\n      \"READ_REVIEWS\"\n    ],\n    \"redirect_url\": \"https://app.sku.io/faire/callback\",\n    \"authorize_url\": \"https://faire.com/oauth2/authorize\"\n  }\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/authorization-url","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Generate the Faire OAuth authorization URL for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nGenerates a CSRF state token (format: `{app.url}_{instance_id}`), stores it in the user's session, and returns the fully-formed Faire authorization URL.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance to authorize\n\n**Response field:**\n- `authorization_url` - URL to redirect the user to. The user must be a Faire brand admin.\n\n**Auth:** Requires Bearer token. CSRF state is bound to the user's session, so the same session must complete the callback."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/authorization-url","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorization_url\": \"https://faire.com/oauth2/authorize?applicationId=test-app-id&scope=READ_PRODUCTS%2CWRITE_PRODUCTS%2CREAD_ORDERS%2CWRITE_ORDERS%2CREAD_BRAND%2CREAD_RETAILER%2CREAD_INVENTORIES%2CWRITE_INVENTORIES%2CREAD_SHIPMENTS%2CREAD_REVIEWS&state=https%3A%2F%2Fapp.sku.io_1&redirectUrl=https%3A%2F%2Fapp.sku.io%2Ffaire%2Fcallback\"\n  }\n}"}]},{"name":"OAuth Callback (Faire → SKU)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/faire/callback?state=https%3A%2F%2Fapp.sku.io_1&authorization_code=auth-code-123","host":["{{baseUrl}}"],"path":["faire","callback"],"query":[{"key":"state","value":"https%3A%2F%2Fapp.sku.io_1","description":"CSRF state token returned by Faire. Format: `{app.url}_{integration_instance_id}`. Must match the value stored in the session by the Get Authorization URL endpoint.","disabled":true},{"key":"authorization_code","value":"auth-code-123","description":"One-time authorization code from Faire (also accepted as `code`).","disabled":true}]},"description":"OAuth callback hit by Faire after the user authorizes the app. **Not called manually** — Faire redirects the user's browser to this URL.\n\n**Flow:**\n1. Validates the `state` parameter against the value stored in the user's session (CSRF protection).\n2. Calls Faire's token endpoint to exchange `authorization_code` for a long-lived `access_token`.\n3. Persists the access token + granted scopes on the integration instance.\n4. Redirects to `/v2/integrations/faire/{id}/dashboard` on success, or `/v2/integrations/faire/{id}/settings?oauth_error=...` on failure.\n\n**Query Parameters:**\n- `state` (required) - CSRF state, format `{app.url}_{instance_id}`\n- `authorization_code` (required, alias `code`) - One-time auth code from Faire\n\n**Auth:** Web session (no Bearer token). Faire redirects the user's browser, so the call lands on the `web` middleware group, not `auth:sanctum`.\n\n**Errors:**\n- `400 State mismatch` - The state in the request doesn't match the session\n- `404 Faire integration not found` - Instance referenced by state has been deleted\n- Redirect with `?oauth_error=...` - Token exchange failed at Faire's side"},"response":[{"name":"Found","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/faire/callback?state=https%3A%2F%2Fapp.sku.io_1&authorization_code=auth-code-123","host":["{{baseUrl}}"],"path":["faire","callback"],"query":[{"key":"state","value":"https%3A%2F%2Fapp.sku.io_1","description":"CSRF state token returned by Faire. Format: `{app.url}_{integration_instance_id}`. Must match the value stored in the session by the Get Authorization URL endpoint.","disabled":true},{"key":"authorization_code","value":"auth-code-123","description":"One-time authorization code from Faire (also accepted as `code`).","disabled":true}]}},"status":"Found","code":302,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Revoke Authorization","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/revoke","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","revoke"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Revoke the stored Faire access token both at Faire (`POST /api/external-api-oauth2/revoke`) and locally on the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAfter revocation, `is_authorized` will be `false` and `granted_scopes` will be empty. The instance must be re-authorized via the OAuth flow before it can sync again.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Auth:** Requires Bearer token.\n\n**Errors:**\n- `422` - Faire returned an error during revocation (e.g., already revoked, invalid token). The local token is still cleared."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/revoke","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","revoke"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Faire authorization revoked\"\n}"}]},{"name":"Set Access Token Manually","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/access-token","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","access-token"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Persist a Faire long-lived access token directly onto the integration instance — an alternative to the OAuth Authorization Code flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Why this exists:** Faire only allows **one live OAuth token per brand** at a time, and the brand admin app does **not** expose a way to revoke an existing OAuth token. Tenants who already have a long-lived token (e.g., issued for a previous integration) can paste it here instead of running the browser-driven OAuth flow.\n\n**What it does:**\n- Stores the token on the integration instance's `connection_settings.access_token`\n- Tags `connection_settings.auth_method = \"manual\"` so the UI and revoke flow can differentiate this from OAuth-issued tokens\n- Sets `granted_scopes` to the full default set from `config('faire.scopes')` (we cannot introspect a user-supplied token to determine its actual scopes)\n- After saving, `is_authorized` becomes `true` immediately — the instance is ready to sync\n\n**Revocation behavior:** When `auth_method = \"manual\"`, the `POST /revoke` endpoint clears the token locally without calling Faire's revoke endpoint — we did not issue this token so we have no business revoking it at Faire (the user may still be using it elsewhere).\n\n**Path Parameters:**\n- `integrationInstance` (required) - The ID of the Faire integration instance\n\n**Request Body:**\n- `access_token` (required, string, min:10, max:4096) - The Faire long-lived access token\n\n**Auth:** Requires Bearer token.\n\n**Errors:**\n- `422` - `access_token` is missing, too short (<10 chars), or longer than 4096 chars","body":{"mode":"raw","raw":"{\n  \"access_token\": \"fa_live_long_lived_token_xyz123abc456def789ghi\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/access-token","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","access-token"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Faire Main Store\",\n    \"is_authorized\": true,\n    \"auth_method\": \"manual\",\n    \"granted_scopes\": [\n      \"READ_PRODUCTS\",\n      \"WRITE_PRODUCTS\",\n      \"READ_ORDERS\",\n      \"WRITE_ORDERS\",\n      \"READ_INVENTORIES\",\n      \"WRITE_INVENTORIES\",\n      \"READ_SHIPMENTS\"\n    ],\n    \"is_automatic_sync_enabled\": true,\n    \"fulfillment_mode\": \"fbm\",\n    \"order_import_start_date\": \"2024-01-01\",\n    \"auto_create_products\": false,\n    \"default_shipping_method_id\": 12,\n    \"default_shipping_method\": {\n      \"id\": 12,\n      \"method_name\": \"UPS Ground\",\n      \"full_name\": \"UPS — Ground\",\n      \"carrier_name\": \"UPS\"\n    },\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"selectedWarehouses\": [\n        3\n      ],\n      \"inventoryModificationRules\": null\n    },\n    \"last_orders_sync\": \"2026-04-24T10:00:00+00:00\",\n    \"last_products_sync\": \"2026-04-24T09:00:00+00:00\",\n    \"orders_count\": 142,\n    \"products_count\": 27,\n    \"created_at\": \"2026-01-15T12:00:00+00:00\",\n    \"updated_at\": \"2026-05-10T08:00:00+00:00\"\n  },\n  \"message\": \"Faire access token saved\"\n}"}]},{"name":"Reuse Existing Connection","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/reuse-connection","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","reuse-connection"],"variable":[{"key":"integrationInstance","value":"2","description":"Faire integration instance ID (the new instance receiving the reused connection)"}]},"description":"Reuse the connection from another authorized Faire integration instance instead of authorizing again.\n\n**Why this exists:** Faire allows only **one live access token per brand**, and the brand portal does not let you revoke or re-issue it. When you add a second Faire integration for the same brand — typically a Fulfilled-by-Faire (FBF) integration alongside an existing Fulfilled-by-Merchant (FBM) one — authorizing again could invalidate the first integration's token. Reuse copies the existing integration's long-lived token onto this one so both work on the same Faire account.\n\n**What it does:**\n- Copies the source integration's access token and scopes onto this integration\n- Verifies the copied token against Faire before saving it (an invalid source connection is rejected, nothing is persisted)\n- Records the Faire brand so both integrations are grouped as one shared connection\n- After success, `is_authorized` becomes `true` and `auth_method` is `reused`\n\n**Requirements:** the source integration must be authorized and must have the **opposite** fulfillment mode (FBM ↔ FBF). Reusing from a same-mode integration is rejected, because one Faire account can only be one mode at a time.\n\n**Disconnecting a shared connection** clears the token from that one integration only — it does not sign the shared Faire login out, so the other integration keeps working.\n\n**Path Parameters:**\n- `integrationInstance` (required) — the integration receiving the reused connection\n\n**Request Body:**\n- `source_instance_id` (required, integer) — the authorized, opposite-mode integration to copy the connection from\n\n**Auth:** Requires Bearer token.\n\n**Errors:**\n- `422` — the source does not exist, is not authorized, is the same integration, is the same fulfillment mode, or its token failed verification with Faire","body":{"mode":"raw","raw":"{\n  \"source_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/reuse-connection","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","reuse-connection"],"variable":[{"key":"integrationInstance","value":"2","description":"Faire integration instance ID (the new instance receiving the reused connection)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"A Bar Above — FBF\",\n    \"is_authorized\": true,\n    \"auth_method\": \"reused\",\n    \"granted_scopes\": [\n      \"READ_PRODUCTS\",\n      \"WRITE_PRODUCTS\",\n      \"READ_ORDERS\",\n      \"WRITE_ORDERS\",\n      \"READ_BRAND\",\n      \"READ_INVENTORIES\"\n    ],\n    \"brand_id\": \"b_abcd1234\",\n    \"brand_name\": \"A Bar Above\",\n    \"reused_from_instance_id\": 1,\n    \"shared_connection\": true,\n    \"connection_group_member_ids\": [\n      2,\n      1\n    ],\n    \"is_automatic_sync_enabled\": false,\n    \"fulfillment_mode\": \"fbf\",\n    \"order_import_start_date\": null,\n    \"effective_order_import_start_date\": \"2026-06-23\",\n    \"auto_create_products\": false,\n    \"default_shipping_method_id\": null,\n    \"default_shipping_method\": null,\n    \"inventory\": {\n      \"auto_sync\": false\n    },\n    \"financial_line_type_overrides\": {\n      \"commission\": null,\n      \"payout_fee\": null,\n      \"payout_protection_fee\": null,\n      \"damaged_and_missing_items\": null,\n      \"covered_shipping\": null\n    },\n    \"last_orders_sync\": null,\n    \"last_products_sync\": null,\n    \"orders_count\": 0,\n    \"products_count\": 0,\n    \"created_at\": \"2026-07-23T14:05:00+00:00\",\n    \"updated_at\": \"2026-07-23T14:05:12+00:00\"\n  },\n  \"message\": \"Connection reused from A Bar Above — FBM\"\n}"}]},{"name":"Validate Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/validate-connection","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","validate-connection"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Verify this integration's stored access token against Faire and capture the brand it belongs to.\n\nCalls Faire to confirm the token is live and reads the brand name/id, which is stored on the integration. Use it to re-check a connection's health or to populate the brand before grouping two integrations that share one Faire account.\n\n**Path Parameters:**\n- `integrationInstance` (required) — the integration to verify\n\n**Auth:** Requires Bearer token.\n\n**Errors:**\n- `422` — the token could not be verified with Faire (missing, revoked, or unreachable)"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/validate-connection","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","validate-connection"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"valid\": true,\n    \"brand_id\": \"b_abcd1234\",\n    \"brand_name\": \"A Bar Above\"\n  }\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Trigger an order sync from Faire for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately\n- The job pulls all new/updated orders from the Faire API since the last sync cursor\n- **Multi-tenant safety:** Each order's top-level `is_fulfilled_by_faire` flag is compared against the instance's `fulfillment_mode` setting before persisting. FBM instances skip orders flagged `is_fulfilled_by_faire=true`; FBF instances skip orders flagged `is_fulfilled_by_faire=false`. This prevents a brand that shares an OAuth token across an FBM and FBF instance from cross-contaminating either side. The skipped count is recorded in the sync log.\n- Combined with the composite-unique constraint on `(integration_instance_id, faire_order_id)`, two sibling instances can safely sync the same brand simultaneously without stomping each other's rows.\n- Progress can be tracked via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID. Use the tracked job log endpoints to monitor completion."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 142\n  },\n  \"message\": \"Order sync started\"\n}"}]},{"name":"Sync Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-products","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Trigger a product catalog sync from Faire for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately\n- The job pulls the full product catalog from the Faire API, including product options (variants) and current inventory levels\n- **Multi-tenant safety:** Products and variants are upserted on the composite `(integration_instance_id, faire_product_id)` / `(faire_product_id, faire_variant_id)` keys, so two sibling instances on the same brand cannot stomp each other's rows.\n- Progress can be tracked via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-products","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 143\n  },\n  \"message\": \"Product sync started\"\n}"}]},{"name":"Sync Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-inventory","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]},"description":"Trigger an inventory sync to push current inventory levels to Faire for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately\n- The job reads current inventory from the linked warehouse and pushes levels to the Faire API for each product variant\n- Progress can be tracked via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/sync-inventory","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire Integration Instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 144\n  },\n  \"message\": \"Inventory sync started\"\n}"}]},{"name":"List Faire Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders","host":["{{baseUrl}}"],"path":["api","faire","orders"]},"description":"List Faire orders for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Tenant resolution (multi-instance safety):**\nBoth shapes are accepted, in priority order:\n- `filter[integration_instance_ids]` (preferred, Amazon-unified plural form; comma-separated CSV — first ID wins)\n- `filter[instance_id]` (legacy singular)\n- `?instance_id=` query string fallback\n- body `instance_id` (POST/PUT only)\n\nIf none resolve to an existing FaireIntegrationInstance the endpoint returns an empty/zeroed payload — it does NOT silently fall back to the first tenant's data.\n\n**Empty-paginator response shape** (when no instance can be resolved):\n```json\n{\n  \"current_page\": 1,\n  \"data\": [],\n  \"total\": 0,\n  \"per_page\": 15\n}\n```\n\n---\n\nList Faire orders with rich Spatie QueryBuilder filtering, sorting and pagination. Defaults to **Active** orders (excludes archived) — mirrors the Purchase Orders bottom-bar pattern. Use `filter[archived]=only` for archived rows, `filter[archived]=all` for both.\n\n**Query Parameters — Pagination & Sort:**\n- `instance_id` (optional) — Filter to a specific integration instance. Defaults to the first instance.\n- `page` (default `1`), `per_page` (default `10`)\n- `sort` — Prefix with `-` for DESC. Default `-ordered_at`. Allowed: `id`, `ordered_at`, `shipped_at`, `delivered_at`, `created_at`, `updated_at`, `total`, `subtotal`, `discount_amount`, `status`, `retailer_name`, `retailer_country_code`.\n\n**Search:**\n- `filter[search]` — AdvancedSearchFilter across `display_id`, `faire_order_id`, `retailer_name`.\n\n**Archived Toggle (default-active):**\n- `filter[archived]=` (or omitted) — Active only\n- `filter[archived]=only` — Archived only\n- `filter[archived]=all` — Both\n\n**Identity / Display:**\n- `filter[status]`, `filter[display_id]`, `filter[faire_order_id]`\n\n**Retailer:**\n- `filter[retailer_name]`, `filter[retailer_country_code]`, `filter[retailer_state]`\n\n**Money (numeric operators):**\n- `filter[total]`, `filter[subtotal]`, `filter[discount_amount]`, `filter[currency_code]`\n\n**Dates (datetime operators — `[between]`, `[gte]`, `[lte]`, `[eq]`):**\n- `filter[ordered_at]`, `filter[shipped_at]`, `filter[delivered_at]`, `filter[updated_at]`, `filter[created_at]`\n\n**Tracking:**\n- `filter[tracking_number]`, `filter[tracking_carrier]`, `filter[tracking_submission_status]` (`pending`, `submitted`, `failed`)\n\n**Boolean callbacks:**\n- `filter[has_sku_order]=true|false` — Has a linked SKU.io sales order.\n- `filter[has_unmapped_items]=true|false` — Has at least one line item without a SKU mapping.\n- `filter[pre_start_date_import]=true|false` — Order was imported via the pre-start-date flow.\n\n**Operator suffixes:** combine any text/numeric/datetime filter with operator suffixes via `filter[column][operator]=value` (e.g. `filter[status][is_one_of]=NEW,PROCESSING`, `filter[total][gte]=100`, `filter[ordered_at][between]=2026-04-01,2026-05-01`).\n\n**Response Fields per Order:**\n- `id`, `integration_instance_id`, `faire_order_id`, `display_id`, `status`\n- `retailer_id`, `retailer_name`, `retailer_state`, `retailer_country_code`\n- `subtotal`, `discount_amount`, `total`, `currency_code` (monetary fields are stored as integers in cents)\n- `ordered_at`, `shipped_at`, `delivered_at`, `archived_at`, `created_at`\n- `tracking_number`, `tracking_carrier`, `tracking_submission_status`\n- `line_items` — Loaded via eager-load (see Show Order for the full shape)\n\n**Linked SKU.io product on each line item:**\nThe per-line `sku_product_id`, `sku_product_route`, and `sku_product` fields resolve through the `FaireProductOption → ProductListing → Product` chain (matched on `faire_variant_id`). They are populated **only when the variant has been explicitly mapped** — either via the Variants Listing page \"Map\" button, Smart Match, or Bulk Map. String-based SKU matching is intentionally NOT used. A line whose `sku` happens to match a Product's `sku` but whose variant has never been mapped will return `sku_product_id: null` (\"Unlinked\" in the UI) — the same behaviour as the Shopify line item resource and the Variants Listing page itself."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/orders","host":["{{baseUrl}}"],"path":["api","faire","orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"integration_instance_id\": 1,\n      \"faire_order_id\": \"bo_abc123xyz\",\n      \"display_id\": \"FO-0001\",\n      \"status\": \"PROCESSING\",\n      \"retailer_id\": \"b_xyz789\",\n      \"retailer_name\": \"The Boutique Shop\",\n      \"retailer_state\": \"CA\",\n      \"retailer_country_code\": \"US\",\n      \"subtotal\": 15000,\n      \"discount_amount\": 0,\n      \"total\": 15000,\n      \"currency_code\": \"USD\",\n      \"ordered_at\": \"2026-04-20T08:30:00+00:00\",\n      \"shipped_at\": null,\n      \"delivered_at\": null,\n      \"tracking_number\": null,\n      \"tracking_carrier\": null,\n      \"tracking_submission_status\": null,\n      \"tracking_submitted_at\": null,\n      \"tracking_submission_error\": null,\n      \"tracking_submission_attempts\": 0,\n      \"line_items\": [\n        {\n          \"id\": 451,\n          \"faire_line_item_id\": \"li_a1b2c3d4\",\n          \"faire_product_id\": \"p_xyz123\",\n          \"faire_variant_id\": \"opt_qr789\",\n          \"sku\": \"WIDGET-RED-LG\",\n          \"name\": \"Widget — Red, Large\",\n          \"option_values\": null,\n          \"quantity\": 2,\n          \"unit_price\": 24.5,\n          \"total_price\": 49,\n          \"sku_product_id\": 89,\n          \"sku_product_route\": \"/products/89\",\n          \"sku_product\": {\n            \"id\": 89,\n            \"sku\": \"WIDGET-RED-LG\",\n            \"name\": \"Red Widget — Large\",\n            \"type\": \"standard\"\n          }\n        },\n        {\n          \"id\": 452,\n          \"faire_line_item_id\": \"li_e5f6g7h8\",\n          \"faire_product_id\": \"p_abc456\",\n          \"faire_variant_id\": \"opt_st012\",\n          \"sku\": \"FAIRE-ONLY-SKU\",\n          \"name\": \"Item not yet mapped to SKU.io\",\n          \"option_values\": null,\n          \"quantity\": 1,\n          \"unit_price\": 18,\n          \"total_price\": 18,\n          \"sku_product_id\": null,\n          \"sku_product_route\": null,\n          \"sku_product\": null\n        }\n      ],\n      \"sales_order\": {\n        \"id\": 57520,\n        \"sales_order_number\": \"FO-0001\",\n        \"order_status\": \"open\",\n        \"fulfillment_status\": \"unfulfilled\",\n        \"payment_status\": \"paid\"\n      },\n      \"created_at\": \"2026-04-20T08:32:00+00:00\",\n      \"archived_at\": null,\n      \"is_archived\": false,\n      \"faire_admin_url\": \"https://www.faire.com/brand-portal/orders/bo_abc123xyz/order-fulfilment\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Faire Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/{order}","host":["{{baseUrl}}"],"path":["api","faire","orders",":order"],"variable":[{"key":"order","value":"101","description":"Internal Faire Order ID"}]},"description":"Get details of a specific Faire order including its line items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `order` — The internal Faire order ID (`faire_orders.id`)\n\n**Response:**\nReturns the full FaireOrderDetail (Faire order object on show) including `raw_data`, `sales_order`, `is_archived`, `archived_at`, `faire_admin_url`, and the `line_items` array. Each line item includes:\n- `id`, `faire_line_item_id`, `faire_product_id`, `faire_variant_id` — Faire-side identifiers\n- `sku`, `name`, `option_values` — Product details from Faire\n- `quantity`, `unit_price`, `total_price`\n- `sku_product_id` — The matched SKU.io `products.id` (null when the variant is unmapped)\n- `sku_product_route` — application UI route path to the matched product (null when unmapped)\n- `sku_product` — Mapped SKU.io product block `{ id, sku, name, type }` for the \"Linked Product\" column on the order detail page (null when unmapped). Mirrors the Shopify line-item shape.\n\n**Linked product resolution:** All three `sku_product*` fields are resolved via the explicit `FaireProductOption → ProductListing → Product` chain (joined on `faire_variant_id`), populated by the Variants Listing page \"Map\" button / Smart Match / Bulk Map. String-based SKU matching is NOT used. If a variant has never been mapped, the fields are null even when the line’s `sku` happens to match a Product’s `sku` — same behaviour as the Shopify order line resource.\n\n**Error Responses:**\n- `404 Not Found` — Order not found"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/orders/{order}","host":["{{baseUrl}}"],"path":["api","faire","orders",":order"],"variable":[{"key":"order","value":"101","description":"Internal Faire Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 1,\n    \"faire_order_id\": \"bo_abc123xyz\",\n    \"display_id\": \"FO-0001\",\n    \"status\": \"PROCESSING\",\n    \"retailer_id\": \"b_xyz789\",\n    \"retailer_name\": \"The Boutique Shop\",\n    \"retailer_state\": \"CA\",\n    \"retailer_country_code\": \"US\",\n    \"subtotal\": 15000,\n    \"discount_amount\": 0,\n    \"total\": 15000,\n    \"currency_code\": \"USD\",\n    \"ordered_at\": \"2026-04-20T08:30:00+00:00\",\n    \"shipped_at\": null,\n    \"delivered_at\": null,\n    \"tracking_number\": null,\n    \"tracking_carrier\": null,\n    \"tracking_submission_status\": null,\n    \"tracking_submitted_at\": null,\n    \"tracking_submission_error\": null,\n    \"tracking_submission_attempts\": 0,\n    \"raw_data\": {\n      \"id\": \"bo_abc123xyz\",\n      \"state\": \"PROCESSING\",\n      \"items\": []\n    },\n    \"line_items\": [\n      {\n        \"id\": 451,\n        \"faire_line_item_id\": \"li_a1b2c3d4\",\n        \"faire_product_id\": \"p_xyz123\",\n        \"faire_variant_id\": \"opt_qr789\",\n        \"sku\": \"WIDGET-RED-LG\",\n        \"name\": \"Widget — Red, Large\",\n        \"option_values\": null,\n        \"quantity\": 2,\n        \"unit_price\": 24.5,\n        \"total_price\": 49,\n        \"sku_product_id\": 89,\n        \"sku_product_route\": \"/products/89\",\n        \"sku_product\": {\n          \"id\": 89,\n          \"sku\": \"WIDGET-RED-LG\",\n          \"name\": \"Red Widget — Large\",\n          \"type\": \"standard\"\n        }\n      }\n    ],\n    \"sales_order\": {\n      \"id\": 57520,\n      \"sales_order_number\": \"FO-0001\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"payment_status\": \"paid\"\n    },\n    \"created_at\": \"2026-04-20T08:32:00+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false,\n    \"faire_admin_url\": \"https://www.faire.com/brand-portal/orders/bo_abc123xyz/order-fulfilment\"\n  }\n}"}]},{"name":"Refetch Order from Faire","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/refetch","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","refetch"],"variable":[{"key":"order","value":"101","description":"Faire order ID (DB primary key)"}]},"description":"Re-fetch the order from the Faire API. Updates local data and (if a linked SKU sales order exists) refreshes the SKU sales order to mirror Faire's latest state. Returns the updated Faire order object (with line_items, sales_order, faire_admin_url).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Linked SKU.io product on line items:** The `sku_product_id`, `sku_product_route`, and `sku_product` fields on each line item resolve via the explicit `FaireProductOption → ProductListing → Product` chain (joined on `faire_variant_id`). They populate only when the variant has been explicitly mapped via the Variants Listing page (Map / Smart Match / Bulk Map). String-based SKU matching is NOT used."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/refetch","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","refetch"],"variable":[{"key":"order","value":"101","description":"Faire order ID (DB primary key)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 1,\n    \"faire_order_id\": \"bo_abc123xyz\",\n    \"display_id\": \"FO-0001\",\n    \"status\": \"PROCESSING\",\n    \"retailer_id\": \"b_xyz789\",\n    \"retailer_name\": \"The Boutique Shop\",\n    \"retailer_state\": \"CA\",\n    \"retailer_country_code\": \"US\",\n    \"subtotal\": 15000,\n    \"discount_amount\": 0,\n    \"total\": 15000,\n    \"currency_code\": \"USD\",\n    \"ordered_at\": \"2026-04-20T08:30:00+00:00\",\n    \"shipped_at\": null,\n    \"delivered_at\": null,\n    \"tracking_number\": null,\n    \"tracking_carrier\": null,\n    \"tracking_submission_status\": null,\n    \"tracking_submitted_at\": null,\n    \"tracking_submission_error\": null,\n    \"tracking_submission_attempts\": 0,\n    \"line_items\": [],\n    \"sales_order\": {\n      \"id\": 57520,\n      \"sales_order_number\": \"FO-0001\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"payment_status\": \"paid\"\n    },\n    \"created_at\": \"2026-04-20T08:32:00+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false,\n    \"faire_admin_url\": \"https://www.faire.com/brand-portal/orders/bo_abc123xyz/order-fulfilment\"\n  },\n  \"message\": \"Order refetched from Faire successfully\"\n}"}]},{"name":"Get Order Filter Options (Distinct Values)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/filter-options","host":["{{baseUrl}}"],"path":["api","faire","orders","filter-options"]},"description":"**Tenant resolution (multi-instance safety):**\nBoth shapes are accepted, in priority order:\n- `filter[integration_instance_ids]` (preferred, Amazon-unified plural form; comma-separated CSV — first ID wins)\n- `filter[instance_id]` (legacy singular)\n- `?instance_id=` query string fallback\n- body `instance_id` (POST/PUT only)\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf none resolve to an existing FaireIntegrationInstance the endpoint returns an empty/zeroed payload — it does NOT silently fall back to the first tenant's data.\n\n**Empty-options response** (when no instance can be resolved):\n```json\n{\n  \"data\": {\n    \"statuses\": [],\n    \"currencies\": [],\n    \"country_codes\": [],\n    \"tracking_carriers\": [],\n    \"tracking_submission_statuses\": []\n  }\n}\n```\n\n---\n\nReturns distinct values for the Faire orders list view filter dropdowns. Mirrors the Shopify pattern — only values that actually appear in the data for the given integration instance are surfaced.\n\n**Query Parameters:**\n- `instance_id` (optional) — Faire integration instance to scope the distinct query. Defaults to the first available instance.\n\n**Response Fields (`data`):**\n- `statuses` — Distinct `faire_orders.status` values (e.g. `NEW`, `PROCESSING`, `COMPLETE`, `CANCELLED`)\n- `currencies` — Distinct `faire_orders.currency_code` values (ISO 4217)\n- `country_codes` — Distinct `faire_orders.retailer_country_code` values\n- `tracking_carriers` — Distinct `faire_orders.tracking_carrier` values\n- `tracking_submission_statuses` — Distinct `faire_orders.tracking_submission_status` values (`pending`, `submitted`, `failed`)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/orders/filter-options","host":["{{baseUrl}}"],"path":["api","faire","orders","filter-options"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"statuses\": [\n      \"BACKORDERED\",\n      \"CANCELLED\",\n      \"COMPLETE\",\n      \"NEW\",\n      \"PROCESSING\"\n    ],\n    \"currencies\": [\n      \"CAD\",\n      \"USD\"\n    ],\n    \"country_codes\": [\n      \"CA\",\n      \"US\"\n    ],\n    \"tracking_carriers\": [\n      \"FEDEX\",\n      \"UPS\",\n      \"USPS\"\n    ],\n    \"tracking_submission_statuses\": [\n      \"pending\",\n      \"submitted\"\n    ]\n  }\n}"}]},{"name":"Get Orders Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Aggregate stats about the Faire orders previously synced to this instance. Powers the **Refresh from Faire** orders modal header card and the latest-sync indicator on the orders index.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Response Fields (`data`):**\n- `latest_order_display_id` — Display ID of the most-recently-ordered Faire order (highest `ordered_at`). `null` when no orders are imported yet.\n- `latest_order_date` — ISO 8601 timestamp of that order's `ordered_at`.\n- `total_orders` — Count of all Faire orders for this instance (active + archived).\n- `created_count` — Faire orders that have a linked SKU.io sales order (`whereHas('salesOrder')`).\n- `pending_count` — Active Faire orders **without** a linked SKU.io sales order (the auto-create-SKU-orders queue).\n- `archived_count` — Faire orders with `archived_at` set.\n- `last_synced_at` — ISO 8601 timestamp from `sync_cursors.orders.synced_at` (when the cron last completed). `null` until the first sync runs.\n- `cursor_at` — The opaque rolling cursor stored at `sync_cursors.orders.cursor_at`. When `null`, the **Fetch Since Latest Sync** mode is unavailable in the refresh modal."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_display_id\": \"FO-0123\",\n    \"latest_order_date\": \"2026-05-01T10:00:00+00:00\",\n    \"total_orders\": 47,\n    \"created_count\": 32,\n    \"pending_count\": 12,\n    \"archived_count\": 3,\n    \"last_synced_at\": \"2026-05-06T08:00:00+00:00\",\n    \"cursor_at\": \"cursor_abc\"\n  }\n}"}]},{"name":"Refresh Orders from Faire (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Dispatches a background job that walks Faire's `/api/v2/orders` endpoint and upserts `faire_orders` + `faire_order_line_items`. Returns immediately with a tracked job log ID — progress is visible via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors the products tracked refresh (`/refresh-tracked` on the products endpoint) so the same UX and progress reporting (synced_orders list, orders_fetched/saved counters) drives the orders refresh modal.\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Body:**\n- `mode` (required) — One of:\n  - `incremental` — Resume from the persisted `sync_cursors.orders.cursor_at`. Recommended for routine refreshes; cursor is persisted across runs.\n  - `full` — Reset the cursor and walk Faire's full updated_at-min window (slow). Cursor is NOT persisted (so the next incremental run still resumes from where things left off).\n  - `date_range` — Fetch only orders whose `updated_at` falls between `date_from` and `date_to` (inclusive). Cursor is NOT persisted.\n- `date_from` (required when `mode=date_range`) — ISO date string (`YYYY-MM-DD`). Sent to Faire as `updated_at_min` (start-of-day UTC).\n- `date_to` (required when `mode=date_range`) — ISO date string (`YYYY-MM-DD`). Sent to Faire as `updated_at_max` (end-of-day UTC). Must be `>= date_from`.\n\n**Response:**\n- `data.tracked_job_log_id` — ID of the dispatched tracked job. Poll `/api/tracked-job-logs/:id` for progress.\n- `message` — Human-readable status string.\n\n**Validation Errors (422):**\n- `mode` must be one of `incremental`, `full`, `date_range`\n- `date_from` and `date_to` are required when `mode=date_range`\n- `date_to` must be on or after `date_from`","body":{"mode":"raw","raw":"{\n  \"mode\": \"incremental\",\n  \"date_from\": null,\n  \"date_to\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8421\n  },\n  \"message\": \"Order refresh job has been queued\"\n}"}]},{"name":"Submit Tracking to Faire (FBM)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/submit-tracking","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","submit-tracking"],"variable":[{"key":"order","value":"1","description":"Faire order ID (internal SKU.io ID, not Faire's bo_* ID)"}]},"description":"Manually retry tracking submission for an FBM Faire order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nDispatches a background job for the most recent fulfilled `SalesOrderFulfillment` that has a tracking number. The job calls Faire's per-line-item fulfillment endpoint (`POST /api/v2/brand/orders/{order_id}/items/{item_id}/fulfillments`) for each item in the shipment, with the carrier, tracking code, shipped-at timestamp, and quantity.\n\nUseful when an automatic submission failed and the user wants to retry. Job retries up to 3 times with exponential backoff (1m / 5m / 15m). Final status is reflected in `tracking_submission_status` on the order (`pending`, `submitted`, or `failed`) along with `tracking_submission_error` and `tracking_submission_attempts`.\n\n**Errors:**\n- `422` — Instance is FBF (tracking is owned by Faire), no SKU sales order linked, or no fulfilled shipment with a tracking number found."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/submit-tracking","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","submit-tracking"],"variable":[{"key":"order","value":"1","description":"Faire order ID (internal SKU.io ID, not Faire's bo_* ID)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Faire tracking submission queued.\"\n}"}]},{"name":"Archive Faire Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","archive"],"variable":[{"key":"order","value":"101","description":"Internal Faire order ID"}]},"description":"Archives a single Faire order — stamps `archived_at = now()` via the `Archive` trait. Archived orders are excluded from the auto-create-SKU-orders pipelines (see `createSkuOrders`) and from the default orders listing (which uses `filter[archived]=` Active by default).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIdempotent: archiving an already-archived order returns `archived: false` with a friendly message.\n\n**Path Parameters:**\n- `order` — The internal Faire order ID (`faire_orders.id`)\n\n**Response Fields:**\n- `message` — Human-readable result\n- `archived` — `true` when the call flipped the row, `false` if it was already archived"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","archive"],"variable":[{"key":"order","value":"101","description":"Internal Faire order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Faire Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","unarchive"],"variable":[{"key":"order","value":"101","description":"Internal Faire order ID"}]},"description":"Unarchives a single Faire order — clears `archived_at` via the `Archive` trait. After unarchiving, the order becomes eligible for auto-create-SKU-orders again.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIdempotent: unarchiving an already-active order returns `unarchived: false`.\n\n**Path Parameters:**\n- `order` — The internal Faire order ID (`faire_orders.id`)\n\n**Response Fields:**\n- `message` — Human-readable result\n- `unarchived` — `true` when the call flipped the row, `false` if it was already active"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","faire","orders",":order","unarchive"],"variable":[{"key":"order","value":"101","description":"Internal Faire order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Bulk Archive Faire Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Archives multiple Faire orders for the given integration instance. Scoped to active orders only — already-archived rows are silently skipped, and IDs from foreign integration instances are NOT affected (the controller filters `where('integration_instance_id', $instance->id)`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOperates in chunks of 100 to keep the query small.\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Body:**\n- `ids` (required, array of integers) — Faire order IDs to archive. Must be a non-empty array.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `archived_count` — Number of rows actually flipped (excludes IDs that were already archived or belong to other instances)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Faire Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Unarchives multiple Faire orders for the given integration instance. Scoped to archived orders only — already-active rows are silently skipped, and IDs from foreign integration instances are NOT affected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOperates in chunks of 100.\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Body:**\n- `ids` (required, array of integers) — Faire order IDs to unarchive. Must be a non-empty array.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `unarchived_count` — Number of rows actually flipped","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders unarchived successfully\",\n  \"unarchived_count\": 3\n}"}]},{"name":"Delete Linked Sales Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"order","value":"101","description":"Internal Faire order ID (`faire_orders.id`)"}]},"description":"Deletes the linked SKU.io sales order for a single Faire order while keeping the Faire order itself intact. Optionally archives the Faire order in the same call to prevent re-creation on the next sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n- `order` — The internal Faire order ID (`faire_orders.id`)\n\n**Query Parameters:**\n- `archive_faire_order` (optional, boolean) — When `true`, archives the Faire order after deleting its linked SKU sales order. Defaults to `false`.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `archived_faire_order` — `true` if the Faire order was archived as part of this call\n\n**Errors:**\n- `404` when the Faire order has no linked SKU sales order"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"order","value":"101","description":"Internal Faire order ID (`faire_orders.id`)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully\",\n  \"archived_faire_order\": false\n}"}]},{"name":"Bulk Delete Linked Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Bulk-deletes the linked SKU.io sales orders for multiple Faire orders while keeping the Faire orders themselves intact. Only orders with a linked sales order in the targeted integration instance are processed — IDs from foreign instances or without a linked SKU order are silently skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- **0 eligible orders** — returns `tracked_job_log_id: null` synchronously.\n- **1 eligible order** — deletes synchronously and returns `tracked_job_log_id: null`.\n- **>1 eligible orders** — dispatches a background job and returns the tracked-job ID for progress polling.\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Body:**\n- `ids` (required, array of integers) — Faire order IDs to delete linked SKU orders for. Must be a non-empty array.\n- `archive_faire_orders` (optional, boolean) — When `true`, archives each Faire order after deleting its linked SKU sales order. Defaults to `false`.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `tracked_job_log_id` — Tracked-job log ID when a job was dispatched, otherwise `null`\n- `total_orders` (only when a tracked job was dispatched) — Number of eligible orders queued for deletion\n\n**Tracked Job Name:** `Bulk Delete SKU Orders: {instance_name}` (frontend `lastCompletedJob` watcher matches with `startsWith`)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ],\n  \"archive_faire_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete job started\",\n  \"tracked_job_log_id\": 4521,\n  \"total_orders\": 3\n}"}]},{"name":"Sync Linked Sales Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/{order}/update-sku-order","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders",":order","update-sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"order","value":"101","description":"Internal Faire order ID (`faire_orders.id`)"}]},"description":"Refetches the order from Faire and synchronously syncs the linked SKU.io sales order's status fields (`order_status`, `payment_status`, `last_synced_from_sales_channel_at`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n- `order` — The internal Faire order ID (`faire_orders.id`)\n\n**Body:** Empty.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `refetched` — `true` when the latest order state was successfully fetched from Faire before the SKU sync\n\n**Errors:**\n- `403` when the order does not belong to the supplied integration instance\n- `404` when the Faire order has no linked SKU sales order\n- `422` when the SKU sales order update fails (e.g., refetch error or downstream validation)","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/{order}/update-sku-order","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders",":order","update-sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"order","value":"101","description":"Internal Faire order ID (`faire_orders.id`)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order updated successfully\",\n  \"refetched\": true\n}"}]},{"name":"Bulk Sync Linked Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-update-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Bulk-refetches Faire orders and re-syncs each linked SKU.io sales order's status fields (`order_status`, `payment_status`, `last_synced_from_sales_channel_at`). Only orders with a linked SKU sales order in the targeted integration instance are processed — foreign-instance IDs and orders without a linked SKU order are silently skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- **0 eligible orders** — returns `tracked_job_log_id: null` synchronously.\n- **1 eligible order** — updates synchronously and returns `tracked_job_log_id: null`.\n- **>1 eligible orders** — dispatches a background job and returns the tracked-job ID for progress polling.\n\n**Path Parameters:**\n- `integrationInstance` — The ID of the integration instance\n\n**Body:**\n- `ids` (required, array of integers) — Faire order IDs to update linked SKU orders for. Must be a non-empty array.\n\n**Response Fields:**\n- `message` — Human-readable result\n- `tracked_job_log_id` — Tracked-job log ID when a job was dispatched, otherwise `null`\n- `total_orders` (only when a tracked job was dispatched) — Number of eligible orders queued for update\n\n**Tracked Job Name:** `Bulk Update SKU Orders: {instance_name}` (frontend `lastCompletedJob` watcher matches with `startsWith`)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/orders/bulk-update-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","orders","bulk-update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk update job started\",\n  \"tracked_job_log_id\": 4528,\n  \"total_orders\": 3\n}"}]},{"name":"List Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/pre-start-date-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","pre-start-date-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Query Faire live for orders placed before the instance's order import start date, so historical orders can be selectively imported. Results come directly from the Faire API — not from the local database — and each order carries eligibility flags for import.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Requires the instance's order import start date to be set** — returns 422 otherwise.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Query Parameters:**\n- `created_at_min` (optional, date) - Lower bound for the query window. Defaults to one year before the order import start date\n\n**Behavior:**\n- Scans up to 10 pages of 50 orders from Faire and keeps only orders created before the start date\n- Cancelled orders and orders already imported into SKU.io are marked ineligible\n- Order totals are read from Faire payout data, falling back to a sum of line item prices when Faire returns zero\n\n**Response:**\n- `data` - The queried orders, each with:\n  - `faire_order_id` - Faire order ID (e.g. `bo_abc123xyz`)\n  - `display_id` - Short human-readable Faire order number\n  - `status` - Faire order state (e.g. `DELIVERED`, `CANCELED`)\n  - `retailer_name` - Retailer/company name from the order address\n  - `ordered_at` - When the order was placed on Faire\n  - `total` - Order subtotal in minor currency units (cents); null when unavailable\n  - `currency_code` - Currency of the total (default USD)\n  - `item_count` - Total units across all line items\n  - `already_imported` - True when the order already exists in SKU.io\n  - `eligible` - True when the order can be imported\n  - `ineligible_reason` - Why the order cannot be imported (null when eligible)\n  - `items` - Line items with `faire_line_item_id`, `sku`, `name`, `quantity`, `unit_price` (major units)\n- `order_import_start_date` - The instance's configured start date\n- `meta.total_queried` / `meta.eligible_count` / `meta.already_imported_count` - Query summary counts"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/pre-start-date-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","pre-start-date-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"faire_order_id\": \"bo_abc123xyz\",\n      \"display_id\": \"K3M2ZX\",\n      \"status\": \"DELIVERED\",\n      \"retailer_name\": \"The Corner Boutique\",\n      \"ordered_at\": \"2025-11-14T18:03:22.000Z\",\n      \"total\": 42500,\n      \"currency_code\": \"USD\",\n      \"item_count\": 18,\n      \"already_imported\": false,\n      \"eligible\": true,\n      \"ineligible_reason\": null,\n      \"items\": [\n        {\n          \"faire_line_item_id\": \"oi_5f8d2k\",\n          \"sku\": \"CANDLE-SM-RED\",\n          \"name\": \"Small Candle\",\n          \"quantity\": 12,\n          \"unit_price\": 15\n        },\n        {\n          \"faire_line_item_id\": \"oi_9c1b7q\",\n          \"sku\": \"CANDLE-LG-NAVY\",\n          \"name\": \"Large Candle\",\n          \"quantity\": 6,\n          \"unit_price\": 22.5\n        }\n      ]\n    },\n    {\n      \"faire_order_id\": \"bo_def456uvw\",\n      \"display_id\": \"H8P4QN\",\n      \"status\": \"CANCELED\",\n      \"retailer_name\": \"Maple & Main Goods\",\n      \"ordered_at\": \"2025-10-02T11:47:09.000Z\",\n      \"total\": 18000,\n      \"currency_code\": \"USD\",\n      \"item_count\": 8,\n      \"already_imported\": false,\n      \"eligible\": false,\n      \"ineligible_reason\": \"Order is cancelled\",\n      \"items\": [\n        {\n          \"faire_line_item_id\": \"oi_2m6x1t\",\n          \"sku\": \"CANDLE-SM-BLUE\",\n          \"name\": \"Small Candle\",\n          \"quantity\": 8,\n          \"unit_price\": 15\n        }\n      ]\n    }\n  ],\n  \"order_import_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 2,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Import selected pre-start-date orders from Faire into SKU.io. Each order is fetched from the Faire API and stored as a Faire order flagged as a pre-start-date import.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBecause each order requires its own throttled Faire API call, the import runs in the background. The request returns immediately with a tracked job log ID that can be used to follow the import's progress.\n\n**Requires the instance's order import start date to be set** — returns 422 otherwise.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Request Body:**\n- `faire_order_ids` (required, array of strings, 1-10000 entries) - Faire order IDs to import (e.g. `bo_abc123xyz`)\n\n**Behavior:**\n- Runs as a background import — the request returns right away with a tracked job log ID; the orders are fetched and stored asynchronously\n- Orders already in SKU.io are marked as pre-start-date imports instead of being re-imported\n- Cancelled orders and orders whose fulfillment mode does not match the instance are skipped\n- Imported orders do NOT automatically create linked sales orders — use Create Linked Sales Orders afterwards\n\n**Response:**\n- `data.tracked_job_log_id` - ID of the tracked job log; poll it to follow import progress\n- `message` - Human-readable confirmation of how many orders are being imported","body":{"mode":"raw","raw":"{\n  \"faire_order_ids\": [\n    \"bo_abc123xyz\",\n    \"bo_jkl789rst\",\n    \"bo_mno012pqr\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8412\n  },\n  \"message\": \"Importing 3 pre-start-date orders — track progress in the job tray.\"\n}"}]},{"name":"Create Linked Sales Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/create-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Create SKU.io sales orders from Faire orders that do not yet have a linked sales order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Request Body:**\n- `ids` (required unless `create_all_orders` is true, array of integers) - Internal Faire order IDs (the `id` from List Faire Orders, not the Faire order ID string)\n- `create_all_orders` (optional, boolean) - When true, targets every eligible Faire order on the instance and `ids` is ignored\n\n**Eligibility:**\nOnly Faire orders belonging to this instance, without an existing linked sales order, and not archived are processed. Ineligible IDs are silently skipped.\n\n**Behavior:**\n- Exactly 1 eligible order — the sales order is created synchronously within the request\n- 2+ eligible orders — a background job is dispatched and the request returns immediately; creation runs asynchronously and progress can be monitored via the returned `tracked_job_log_id`\n- 0 eligible orders — returns a `No orders to create` message\n\n**Response:**\n- `message` - Outcome summary\n- `tracked_job_log_id` - ID for monitoring the background creation (only when 2+ orders are queued)\n- `total_orders` - Number of orders queued for creation (only when 2+ orders are queued)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/create-sku-orders","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order creation started for 3 orders\",\n  \"tracked_job_log_id\": 152,\n  \"total_orders\": 3\n}"}]},{"name":"List Faire Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/products?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","faire","products"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default: 10)","disabled":true}]},"description":"List Faire products synced for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Tenant resolution (multi-instance safety):**\nBoth shapes are accepted, in priority order:\n- `filter[integration_instance_ids]` (preferred, Amazon-unified plural form; comma-separated CSV — first ID wins)\n- `filter[instance_id]` (legacy singular)\n- `?instance_id=` query string fallback\n- body `instance_id` (POST/PUT only)\n\nIf none resolve to an existing FaireIntegrationInstance the endpoint returns an empty/zeroed payload — it does NOT silently fall back to the first tenant's data.\n\n**Empty-paginator response** when no instance resolves: `{ data: [], total: 0, per_page, ... }`.\n\n---\n\nList Faire products synced for a specific integration instance.\n\n**Query Parameters:**\n- `instance_id` (optional) - Filter products to a specific integration instance. Defaults to the first instance.\n- `page` (optional) - Page number (default: 1)\n- `per_page` (optional) - Items per page (default: 10)\n\n**Response Fields per Product:**\n- `id` - Internal product ID\n- `integration_instance_id` - Integration instance ID\n- `faire_product_id` - Faire's product ID (e.g. `p_abc123`)\n- `name` - Product name\n- `status` - Product status (`ACTIVE`, `INACTIVE`, `DELETED`)\n- `wholesale_price_minimum` - Minimum wholesale price in cents\n- `currency_code` - ISO 4217 currency code\n- `options` - Loaded when explicitly eager-loaded (variants/SKUs)\n- `created_at` - ISO timestamp"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/products?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","faire","products"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 50,\n      \"integration_instance_id\": 1,\n      \"faire_product_id\": \"p_xyz456abc\",\n      \"name\": \"Small Candle\",\n      \"status\": \"ACTIVE\",\n      \"wholesale_price_minimum\": 1200,\n      \"currency_code\": \"USD\",\n      \"options\": [],\n      \"created_at\": \"2026-04-10T07:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Products for Instance (Variants Listing)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products?per_page=15&sort=-created_at&filter[archived]=0&filter[mapped.is]=&filter[search]=&filter[status][is]=&filter[product_type][is]=&filter[has_sku.is]=&filter[date_from]=&filter[date_to]=","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-created_at","description":"Allowed: id, sku, faire_variant_id, wholesale_price, created_at. Prefix with `-` for descending.","disabled":true},{"key":"filter[archived]","value":"0","description":"0 = active variants only (default), 1 = archived only. Omit to include both.","disabled":true},{"key":"filter[mapped.is]","value":"","description":"1 = only variants linked to a sku.io product. 0 = only unmapped. Operator suffix (`.is`) matches the advanced-filter checkbox convention.","disabled":true},{"key":"filter[search]","value":"","description":"Free-text search across sku, faire_variant_id, name (uses AdvancedSearchFilter)","disabled":true},{"key":"filter[status][is]","value":"","description":"Faire product status: ACTIVE | INACTIVE | DRAFT | DELETED","disabled":true},{"key":"filter[product_type][is]","value":"","description":"Faire taxonomy product_type (e.g. \"Bar Tool\"). Powered by the filter-options endpoint.","disabled":true},{"key":"filter[has_sku.is]","value":"","description":"1 = variants with a Faire SKU. 0 = variants missing a SKU. Operator suffix (`.is`) matches the advanced-filter checkbox convention.","disabled":true},{"key":"filter[date_from]","value":"","description":"Created on/after this date (any parseable date string)","disabled":true},{"key":"filter[date_to]","value":"","description":"Created on/before this date","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Paginated list of `FaireProductOption` rows (variants) for one Faire integration instance. Powers the **Faire → Products** listing page in application UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUses Spatie QueryBuilder under the hood with `GroupedFilterSupport`. The advanced-filter operator suffix is required for `status` and `product_type` filters (`filter[status][is]=ACTIVE`, etc.).\n\n**Default behavior:** archived variants are hidden unless `filter[archived]` is set explicitly.\n\n**Response shape:** standard Laravel paginator wrapping Faire product option object. Each row eager-loads the parent `product` and `productListing.product.defaultFinancialLineType`, so `product_name`, `product_status`, `product_type`, `product_image_url`, `product_brand_name`, `product_description`, and the mapped sku.io `product` block are populated when present.\n\n**Note:** `product_brand_name` and `product_description` are derived from the parent `FaireProduct.raw_data` JSON column via Eloquent accessors — they are not dedicated DB columns. They surface in the variant listing (and detail) so the mapping modal can display brand context for each variant.\n\n**Allowed sorts:** `id`, `sku`, `faire_variant_id`, `wholesale_price`, `created_at` (default `-created_at`).\n\n**Note:** `faire_product_id` is the Faire-issued product ID (e.g. `p_3bz2tdhtkq`), sourced from the parent FaireProduct. It is NOT the internal `faire_product_options.faire_product_id` foreign key."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products?per_page=15&sort=-created_at&filter[archived]=0&filter[mapped.is]=&filter[search]=&filter[status][is]=&filter[product_type][is]=&filter[has_sku.is]=&filter[date_from]=&filter[date_to]=","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-created_at","description":"Allowed: id, sku, faire_variant_id, wholesale_price, created_at. Prefix with `-` for descending.","disabled":true},{"key":"filter[archived]","value":"0","description":"0 = active variants only (default), 1 = archived only. Omit to include both.","disabled":true},{"key":"filter[mapped.is]","value":"","description":"1 = only variants linked to a sku.io product. 0 = only unmapped. Operator suffix (`.is`) matches the advanced-filter checkbox convention.","disabled":true},{"key":"filter[search]","value":"","description":"Free-text search across sku, faire_variant_id, name (uses AdvancedSearchFilter)","disabled":true},{"key":"filter[status][is]","value":"","description":"Faire product status: ACTIVE | INACTIVE | DRAFT | DELETED","disabled":true},{"key":"filter[product_type][is]","value":"","description":"Faire taxonomy product_type (e.g. \"Bar Tool\"). Powered by the filter-options endpoint.","disabled":true},{"key":"filter[has_sku.is]","value":"","description":"1 = variants with a Faire SKU. 0 = variants missing a SKU. Operator suffix (`.is`) matches the advanced-filter checkbox convention.","disabled":true},{"key":"filter[date_from]","value":"","description":"Created on/after this date (any parseable date string)","disabled":true},{"key":"filter[date_to]","value":"","description":"Created on/before this date","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 140,\n      \"integration_instance_id\": 7,\n      \"faire_product_id\": \"p_3bz2tdhtkq\",\n      \"faire_variant_id\": \"7c3a2b18-9d4a-4f6e-b211-7a9c84d0f221\",\n      \"sku\": \"HAW-STR-CP\",\n      \"name\": \"Antique Copper\",\n      \"product_name\": \"Hawthorne Strainer\",\n      \"product_status\": \"ACTIVE\",\n      \"product_type\": \"Bar Tool\",\n      \"product_image_url\": \"https://cdn.faire.com/img/abc123/300.jpg\",\n      \"product_brand_name\": \"Hawthorne & Co.\",\n      \"product_description\": \"Premium 4-prong strainer machined from solid brass.\",\n      \"product_wholesale_price_minimum\": 8.5,\n      \"product_currency_code\": \"USD\",\n      \"inventory_quantity\": 12,\n      \"faire_inventory_quantity\": 12,\n      \"wholesale_price\": 8.5,\n      \"product\": null,\n      \"sibling_options\": [\n        {\n          \"id\": 141,\n          \"faire_variant_id\": \"9b81…\",\n          \"sku\": \"HAW-STR-BLK\",\n          \"name\": \"Matte Black\",\n          \"wholesale_price\": 8.5,\n          \"inventory_quantity\": 6,\n          \"product_listing_product\": null\n        }\n      ],\n      \"archived_at\": null,\n      \"created_at\": \"2026-05-04T18:22:31+00:00\",\n      \"updated_at\": \"2026-05-06T19:14:02+00:00\"\n    },\n    {\n      \"id\": 132,\n      \"integration_instance_id\": 7,\n      \"faire_product_id\": \"p_wvdp6e8v4u\",\n      \"faire_variant_id\": \"f0a18…\",\n      \"sku\": \"JAR-BELL-CP\",\n      \"name\": \"Antique Copper\",\n      \"product_name\": \"Bell Jar Cocktail Shaker\",\n      \"product_status\": \"ACTIVE\",\n      \"product_type\": \"Bar Tool\",\n      \"product_image_url\": \"https://cdn.faire.com/img/def456/300.jpg\",\n      \"product_brand_name\": \"Bell Jar Co.\",\n      \"product_description\": null,\n      \"product_wholesale_price_minimum\": 22,\n      \"product_currency_code\": \"USD\",\n      \"inventory_quantity\": 4,\n      \"faire_inventory_quantity\": 4,\n      \"wholesale_price\": 22,\n      \"product\": {\n        \"id\": 33421,\n        \"sku\": \"JAR-BELL-CP\",\n        \"name\": \"Bell Jar Cocktail Shaker\",\n        \"default_financial_line_type_id\": null,\n        \"default_financial_line_type\": null\n      },\n      \"sibling_options\": [],\n      \"archived_at\": null,\n      \"created_at\": \"2026-05-04T18:22:30+00:00\",\n      \"updated_at\": \"2026-05-06T19:14:01+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku2.test/api/faire/instances/7/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 71,\n  \"last_page_url\": \"https://sku2.test/api/faire/instances/7/products?page=71\",\n  \"links\": [],\n  \"next_page_url\": \"https://sku2.test/api/faire/instances/7/products?page=2\",\n  \"path\": \"https://sku2.test/api/faire/instances/7/products\",\n  \"per_page\": 2,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 141\n}"}]},{"name":"Get Faire Products Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Aggregate stats about the products previously synced from Faire. Used by the **Refresh from Faire** modal header to show how much data is currently cached locally and which mode of refresh is appropriate.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Response Fields:**\n- `latest_product_title` - Name of the most recently updated `FaireProduct` for this instance (null if none synced yet)\n- `latest_product_date` - ISO timestamp of that product's `updated_at`\n- `total_products` - Count of distinct `faire_products` rows for this instance\n- `total_variants` - Count of `faire_product_options` rows for this instance\n- `mapped_products` - Number of variants linked to a `product_listings` row\n- `unmapped_products` - Variants without a product listing\n- `last_synced_at` - Latest `updated_at` across all variants\n- `cursor_at` - Stored incremental sync cursor on the integration instance (`sync_cursors.products.cursor_at`). When null, the **Fetch Since Latest Sync** mode is unavailable and the user is forced to choose **Refetch Entire Catalog** or **Custom Date Range**."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Citrus Peeler, Gold & Black\",\n    \"latest_product_date\": \"2026-05-04T18:22:31+00:00\",\n    \"total_products\": 127,\n    \"total_variants\": 141,\n    \"mapped_products\": 0,\n    \"unmapped_products\": 141,\n    \"last_synced_at\": \"2026-05-04T18:22:31+00:00\",\n    \"cursor_at\": \"2026-05-04T18:22:31+00:00\"\n  }\n}"}]},{"name":"Get Variant Filter Options (Distinct Product Types)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Returns distinct values for the variant listing's filter dropdowns. Currently only `product_types` (sourced from `faire_products.product_type`, populated from Faire's taxonomy `taxonomy_type.name`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Used by:** the **Product Type** filter chip on the Faire products listing page — calls this endpoint once on mount to populate its autocomplete dropdown.\n\nResults are sorted alphabetically and exclude blank/null values."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_types\": [\n      \"Bar Tool\",\n      \"Coffee Maker\",\n      \"Drinkware\",\n      \"Glassware\",\n      \"Kitchen Accessory\"\n    ]\n  }\n}"}]},{"name":"Refresh Products from Faire (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Dispatches a background job background job that walks the Faire catalog and persists `faire_products` + `faire_product_options`. Returns immediately with a tracked job log ID — progress is visible via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Body:**\n- `mode` (required) - One of:\n  - `incremental` - Resume from the persisted `sync_cursors.products.cursor_at` (skip products already imported since the last sync). Recommended for routine refreshes.\n  - `full` - Reset the cursor and walk the entire catalog (slow). Use to rebuild from scratch.\n  - `date_range` - Fetch only products whose `updated_at` falls between `date_from` and `date_to` (inclusive). Cursor is NOT persisted in this mode.\n- `date_from` (required when `mode=date_range`) - ISO date string (`YYYY-MM-DD`). Sent to Faire as `updated_at_min` (start-of-day UTC).\n- `date_to` (required when `mode=date_range`) - ISO date string (`YYYY-MM-DD`). Sent to Faire as `updated_at_max` (end-of-day UTC). Must be `>= date_from`.\n\n**Response:**\n- `data.tracked_job_log_id` - The ID of the dispatched tracked job. Pass to `/api/tracked-job-logs/:id` to poll progress.\n- `message` - Human-readable status string.\n\n**Validation Errors (422):**\n- `mode` must be one of `incremental`, `full`, `date_range`\n- `date_from` and `date_to` are required when `mode=date_range`\n- `date_to` must be on or after `date_from`","body":{"mode":"raw","raw":"{\n  \"mode\": \"incremental\",\n  \"date_from\": null,\n  \"date_to\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4218\n  },\n  \"message\": \"Product refresh job has been queued\"\n}"}]},{"name":"Bulk Operation (Synchronous)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Run a bulk action on Faire product options synchronously and return the result inline. Best for **Selected Only** requests where the count is small and the operation completes in well under HTTP timeout. For **All Filtered** requests that may exceed timeout, use the tracked variant instead.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` (required) - The ID of the Faire integration instance.\n\n**Body:**\n- `action` (required) - One of `archive`, `unarchive`, `delete`, `map`, `unmap`, `create`, `remap`. Currently only `archive`, `unarchive`, and `delete` are wired up; mapping actions surface as `skipped`.\n- `selection` (required) - object describing which records to act on:\n  - `selection.type` (required) - One of `selected` (use the explicit `ids` list), `visible` (use the current page's filters), `filtered` (use the active filter set across all matching records).\n  - `selection.ids` (required when `type=selected`) - Array of `faire_product_options.id` values.\n  - `selection.filters` (optional) - Spatie QueryBuilder filter map. The same filter shape accepted by `GET /api/faire/instances/:integrationInstance/products`. Resolved via `BulkFilterResolver`.\n- `options` (optional) - object reserved for action-specific options (currently unused on Faire — placeholder for future mapping options).\n\n**Response (200):**\n- `data.processed` - Count of records the action successfully ran against.\n- `data.failed` - Count of records that errored during the action.\n- `data.skipped` - Count of records that were skipped (e.g., already in the target state, or unsupported `action`).\n- `message` - Human-readable status string.\n\n**Errors:**\n- `422` when no records resolve from the selection (empty `ids` for `type=selected`, or filters returning zero rows).\n- `422` when validation fails on the body shape.","body":{"mode":"raw","raw":"{\n  \"action\": \"archive\",\n  \"selection\": {\n    \"type\": \"selected\",\n    \"ids\": [\n      101,\n      102,\n      103\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processed\": 3,\n    \"failed\": 0,\n    \"skipped\": 0\n  },\n  \"message\": \"Bulk archive completed. Processed: 3, Failed: 0, Skipped: 0\"\n}"}]},{"name":"Bulk Operation (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Dispatches a background job background job that performs the bulk action across the resolved selection. Returns immediately with a tracked job log ID — progress is visible via the tracked job log endpoints and pollable via the `bulk-progress` endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUse this variant for **All Filtered** requests where the count may be large enough to exceed an HTTP timeout. For **Selected Only** with small counts, the synchronous variant is faster.\n\n**Path Parameters:**\n- `integrationInstance` (required) - The ID of the Faire integration instance.\n\n**Body:** Same shape as the synchronous `bulk` endpoint. See its description for full field-by-field documentation. The selection is resolved server-side BEFORE the job is dispatched, so the response includes the tracked-job ID only when at least one record matched.\n\n**Response (200):**\n- `data.tracked_job_log_id` - The ID of the dispatched tracked job. Pass to `bulk-progress/:trackedJobLogId` (or the global `/api/tracked-job-logs/:id`) to poll progress.\n- `message` - Human-readable status string.\n\n**Errors:**\n- `422` when no records resolve from the selection.\n- `422` when validation fails on the body shape.","body":{"mode":"raw","raw":"{\n  \"action\": \"archive\",\n  \"selection\": {\n    \"type\": \"filtered\",\n    \"filters\": {\n      \"archived\": 0\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5217\n  },\n  \"message\": \"Bulk operation job has been queued\"\n}"}]},{"name":"Bulk Operation Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"trackedJobLogId","value":"5217","description":"ID of the tracked job log returned by the bulk-tracked endpoint"}]},"description":"Returns the live progress of a background job. Returns the standard tracked job log object shape — same as the tracked job log endpoints polls. Poll this endpoint while the job runs; `progress_percentage` and `results` update as the job processes batches.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` (required) - The ID of the Faire integration instance.\n- `trackedJobLogId` (required) - The tracked job log ID returned by the `bulk-tracked` dispatch.\n\n**Response (200):** A standard tracked job log object. Key fields for a Faire bulk job:\n- `data.id` - Tracked job log ID.\n- `data.status` - One of `pending`, `processing`, `completed`, `failed`, `cancelled`.\n- `data.progress_percentage` - 0-100 (or `null` until the job starts).\n- `data.message` - Latest status message from the job.\n- `data.results` - When completed, contains `{ action, total, processed, failed, skipped, started_at, completed_at }`. Errors populate `results.error`.\n\n**Errors:**\n- `404` when the tracked job log ID does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"trackedJobLogId","value":"5217","description":"ID of the tracked job log returned by the bulk-tracked endpoint"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5217,\n    \"job_name\": \"Bulk Archive: 248 Faire products\",\n    \"status\": \"processing\",\n    \"progress_percentage\": 47,\n    \"message\": \"Archiving 116 of 248\",\n    \"results\": null,\n    \"created_at\": \"2026-05-06T19:55:00.000000Z\",\n    \"updated_at\": \"2026-05-06T19:55:42.000000Z\"\n  }\n}"}]},{"name":"Map Single Variant to SKU.io Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/map","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]},"description":"Maps a single Faire product variant (option) to an existing SKU.io product. Used by the per-row Map button on the Faire products page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf the variant is already mapped, the existing `product_listings` row is updated in place (no duplicate is created) — this powers the Remap flow as well.\n\n**Path Parameters:**\n- `integrationInstance` - Faire integration instance ID. Returns 404 if the variant doesn't belong to this instance.\n- `option` - Faire product option (variant) ID.\n\n**Body:**\n- `product_id` (required, integer, exists:products,id) - The SKU.io product ID to map this Faire variant to.\n\n**Response:**\nReturns the updated `FaireProductOptionDetail` resource (same shape as `GET .../products/:option`), with `product` populated to the newly-linked SKU.io product.\n\n**Errors:**\n- `404` - The variant does not belong to the given integration instance.\n- `422` - `product_id` is missing or does not exist in `products`.\n- `500` - The Faire integration instance has no associated `sales_channel` row (configuration issue).\n\n**Note:** `faire_product_id` is the Faire-issued product ID (e.g. `p_3bz2tdhtkq`), sourced from the parent FaireProduct. It is NOT the internal `faire_product_options.faire_product_id` foreign key.","body":{"mode":"raw","raw":"{\n  \"product_id\": 12345\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/map","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 139,\n    \"faire_product_id\": \"p_a1b2c3d4e5f\",\n    \"faire_variant_id\": \"v_xyz\",\n    \"sku\": \"JGR-BELL-CP\",\n    \"name\": \"Bell Jigger - 2 ounce, Antique Copper\",\n    \"wholesale_price\": 18.5,\n    \"product\": {\n      \"id\": 12345,\n      \"sku\": \"JGR-BELL-CP\",\n      \"name\": \"Bell Jigger 2oz Antique Copper\",\n      \"default_financial_line_type\": null\n    },\n    \"product_listing\": {\n      \"id\": 9871,\n      \"product_id\": 12345,\n      \"sales_channel_id\": 88,\n      \"listing_sku\": \"JGR-BELL-CP\"\n    }\n  }\n}"}]},{"name":"Unmap Single Variant","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/map","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]},"description":"Removes the SKU.io product link for a single Faire variant by deleting the associated `product_listings` row. Idempotent — calling on a variant that wasn't mapped returns `data.unmapped = false` with status 200.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - Faire integration instance ID. Returns 404 if the variant doesn't belong to this instance.\n- `option` - Faire product option (variant) ID.\n\n**Response:**\n- `data.unmapped` (boolean) - `true` if a mapping was deleted, `false` if the variant wasn't mapped.\n- `message` (string) - Human-readable status (`Product unmapped` or `Product was not mapped`).\n\n**Errors:**\n- `404` - The variant does not belong to the given integration instance.\n\n**Note:** `faire_product_id` is the Faire-issued product ID (e.g. `p_3bz2tdhtkq`), sourced from the parent FaireProduct. It is NOT the internal `faire_product_options.faire_product_id` foreign key."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/map","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unmapped\": true\n  },\n  \"message\": \"Product unmapped\"\n}"}]},{"name":"Find Smart-Match Candidates","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/smart-match","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]},"description":"Suggests SKU.io products to map a Faire variant to. Used by the per-row mapping modal to power the **Smart Match** section.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Algorithm:**\n1. **Exact match** — looks up a SKU.io product whose `sku` exactly matches the Faire variant SKU.\n2. **Similar matches** — fuzzy text search using the parent Faire product name (preferred) or the variant name/SKU as the search term. Returns up to ~10 candidate products by name/SKU similarity.\n\n**Path Parameters:**\n- `integrationInstance` — Faire integration instance ID. Returns 404 if the variant doesn't belong to this instance.\n- `option` — Faire product option (variant) ID.\n\n**Response shape:**\n```\n{\n    \"data\": {\n        \"exact_match\": { id, sku, name, barcode, type, match_type: \"sku\", price } | null,\n        \"similar_matches\": [ { id, sku, name, barcode, type, match_type: \"fuzzy\", price } ]\n    }\n}\n```\n\n`price` is the SKU.io product's selling price (nullable). Surfaced in the mapping modal so users can compare against the Faire wholesale price.\n\n**Note:** Faire variants do not carry a barcode column, so `barcode_match` is intentionally absent.\n\n**Errors:**\n- `404` — The variant does not belong to the given integration instance."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/smart-match","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 12345,\n      \"sku\": \"JGR-BELL-CP\",\n      \"name\": \"Bell Jigger 2oz Antique Copper\",\n      \"barcode\": null,\n      \"type\": \"sku\",\n      \"match_type\": \"sku\",\n      \"price\": 12.5\n    },\n    \"similar_matches\": [\n      {\n        \"id\": 12346,\n        \"sku\": \"JGR-BELL-SS\",\n        \"name\": \"Bell Jigger 2oz Stainless Steel\",\n        \"barcode\": null,\n        \"type\": \"sku\",\n        \"match_type\": \"fuzzy\",\n        \"price\": 11\n      },\n      {\n        \"id\": 12347,\n        \"sku\": \"JGR-BELL-GD\",\n        \"name\": \"Bell Jigger 2oz Gold\",\n        \"barcode\": null,\n        \"type\": \"sku\",\n        \"match_type\": \"fuzzy\",\n        \"price\": null\n      }\n    ]\n  }\n}"}]},{"name":"Create SKU.io Product from Variant","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/create-sku-product","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]},"description":"Creates a new SKU.io product from a Faire variant's data and links the variant to it via a `product_listings` row. Used by the **Create New SKU Product** action in the per-row mapping modal.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Behavior:**\n- If a SKU.io product with the same SKU as the Faire variant already exists, links to that product instead of creating a duplicate (the response sets `linked_existing: true`).\n- Otherwise, creates a fresh `Product` row using the variant's SKU, name, and pricing data, then maps the variant to it.\n- The new product's SKU is made unique with a numeric suffix if the variant SKU collides with an unrelated product.\n\n**Path Parameters:**\n- `integrationInstance` — Faire integration instance ID. Returns 404 if the variant doesn't belong to this instance.\n- `option` — Faire product option (variant) ID.\n\n**Body:** None — all data is derived from the Faire variant.\n\n**Response shape:** Returns the updated Faire product option object (same shape as `GET .../products/:option`) with `product` populated, plus:\n- `linked_existing` (bool) — `true` if an existing SKU.io product was reused.\n- `message` (string) — Human-readable status.\n\n**Errors:**\n- `404` — The variant does not belong to the given integration instance.\n- `422` — The variant is already mapped to a SKU.io product. Unmap it first.\n\n**Note:** `faire_product_id` is the Faire-issued product ID (e.g. `p_3bz2tdhtkq`), sourced from the parent FaireProduct. It is NOT the internal `faire_product_options.faire_product_id` foreign key."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/create-sku-product","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"139","description":"Faire product option (variant) ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 139,\n    \"faire_product_id\": \"p_a1b2c3d4e5f\",\n    \"faire_variant_id\": \"v_xyz\",\n    \"sku\": \"JGR-BELL-CP\",\n    \"name\": \"Bell Jigger - 2 ounce, Antique Copper\",\n    \"wholesale_price\": 18.5,\n    \"product\": {\n      \"id\": 67890,\n      \"sku\": \"JGR-BELL-CP\",\n      \"name\": \"Bell Jigger - 2 ounce, Antique Copper\",\n      \"default_financial_line_type\": null\n    },\n    \"product_listing\": {\n      \"id\": 9872,\n      \"product_id\": 67890,\n      \"sales_channel_id\": 88,\n      \"listing_sku\": \"JGR-BELL-CP\"\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU.io product created and mapped.\"\n}"}]},{"name":"Get Variant Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"140","description":"FaireProductOption ID (variant)"}]},"description":"Detail view of a single `FaireProductOption` (variant), powering the Faire variant detail page in application UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Eager-loaded relationships:**\n- `product` — parent `FaireProduct` (status, product_type, image_url, wholesale_price_minimum, currency_code, brand_name, description)\n- `product.options.productListing.product.defaultFinancialLineType` — sibling variants and their sku.io mapping\n- `productListing.product.defaultFinancialLineType` — the sku.io product this variant is mapped to (if any)\n\n**Response shape:**\n- `id`, `integration_instance_id`, `faire_product_id`, `faire_variant_id`, `sku`, `name`\n- `product_name`, `product_status`, `product_type`, `product_image_url` — copied from parent product\n- `product_brand_name`, `product_description` — derived from the parent `FaireProduct.raw_data` JSON via Eloquent accessors (Faire does not store these as dedicated columns)\n- `product_wholesale_price_minimum`, `product_currency_code`\n- `inventory_quantity`, `faire_inventory_quantity`, `wholesale_price`\n- `product` — `{ id, sku, name, type, default_financial_line_type_id, default_financial_line_type }` of the mapped sku.io product (null if unmapped). `type` is the SKU.io `products.type` value (`single`, `variation`, etc.).\n- `sibling_options[]` — other variants on the same `FaireProduct`, each with their own mapping status; sibling `product_listing_product` now includes `type` as well\n- `archived_at` — ISO timestamp; non-null indicates the variant is archived\n- `created_at`, `updated_at` — ISO timestamps\n\n**Note:** Faire's full `raw_data` payload is NOT included here for performance reasons. Fetch it on-demand via `GET /api/faire/instances/:integrationInstance/products/:option/raw`.\n\n**Note:** `faire_product_id` is the Faire-issued product ID (e.g. `p_3bz2tdhtkq`), sourced from the parent FaireProduct. It is NOT the internal `faire_product_options.faire_product_id` foreign key."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"140","description":"FaireProductOption ID (variant)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 140,\n    \"integration_instance_id\": 7,\n    \"faire_product_id\": \"p_3bz2tdhtkq\",\n    \"faire_variant_id\": \"7c3a2b18-9d4a-4f6e-b211-7a9c84d0f221\",\n    \"sku\": \"HAW-STR-CP\",\n    \"name\": \"Antique Copper\",\n    \"product_name\": \"Hawthorne Strainer\",\n    \"product_status\": \"ACTIVE\",\n    \"product_type\": \"Bar Tool\",\n    \"product_image_url\": \"https://cdn.faire.com/img/abc123/300.jpg\",\n    \"product_brand_name\": \"Hawthorne & Co.\",\n    \"product_description\": \"Premium 4-prong strainer machined from solid brass.\",\n    \"product_wholesale_price_minimum\": 8.5,\n    \"product_currency_code\": \"USD\",\n    \"inventory_quantity\": 12,\n    \"faire_inventory_quantity\": 12,\n    \"wholesale_price\": 8.5,\n    \"product\": null,\n    \"sibling_options\": [\n      {\n        \"id\": 141,\n        \"faire_variant_id\": \"9b81f27e-30dd-4a8d-9f8c-71a8bf6c0e02\",\n        \"sku\": \"HAW-STR-BLK\",\n        \"name\": \"Matte Black\",\n        \"wholesale_price\": 8.5,\n        \"inventory_quantity\": 6,\n        \"product_listing_product\": null\n      }\n    ],\n    \"archived_at\": null,\n    \"created_at\": \"2026-05-04T18:22:31+00:00\",\n    \"updated_at\": \"2026-05-06T19:14:02+00:00\"\n  }\n}"}]},{"name":"Get Raw Data from Faire (Variant)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/raw","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"140","description":"FaireProductOption ID (variant) — the parent product's `raw_data` is returned"}]},"description":"Lazy-loaded raw payload from Faire for a single variant's parent product. Used by the Faire variant detail page's collapsible 'Raw Data from Faire' panel — only fetched when the panel is opened.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response is the contents of `faire_products.raw_data` (the JSON body as Faire returned it during the most recent product sync). This endpoint is intentionally separate from the variant detail endpoint to keep the page snappy: `raw_data` can be ~50 KB per product.\n\n**Response:**\n- `data` — the raw JSON object from Faire, or `null` if the product has no cached raw data yet\n\n**404 conditions:**\n- The variant doesn't belong to the supplied integration instance"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/products/{option}/raw","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","products",":option","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"},{"key":"option","value":"140","description":"FaireProductOption ID (variant) — the parent product's `raw_data` is returned"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"p_abc123\",\n    \"name\": \"Hand-Poured Soy Candle\",\n    \"description\": \"Brand-supplied long description as returned by Faire\",\n    \"brand_id\": \"b_xyz789\",\n    \"active\": true,\n    \"product_type\": \"Home Goods\",\n    \"wholesale_price_minimum\": {\n      \"amount_cents\": 1500,\n      \"currency\": \"USD\"\n    },\n    \"options\": [\n      {\n        \"id\": \"po_111\",\n        \"name\": \"Lavender\",\n        \"sku\": \"CANDLE-LAV\",\n        \"active\": true,\n        \"available_quantity\": 12\n      }\n    ],\n    \"images\": [\n      {\n        \"id\": \"im_aaa\",\n        \"url\": \"https://cdn.faire.com/example.jpg\"\n      }\n    ],\n    \"created_at\": \"2025-08-01T10:30:00Z\",\n    \"updated_at\": \"2026-04-22T14:12:00Z\"\n  }\n}"}]},{"name":"Get Product Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Get the product field mappings for a Faire integration instance. Mappings control which Faire listing/variant fields populate which SKU.io product fields when a SKU.io product is created from a Faire variant.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nDefault mappings (`sku` → `sku`, `name` → `item_name`, `wholesale_price` → the default pricing tier) are merged with per-instance custom mappings; a custom mapping targeting the same SKU.io field overrides the default.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Response:**\n- `integration_instance_id` - The integration instance ID\n- `integration_name` - The integration instance name\n- `mappings` - The effective mapping list (defaults merged with custom overrides)\n- `available_faire_fields` - Faire fields that can be used as a mapping source (`name`, `brand_name`, `description`, `sku`, `wholesale_price`), each with `name`, `label`, `type`, `description`, and `group`\n- `available_sku_fields` - SKU.io product fields that can be mapped to: static fields (`sku`, `name`, `item_name`, `barcode`, `description`, `unit_cost`, `weight`, `weight_unit`, `brand`) plus dynamic pricing-tier fields (`price.{tier}.value`) and product attribute fields (`attributes.{name}`)\n- `default_mappings` - The built-in defaults (each with `source: \"default\"`)\n- `custom_mappings` - Per-instance overrides saved via the update endpoint (each with `source: \"custom\"`)\n- `effective_mappings` - Same merged list as `mappings`\n\nEach mapping entry has:\n- `listing_field` - The Faire source field\n- `sku_field` - The SKU.io destination field\n- `parsers` - Optional value-transformation rules applied in order\n- `source` - `default` or `custom`\n- `description` - Human-readable summary of the mapping"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Faire - Main Brand\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps sku to sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps name to item_name\"\n      },\n      {\n        \"listing_field\": \"wholesale_price\",\n        \"sku_field\": \"price.Wholesale.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps wholesale_price to price.Wholesale.value\"\n      },\n      {\n        \"listing_field\": \"brand_name\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand_name → brand\"\n      }\n    ],\n    \"available_faire_fields\": {\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Faire product name (from parent product)\",\n        \"group\": \"Product Info\"\n      },\n      \"brand_name\": {\n        \"name\": \"brand_name\",\n        \"label\": \"Brand Name\",\n        \"type\": \"string\",\n        \"description\": \"Brand name from Faire product raw data\",\n        \"group\": \"Product Info\"\n      },\n      \"description\": {\n        \"name\": \"description\",\n        \"label\": \"Description\",\n        \"type\": \"string\",\n        \"description\": \"Product description from Faire product raw data\",\n        \"group\": \"Product Info\"\n      },\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Faire option SKU\",\n        \"group\": \"Variant Details\"\n      },\n      \"wholesale_price\": {\n        \"name\": \"wholesale_price\",\n        \"label\": \"Wholesale Price\",\n        \"type\": \"decimal\",\n        \"description\": \"Faire option wholesale price\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Stock Keeping Unit\",\n        \"group\": \"Basic Info\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Product name/title\",\n        \"group\": \"Basic Info\"\n      },\n      \"item_name\": {\n        \"name\": \"item_name\",\n        \"label\": \"Item Name\",\n        \"type\": \"string\",\n        \"description\": \"Item name (alias for product name)\",\n        \"group\": \"Basic Info\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\",\n        \"description\": \"Product barcode/UPC\",\n        \"group\": \"Basic Info\"\n      },\n      \"description\": {\n        \"name\": \"description\",\n        \"label\": \"Description\",\n        \"type\": \"string\",\n        \"description\": \"Product description\",\n        \"group\": \"Basic Info\"\n      },\n      \"unit_cost\": {\n        \"name\": \"unit_cost\",\n        \"label\": \"Unit Cost\",\n        \"type\": \"decimal\",\n        \"description\": \"Product cost price\",\n        \"group\": \"Pricing\"\n      },\n      \"weight\": {\n        \"name\": \"weight\",\n        \"label\": \"Weight\",\n        \"type\": \"decimal\",\n        \"description\": \"Product weight\",\n        \"group\": \"Physical\"\n      },\n      \"weight_unit\": {\n        \"name\": \"weight_unit\",\n        \"label\": \"Weight Unit\",\n        \"type\": \"string\",\n        \"description\": \"Unit of weight measurement\",\n        \"group\": \"Physical\"\n      },\n      \"brand\": {\n        \"name\": \"brand\",\n        \"label\": \"Brand\",\n        \"type\": \"string\",\n        \"description\": \"Product brand name\",\n        \"group\": \"Categorization\"\n      },\n      \"price.Wholesale.value\": {\n        \"name\": \"price.Wholesale.value\",\n        \"label\": \"Pricing: Wholesale\",\n        \"type\": \"decimal\",\n        \"description\": \"Price value for Wholesale pricing tier\",\n        \"group\": \"Pricing Tiers\"\n      },\n      \"attributes.Color\": {\n        \"name\": \"attributes.Color\",\n        \"label\": \"Attribute: Color\",\n        \"type\": \"string\",\n        \"description\": \"Product attribute: Color\",\n        \"group\": \"Product Attributes\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps sku to sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps name to item_name\"\n      },\n      {\n        \"listing_field\": \"wholesale_price\",\n        \"sku_field\": \"price.Wholesale.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps wholesale_price to price.Wholesale.value\"\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"brand_name\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand_name → brand\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps sku to sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps name to item_name\"\n      },\n      {\n        \"listing_field\": \"wholesale_price\",\n        \"sku_field\": \"price.Wholesale.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps wholesale_price to price.Wholesale.value\"\n      },\n      {\n        \"listing_field\": \"brand_name\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand_name → brand\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Product Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Update the custom product field mappings for a Faire integration instance. The submitted array replaces the instance's entire custom mapping set — include every custom mapping you want to keep.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCustom mappings override the built-in defaults when they target the same SKU.io field; defaults remain in effect for any SKU.io field not covered by a custom mapping.\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Request Body:**\n- `mappings` (required, array) - The custom mapping list\n- `mappings[].listing_field` (required, string) - Faire source field: `name`, `brand_name`, `description`, `sku`, or `wholesale_price`\n- `mappings[].sku_field` (required, string) - SKU.io destination field: a static field (`sku`, `name`, `item_name`, `barcode`, `description`, `unit_cost`, `weight`, `weight_unit`, `brand`), a pricing-tier field (`price.{tier}.value`), or an attribute field (`attributes.{name}`)\n- `mappings[].parsers` (optional, array) - Value-transformation rules applied in order when the mapping is resolved; each entry has a `rule` name and `args`\n\n**Response:**\n- `data.integration_instance_id` - The integration instance ID\n- `data.integration_name` - The integration instance name\n- `data.mappings` - The new effective mapping list (defaults merged with the saved custom mappings)\n- `data.effective_mappings` - Same merged list as `mappings`\n- `message` - Confirmation message","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"name\",\n      \"sku_field\": \"item_name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"wholesale_price\",\n      \"sku_field\": \"price.Wholesale.value\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"brand_name\",\n      \"sku_field\": \"brand\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Faire - Main Brand\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps sku to sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps name to item_name\"\n      },\n      {\n        \"listing_field\": \"wholesale_price\",\n        \"sku_field\": \"price.Wholesale.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps wholesale_price to price.Wholesale.value\"\n      },\n      {\n        \"listing_field\": \"brand_name\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand_name → brand\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps sku to sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps name to item_name\"\n      },\n      {\n        \"listing_field\": \"wholesale_price\",\n        \"sku_field\": \"price.Wholesale.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps wholesale_price to price.Wholesale.value\"\n      },\n      {\n        \"listing_field\": \"brand_name\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand_name → brand\"\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Faire Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/inventory?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","faire","inventory"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default: 10)","disabled":true}]},"description":"**Legacy** — prefer the per-instance route `GET /api/faire/instances/{integrationInstance}/inventory`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nList Faire product variant inventory levels (product options) for a specific integration instance.\n\n**Tenant resolution (multi-instance safety):**\nBoth shapes are accepted, in priority order:\n- `filter[integration_instance_ids]` (preferred, Amazon-unified plural form; comma-separated CSV — first ID wins)\n- `filter[instance_id]` (legacy singular)\n- `?instance_id=` query string fallback\n- body `instance_id` (POST/PUT only)\n\nIf none resolve to an existing FaireIntegrationInstance the endpoint returns an empty/zeroed payload — it does NOT silently fall back to the first tenant's data.\n\n**Empty-paginator response** when no instance resolves.\n\n---\n\nList Faire product variant inventory levels (product options) for a specific integration instance.\n\nThis endpoint returns inventory data at the variant/SKU level (FaireProductOption records).\n\n**Query Parameters:**\n- `instance_id` (optional) - Filter to a specific integration instance. Defaults to the first instance.\n- `page` (optional) - Page number (default: 1)\n- `per_page` (optional) - Items per page (default: 10)\n\n**Response Fields per Variant:**\n- `id` - Internal product option ID\n- `faire_product_id` - Faire product ID\n- `faire_variant_id` - Faire variant ID\n- `sku` - SKU code\n- `name` - Variant name\n- `inventory_quantity` - Current inventory quantity in the linked warehouse\n- `faire_inventory_quantity` - Last-pushed inventory quantity on Faire\n- `wholesale_price` - Wholesale price in cents\n- `product_name` - Parent product name (when loaded)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/inventory?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","faire","inventory"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 301,\n      \"faire_product_id\": \"p_xyz456abc\",\n      \"faire_variant_id\": \"pv_var001\",\n      \"sku\": \"CANDLE-SM-RED\",\n      \"name\": \"Red\",\n      \"inventory_quantity\": 120,\n      \"faire_inventory_quantity\": 115,\n      \"wholesale_price\": 1500,\n      \"product_name\": \"Small Candle\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 10,\n  \"total\": 35,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Faire Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/inventory/summary","host":["{{baseUrl}}"],"path":["api","faire","inventory","summary"]},"description":"**Legacy** — prefer the per-instance route `GET /api/faire/instances/{integrationInstance}/inventory/summary`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAggregate inventory comparison metrics for a Faire integration instance (total tracked items, count in-sync with Faire, count needing an update, count never fetched).\n\n**Tenant resolution (multi-instance safety):**\nBoth shapes are accepted, in priority order:\n- `filter[integration_instance_ids]` (preferred, Amazon-unified plural form; comma-separated CSV — first ID wins)\n- `filter[instance_id]` (legacy singular)\n- `?instance_id=` query string fallback\n- body `instance_id` (POST/PUT only)\n\nIf none resolve to an existing FaireIntegrationInstance the endpoint returns an empty/zeroed payload — it does NOT silently fall back to the first tenant's data.\n\n**Zeroed response** when no instance resolves:\n```json\n{\n  \"data\": {\n    \"total_items\": 0,\n    \"in_sync\": 0,\n    \"needs_update\": 0,\n    \"never_fetched\": 0\n  }\n}\n```"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/inventory/summary","host":["{{baseUrl}}"],"path":["api","faire","inventory","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 142,\n    \"in_sync\": 120,\n    \"needs_update\": 18,\n    \"never_fetched\": 4\n  }\n}"}]},{"name":"Push Inventory to Faire","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/inventory/push","host":["{{baseUrl}}"],"path":["api","faire","inventory","push"]},"description":"Push current inventory levels from the linked warehouse to Faire.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body:**\n- `instance_id` (required) - The ID of the integration instance to push inventory for\n\n**Behavior:**\n- Dispatches a background job immediately\n- The job reads inventory quantities from the linked warehouse and updates each Faire product variant via the Faire API\n- Useful for an immediate manual push when automatic sync is not running\n- Progress can be tracked via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID.","body":{"mode":"raw","raw":"{\n  \"instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/inventory/push","host":["{{baseUrl}}"],"path":["api","faire","inventory","push"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 145\n  },\n  \"message\": \"Inventory push started\"\n}"}]},{"name":"Refresh Inventory Snapshot","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/faire/inventory/refresh","host":["{{baseUrl}}"],"path":["api","faire","inventory","refresh"]},"description":"Refresh the local inventory snapshot by pulling current inventory levels from the Faire API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body:**\n- `instance_id` (required) - The ID of the integration instance to refresh inventory for\n\n**Behavior:**\n- Dispatches a background job immediately\n- The job pulls inventory levels from Faire and updates the local `faire_inventory_quantity` field on each product option\n- Use this to reconcile local data against Faire when discrepancies are suspected\n- Progress can be tracked via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID.","body":{"mode":"raw","raw":"{\n  \"instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/inventory/refresh","host":["{{baseUrl}}"],"path":["api","faire","inventory","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 146\n  },\n  \"message\": \"Inventory refresh started\"\n}"}]},{"name":"List Faire Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"List the inventory comparison for a Faire integration instance — one row per Faire listing/variant, comparing the SKU.io quantity against the last-known quantity on Faire.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRows come from a locally cached snapshot that is kept current by the fetch, push, and recache actions (and by the scheduled inventory sync). Each row's `status` is derived as:\n- `needs_recalc` — the SKU.io quantity is flagged for recalculation and the row is excluded from pushes until recached\n- `synced` — quantities match (negative SKU.io quantities are treated as 0 for the comparison)\n- `variance` — quantities differ; the row will be included in the next push\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Query Parameters:**\n- `page` (optional) - Page number (default: 1)\n- `per_page` (optional) - Results per page (default: 10)\n- `sort` (optional) - Prefix with `-` for descending. Allowed: `id`, `sku_quantity`, `sales_channel_quantity`, `sales_channel_quantity_updated_at`, `sales_channel_quantity_synced_at`, `created_at`, `updated_at` (default: `-id`)\n- `filter[search]` (optional) - Fuzzy search across listing SKU, listing title, and SKU.io product SKU\n- `filter[status.is]` (optional) - `synced`, `variance`, or `needs_recalc` (aliases `in_sync`, `needs_update` accepted); `status.is_one_of` takes a comma-separated list, `status.is_not` excludes one value\n- `filter[listing_sku.*]` / `filter[title.*]` (optional) - Text filters with operators: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty\n- `filter[sku_quantity.*]` / `filter[sales_channel_quantity.*]` (optional) - Numeric filters with operators: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty\n- `filter[sales_channel_quantity_updated_at.*]`, `filter[sales_channel_quantity_synced_at.*]`, `filter[created_at.*]`, `filter[updated_at.*]` (optional) - Datetime filters with operators: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days\n- `filter_groups` (optional) - Base64-encoded JSON tree of nested AND/OR filter groups\n\n**Response:**\nPaginated list. Each row contains:\n- `id` - Inventory cache row ID\n- `product_listing_id` - SKU.io product listing ID\n- `document_id` - Faire variant record ID\n- `sku` - Listing SKU (falls back to the Faire variant SKU)\n- `title` - Listing title (falls back to the Faire product name)\n- `product_sku` - Linked SKU.io product SKU\n- `sku_quantity` - Current SKU.io sellable quantity\n- `sales_channel_quantity` - Last-known quantity on Faire (null if never fetched)\n- `variance` - SKU.io quantity (clamped at 0) minus the Faire quantity\n- `change_needed` - Quantity delta a push would send (null if the Faire quantity was never fetched)\n- `status` - `synced`, `variance`, or `needs_recalc`\n- `is_sku_recalculation_needed` - True when the SKU.io quantity is stale and pending recalculation\n- `sales_channel_quantity_updated_at` - When the Faire quantity was last fetched\n- `sales_channel_quantity_synced_at` - When a quantity was last pushed to Faire\n- `sku_quantity_updated_at` - When the SKU.io quantity was last recalculated\n- `created_at` / `updated_at` - Cache row timestamps\n- `faire_variant_id` - Faire variant ID\n- `faire_listing_url` - Listing URL on Faire (currently always null)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"product_listing_id\": 2048,\n      \"document_id\": 301,\n      \"sku\": \"CANDLE-SM-RED\",\n      \"title\": \"Small Candle - Red\",\n      \"product_sku\": \"CANDLE-SM-RED\",\n      \"sku_quantity\": 120,\n      \"sales_channel_quantity\": 115,\n      \"variance\": 5,\n      \"change_needed\": 5,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sales_channel_quantity_updated_at\": \"2026-07-06T14:22:10.000000Z\",\n      \"sales_channel_quantity_synced_at\": \"2026-07-05T09:00:03.000000Z\",\n      \"sku_quantity_updated_at\": \"2026-07-06T13:58:41.000000Z\",\n      \"created_at\": \"2026-05-01T10:15:00.000000Z\",\n      \"updated_at\": \"2026-07-06T14:22:10.000000Z\",\n      \"faire_variant_id\": \"pv_var001\",\n      \"faire_listing_url\": null\n    },\n    {\n      \"id\": 511,\n      \"product_listing_id\": 2047,\n      \"document_id\": 300,\n      \"sku\": \"CANDLE-SM-BLUE\",\n      \"title\": \"Small Candle - Blue\",\n      \"product_sku\": \"CANDLE-SM-BLUE\",\n      \"sku_quantity\": 48,\n      \"sales_channel_quantity\": 48,\n      \"variance\": 0,\n      \"change_needed\": 0,\n      \"status\": \"synced\",\n      \"is_sku_recalculation_needed\": false,\n      \"sales_channel_quantity_updated_at\": \"2026-07-06T14:22:10.000000Z\",\n      \"sales_channel_quantity_synced_at\": \"2026-07-06T09:00:02.000000Z\",\n      \"sku_quantity_updated_at\": \"2026-07-06T08:45:19.000000Z\",\n      \"created_at\": \"2026-05-01T10:15:00.000000Z\",\n      \"updated_at\": \"2026-07-06T14:22:10.000000Z\",\n      \"faire_variant_id\": \"pv_var002\",\n      \"faire_listing_url\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 10,\n  \"total\": 35,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Faire Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Get aggregate inventory sync statistics for a Faire integration instance, computed from the same cached snapshot as the inventory list.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Response:**\n- `total_items` - Total listings tracked for this instance\n- `in_sync` - Listings whose SKU.io and Faire quantities match\n- `with_variance` - Listings whose quantities differ (would be included in the next push)\n- `needs_recalculation` - Listings whose SKU.io quantity is flagged as stale\n- `in_stock` - Listings with a positive quantity on Faire (relevant for FBF instances)\n- `out_of_stock` - Listings with zero quantity on Faire (relevant for FBF instances)\n- `last_fetch_at` - Most recent time a quantity was fetched from Faire (null if never)\n- `last_sync_at` - Most recent time a quantity was pushed to Faire (null if never)\n- `needs_update` - Legacy alias of `with_variance`\n- `never_fetched` - Listings whose Faire quantity has never been fetched\n\nIf the instance has no sales channel yet, all counts return 0 and the timestamps return null."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 35,\n    \"in_sync\": 28,\n    \"with_variance\": 5,\n    \"needs_recalculation\": 2,\n    \"in_stock\": 30,\n    \"out_of_stock\": 5,\n    \"last_fetch_at\": \"2026-07-06T14:22:10.000000Z\",\n    \"last_sync_at\": \"2026-07-06T09:00:02.000000Z\",\n    \"needs_update\": 5,\n    \"never_fetched\": 3\n  }\n}"}]},{"name":"Refresh Inventory from Faire","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/fetch","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","fetch"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Pull current inventory quantities from Faire into the local snapshot for a Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately and returns — the refresh runs asynchronously\n- The job walks Faire's paginated products feed and reads each variant's available quantity, updating the cached Faire quantity and its fetched-at timestamp per listing\n- Works for both FBM and FBF instances\n- Progress can be monitored via the returned `tracked_job_log_id`\n\n**Response:**\nReturns immediately with a tracked job log ID:\n- `data.tracked_job_log_id` - ID for monitoring the background refresh\n- `message` - Confirmation that the refresh started"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/fetch","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","fetch"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 146\n  },\n  \"message\": \"Inventory refresh started\"\n}"}]},{"name":"Push Inventory to Faire","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/push","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","push"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Push SKU.io inventory quantities to Faire for a Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately and returns — the push runs asynchronously\n- Only listings with a variance between the SKU.io and Faire quantities are pushed; rows flagged as needing recalculation are excluded until they are recached\n- Quantities are clamped at a minimum of 0 before being sent to Faire\n- Each successfully pushed listing is marked synced with a fresh synced-at timestamp\n- Outbound inventory sync must be enabled on the instance — when it is disabled, the job pushes nothing\n- Progress can be monitored via the returned `tracked_job_log_id`\n\n**Not available for FBF instances** — returns 422, since Faire manages inventory in FBF (Fulfilled by Faire) mode.\n\n**Response:**\nReturns immediately with a tracked job log ID:\n- `data.tracked_job_log_id` - ID for monitoring the background push\n- `message` - Confirmation that the push started"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/push","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","push"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 145\n  },\n  \"message\": \"Inventory push started\"\n}"}]},{"name":"Recache Inventory Quantities","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]},"description":"Recalculate the SKU.io sellable quantities cached for every listing on a Faire integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path Parameters:**\n- `integrationInstance` - The ID of the integration instance\n\n**Behavior:**\n- Dispatches a background job immediately and returns — the recache runs asynchronously\n- The job marks every cached row for the instance as needing recalculation, then recomputes each listing's SKU.io quantity and writes fresh values with updated timestamps\n- Use this when SKU.io quantities in the inventory comparison look stale, or to clear rows stuck in the `needs_recalc` status so the next push can include them\n- Progress can be monitored via the returned `tracked_job_log_id`\n\n**Not available for FBF instances** — returns 422, since Faire manages inventory in FBF (Fulfilled by Faire) mode.\n\n**Response:**\nReturns immediately with a tracked job log ID:\n- `data.tracked_job_log_id` - ID for monitoring the background recache\n- `message` - Confirmation that the recache started"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/faire/instances/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","faire","instances",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"Faire integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 147\n  },\n  \"message\": \"Inventory recache started\"\n}"}]},{"name":"Receive Faire Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/faire","host":["{{baseUrl}}"],"path":["api","webhooks","faire"]},"description":"Single webhook endpoint that receives every Faire event. Faire identifies the event via the `X-Faire-Webhook-Topic` header — the request body shape varies by topic.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** none — Faire calls this endpoint directly. The `X-Faire-Brand-Token` header identifies the integration instance.\n\n**Required headers:**\n- `X-Faire-Webhook-Topic` — one of `ORDER_CREATED`, `ORDER_UPDATED`, `INVENTORY_QUANTITY_UPDATED` (Faire also accepts `X-Faire-Topic`)\n- `X-Faire-Brand-Token` — brand token used to look up the integration instance\n\n**Supported topics:**\n- `ORDER_CREATED` — new order placed; full order payload (default body shown here)\n- `ORDER_UPDATED` — order state change, shipments added, etc.\n- `INVENTORY_QUANTITY_UPDATED` — variant-level inventory update from Faire\n\nUse the saved examples below to see each event's payload shape.","body":{"mode":"raw","raw":"{\n  \"id\": \"bo_abc123xyz\",\n  \"display_id\": \"FO-0001\",\n  \"retailer\": {\n    \"id\": \"b_xyz789\",\n    \"name\": \"The Boutique Shop\",\n    \"state\": \"CA\",\n    \"country_code\": \"US\"\n  },\n  \"items\": [\n    {\n      \"id\": \"bi_item001\",\n      \"product_id\": \"p_xyz456abc\",\n      \"variant_id\": \"pv_var001\",\n      \"sku\": \"CANDLE-SM-RED\",\n      \"quantity\": 10,\n      \"unit_price\": 1500\n    }\n  ],\n  \"subtotal\": 15000,\n  \"total\": 15000,\n  \"currency_code\": \"USD\",\n  \"created_at\": \"2026-04-20T08:30:00Z\",\n  \"state\": \"NEW\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhooks/faire","host":["{{baseUrl}}"],"path":["api","webhooks","faire"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"ORDER_CREATED webhook processed\"\n}"}]}]},{"name":"Amazon","item":[{"name":"List Amazon Integration Instances (Simple Dropdown)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/list","host":["{{baseUrl}}"],"path":["api","amazon","list"]},"description":"Simple flat list of all Amazon integration instances suitable for use in dropdown selectors and integration filters in the UI. Returns just `{id, name}` for each instance with no pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/list","host":["{{baseUrl}}"],"path":["api","amazon","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Amazon US - Main\"\n    },\n    {\n      \"id\": 4,\n      \"name\": \"Amazon CA - Secondary\"\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Amazon UK\"\n    }\n  ]\n}"}]},{"name":"Show Amazon Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Show a single Amazon integration instance with its salesChannel and integration relationships eager-loaded. Returns an Amazon integration instance object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon US - Main\",\n    \"connection_settings\": {\n      \"selling_partner_id\": \"A1B2C3D4E5F6G7\",\n      \"refresh_token\": \"Atzr|IwEBI...\",\n      \"access_token\": \"Atza|IwEBI...\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01\",\n      \"store_id\": 12,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 200,\n      \"cogs_nominal_code_id\": 500,\n      \"shipping_revenue_nominal_code_id\": 210,\n      \"shipping_refund_nominal_code_id\": 211,\n      \"sales_returns_allowances_nominal_code_id\": 215,\n      \"is_fba_enabled\": true,\n      \"fba_inventory_tracking_start_date\": \"2026-01-01\",\n      \"batch_sales_order_invoices\": true,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"reconcile_ledger\": true,\n      \"automatically_create_warehouse_transfers_from_inbounds\": false,\n      \"automatically_create_purchase_orders_from_inbounds\": false,\n      \"automatically_create_warehouse_transfers_from_removal_orders\": false,\n      \"awd_initial_inventory_imported\": false,\n      \"awd_initial_inventory_confirmed_no_inventory\": false,\n      \"setup_step\": \"finalize\",\n      \"setup_completed\": true\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"sales_channel\": {\n      \"id\": 9,\n      \"store_id\": 12,\n      \"integration_instance_id\": 3\n    },\n    \"connection_status\": \"connected\",\n    \"account_status_signal\": null,\n    \"pricing_health_signal\": null,\n    \"fee_promotion_signals\": [],\n    \"integration_name\": \"Amazon\",\n    \"store\": {\n      \"id\": 12,\n      \"name\": \"Main Store\"\n    },\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-05-20T14:30:00.000000Z\"\n  }\n}"}]},{"name":"Update Amazon Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Full or partial update of an Amazon integration instance. Validated by `UpdateAmazonIntegrationData` (all fields Optional). Supports both `PUT` (full) and `PATCH` (partial with deep-merge of `integration_settings` / `connection_settings`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf `is_fba_enabled` changes, the controller dispatches the FBA state-change handler. If `sync_sales_order_invoices_to_accounting` or `sync_sales_credit_to_accounting` change, the accounting sync state is updated. If `pricing.masterOfPrice.name` changes, a background job is dispatched. If `inventory` changes, the full inventory cache is invalidated. If `store_id` changes, the SalesChannel row is re-pointed.","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon US - Main (renamed)\",\n  \"is_automatic_sync_enabled\": true,\n  \"connection_settings\": {\n    \"selling_partner_id\": \"A1B2C3D4E5F6G7\",\n    \"refresh_token\": \"Atzr|IwEBI...\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2026-01-01\",\n    \"store_id\": 12,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"is_fba_enabled\": true,\n    \"fba_inventory_tracking_start_date\": \"2026-01-01\",\n    \"batch_sales_order_invoices\": true,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true,\n    \"reconcile_ledger\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon US - Main (renamed)\",\n    \"is_automatic_sync_enabled\": true,\n    \"connection_settings\": {\n      \"selling_partner_id\": \"A1B2C3D4E5F6G7\",\n      \"refresh_token\": \"Atzr|IwEBI...\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01\",\n      \"store_id\": 12,\n      \"is_fba_enabled\": true,\n      \"reconcile_ledger\": true\n    },\n    \"connection_status\": \"connected\",\n    \"integration_name\": \"Amazon\",\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-05-29T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Amazon Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Soft-delete an Amazon integration instance. Dispatches a background job to clean up the linked sales channel and related records asynchronously. Returns 204 No Content.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Amazon Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon","host":["{{baseUrl}}"],"path":["api","amazon"]},"description":"List all Amazon integration instances. Registered automatically by the `Route::salesChannel('amazon', ...)` macro — this is the standard `apiResource` index returning the configured list view response (paginated Amazon integration instance object collection).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon","host":["{{baseUrl}}"],"path":["api","amazon"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Amazon US - Main\",\n      \"connection_settings\": {\n        \"selling_partner_id\": \"A1B2C3D4E5F6G7\",\n        \"refresh_token\": \"Atzr|IwEBI...\",\n        \"access_token\": \"Atza|IwEBI...\"\n      },\n      \"integration_settings\": {\n        \"start_date\": \"2026-01-01\",\n        \"store_id\": 12,\n        \"auto_link_products\": true,\n        \"auto_create_products\": false,\n        \"is_fba_enabled\": true,\n        \"reconcile_ledger\": true,\n        \"batch_sales_order_invoices\": true\n      },\n      \"is_automatic_sync_enabled\": true,\n      \"connection_status\": \"connected\",\n      \"account_status_signal\": null,\n      \"pricing_health_signal\": null,\n      \"fee_promotion_signals\": [],\n      \"integration_name\": \"Amazon\",\n      \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n      \"updated_at\": \"2026-05-20T14:30:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Amazon Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon","host":["{{baseUrl}}"],"path":["api","amazon"]},"description":"Create a new Amazon integration instance. Validated by `StoreAmazonIntegrationData`. After creation the controller also ensures a PaymentType for Amazon exists, then returns the redirect URL the user must follow to authorize the SP-API connection.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields**\n- `name` (string, required) — display name for this instance\n- `integration_id` (int, required, must exist in `integrations` table) — id of the Amazon integration row\n- `country` (string, optional) — ISO country code (e.g. `US`, `CA`, `UK`)\n- `is_automatic_sync_enabled` (bool, default false)\n- `connection_settings` (object, optional) — typically populated by OAuth callback\n- `integration_settings` (object, required) — AmazonIntegrationSettingsData fields (see show response for available keys)","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon US - Main\",\n  \"integration_id\": 4,\n  \"country\": \"US\",\n  \"is_automatic_sync_enabled\": false,\n  \"connection_settings\": {\n    \"selling_partner_id\": \"A1B2C3D4E5F6G7\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2026-01-01\",\n    \"store_id\": 12,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": 200,\n    \"cogs_nominal_code_id\": 500,\n    \"shipping_revenue_nominal_code_id\": 210,\n    \"shipping_refund_nominal_code_id\": 211,\n    \"sales_returns_allowances_nominal_code_id\": 215,\n    \"is_fba_enabled\": true,\n    \"fba_inventory_tracking_start_date\": \"2026-01-01\",\n    \"batch_sales_order_invoices\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon","host":["{{baseUrl}}"],"path":["api","amazon"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon US - Main\",\n    \"integration_id\": 4,\n    \"is_automatic_sync_enabled\": false,\n    \"connection_settings\": {\n      \"selling_partner_id\": \"A1B2C3D4E5F6G7\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01\",\n      \"store_id\": 12,\n      \"is_fba_enabled\": true\n    },\n    \"created_at\": \"2026-05-29T12:00:00.000000Z\",\n    \"updated_at\": \"2026-05-29T12:00:00.000000Z\"\n  },\n  \"redirect_url\": \"https://sellercentral.amazon.com/apps/authorize/consent?application_id=amzn1.sp.solution.xxxx&state=eyJpbnN0YW5jZUlkIjozfQ&version=beta\"\n}"}]},{"name":"Update Amazon Settings (Partial)","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","settings"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Optimized partial update used by the application UI Amazon settings page. Validated by `UpdateAmazonSettingsOnlyData` — every field is Optional, so the client may send only the fields the user actually changed. Internally, root-level fields (`name`, `is_automatic_sync_enabled`) are separated from `integration_settings` fields and merged into the existing settings JSON.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the freshly reloaded Amazon integration instance object with `salesChannel.store` and `integration` eager-loaded.\n\nfbmBackup (optional): catalog-wide FBM Backup Mode default { enabled: bool, fbaThreshold: int>=0, scope: \"same_country\"|\"all_marketplaces\" }. Malformed values return 422.","body":{"mode":"raw","raw":"{\n  \"name\": \"Amazon US - Main\",\n  \"is_automatic_sync_enabled\": true,\n  \"store_id\": 12,\n  \"sales_nominal_code_id\": 200,\n  \"cogs_nominal_code_id\": 500,\n  \"shipping_revenue_nominal_code_id\": 210,\n  \"shipping_refund_nominal_code_id\": 211,\n  \"sales_returns_allowances_nominal_code_id\": 215,\n  \"batch_sales_order_invoices\": true,\n  \"sync_sales_order_invoices_to_accounting\": true,\n  \"sync_sales_credit_to_accounting\": true,\n  \"start_date\": \"2026-01-01\",\n  \"reconcile_ledger\": true,\n  \"pricing\": {\n    \"masterOfPrice\": {\n      \"name\": \"sku\"\n    }\n  },\n  \"automatically_create_warehouse_transfers_from_inbounds\": false,\n  \"automatically_create_purchase_orders_from_inbounds\": false,\n  \"automatically_create_warehouse_transfers_from_removal_orders\": false,\n  \"inbound_manager_process_error_notification_emails\": \"ops@example.com\",\n  \"selected_marketplace_ids\": [\n    \"ATVPDKIKX0DER\"\n  ],\n  \"payment_method_mappings\": [\n    {\n      \"amazon_method\": \"Other\",\n      \"payment_type_id\": 7\n    }\n  ],\n  \"fbmBackup\": {\n    \"enabled\": true,\n    \"fbaThreshold\": 0,\n    \"scope\": \"same_country\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","settings"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Amazon US - Main\",\n    \"connection_settings\": {\n      \"selling_partner_id\": \"A1B2C3D4E5F6G7\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2026-01-01\",\n      \"store_id\": 12,\n      \"sales_nominal_code_id\": 200,\n      \"cogs_nominal_code_id\": 500,\n      \"shipping_revenue_nominal_code_id\": 210,\n      \"shipping_refund_nominal_code_id\": 211,\n      \"sales_returns_allowances_nominal_code_id\": 215,\n      \"batch_sales_order_invoices\": true,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true,\n      \"reconcile_ledger\": true,\n      \"pricing\": {\n        \"masterOfPrice\": {\n          \"name\": \"sku\"\n        }\n      },\n      \"selected_marketplace_ids\": [\n        \"ATVPDKIKX0DER\"\n      ],\n      \"payment_method_mappings\": [\n        {\n          \"amazon_method\": \"Other\",\n          \"payment_type_id\": 7\n        }\n      ]\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"sales_channel\": {\n      \"id\": 9,\n      \"store_id\": 12,\n      \"integration_instance_id\": 3\n    },\n    \"connection_status\": \"connected\",\n    \"integration_name\": \"Amazon\",\n    \"store\": {\n      \"id\": 12,\n      \"name\": \"Main Store\"\n    },\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-05-29T12:00:00.000000Z\"\n  }\n}"}]},{"name":"OAuth Callback (Web)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/amazon/callback?state=tenant1_1&spapi_oauth_code=ANabcDEFghiJKLmnoPQR&selling_partner_id=A1XYZ123EXAMPLE","host":["{{baseUrl}}"],"path":["amazon","callback"],"query":[{"key":"state","value":"tenant1_1","description":"Opaque OAuth state token built by SKU.io when generating the authorization URL. Contains the tenant identifier and the integration instance ID, e.g. `<tenant>_<integration_instance_id>`. Used to validate the callback origin and re-initialize tenancy.","disabled":true},{"key":"spapi_oauth_code","value":"ANabcDEFghiJKLmnoPQR","description":"Single-use authorization code issued by Amazon LWA. Exchanged server-side for a refresh + access token pair.","disabled":true},{"key":"selling_partner_id","value":"A1XYZ123EXAMPLE","description":"The Amazon Seller Central account identifier (merchant token) of the seller who completed the OAuth consent flow. Persisted onto the integration instance connection settings.","disabled":true}]},"description":"Amazon Seller Central OAuth callback endpoint. Amazon redirects the user here after they grant or deny SP-API access in Seller Central. This endpoint is a **web** route (not under `/api`), is invoked by the user's browser (not by SKU.io frontend code), and accepts any HTTP method (`Route::any`).\n\nFlow:\n1. Validates the presence of `spapi_oauth_code` and `state` query params (400 if missing).\n2. Re-initializes tenancy from the `state` value.\n3. Loads the matching `AmazonIntegrationInstance` and exchanges the auth code for an access/refresh token via the Amazon SP-API connector.\n4. Persists the authenticator + `selling_partner_id` and marks the integration instance `sync_status = ACTIVE` and `is_automatic_sync_enabled = true`.\n5. Performs initial setup calls when not in fake-OAuth mode: fetches marketplace participations, requests initial reports, processes FBA state, and dispatches the initial Financial Event Groups + Orders refresh jobs onto the `serial` queue.\n6. Redirects the browser to `/integrations/amazon/{integrationInstanceId}/dashboard`.\n\nThe response is a 302 redirect to the Vue 2/application UI Amazon integration dashboard for the instance — there is no JSON payload."},"response":[{"name":"Found","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/amazon/callback?state=tenant1_1&spapi_oauth_code=ANabcDEFghiJKLmnoPQR&selling_partner_id=A1XYZ123EXAMPLE","host":["{{baseUrl}}"],"path":["amazon","callback"],"query":[{"key":"state","value":"tenant1_1","description":"Opaque OAuth state token built by SKU.io when generating the authorization URL. Contains the tenant identifier and the integration instance ID, e.g. `<tenant>_<integration_instance_id>`. Used to validate the callback origin and re-initialize tenancy.","disabled":true},{"key":"spapi_oauth_code","value":"ANabcDEFghiJKLmnoPQR","description":"Single-use authorization code issued by Amazon LWA. Exchanged server-side for a refresh + access token pair.","disabled":true},{"key":"selling_partner_id","value":"A1XYZ123EXAMPLE","description":"The Amazon Seller Central account identifier (merchant token) of the seller who completed the OAuth consent flow. Persisted onto the integration instance connection settings.","disabled":true}]}},"status":"Found","code":302,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"The ID of the Amazon integration instance for which to build the Amazon Seller Central OAuth authorization URL."}]},"description":"Returns the Amazon Seller Central OAuth authorization URL for the given Amazon integration instance. The frontend should redirect the user to this URL so they can grant SP-API access to SKU.io. Upon successful authorization, Amazon redirects the user back to the configured callback URL with `spapi_oauth_code`, `state`, and `selling_partner_id` query parameters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen `FakeOAuthService` is enabled in non-production environments, a fake OAuth URL is returned to allow the OAuth handshake to be tested end-to-end without contacting Amazon."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"The ID of the Amazon integration instance for which to build the Amazon Seller Central OAuth authorization URL."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://sellercentral.amazon.com/apps/authorize/consent?application_id=amzn1.sp.solution.example-app-id&state=tenant1_1&version=beta\",\n  \"errors\": [],\n  \"messages\": [],\n  \"success\": true\n}"}]},{"name":"List Fee Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"List Fee Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Create Fee Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings"]},"description":"Create Fee Mapping\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fee_type\": \"\",\n  \"financial_line_type_id\": null\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Fee Mapping","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/{feeMapping}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings",":feeMapping"],"variable":[{"key":"feeMapping","value":"","description":"The fee mapping ID."}]},"description":"Update Fee Mapping\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"financial_line_type_id\": null\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Fee Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/{feeMapping}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings",":feeMapping"],"variable":[{"key":"feeMapping","value":"","description":"The fee mapping ID."}]},"description":"Delete Fee Mapping\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Preview Recategorization","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/recategorize-historical/preview","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings","recategorize-historical","preview"]},"description":"Preview the impact of recategorizing historical settlement data based on current fee mappings (dry-run).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/recategorize-historical/preview","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings","recategorize-historical","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"affected_count\": 152,\n    \"fee_types\": [\n      \"FBAPerUnitFulfillmentFee\",\n      \"Commission\"\n    ]\n  }\n}"}]},{"name":"Recategorize Historical","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/recategorize-historical","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings","recategorize-historical"]},"description":"Recategorize historical settlement data based on current fee mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fee-mappings/recategorize-historical","host":["{{baseUrl}}"],"path":["api","amazon","unified","fee-mappings","recategorize-historical"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Historical recategorization complete\",\n  \"data\": {\n    \"updated_count\": 152\n  }\n}"}]},{"name":"List Merchant SKU Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/merchant-sku-mappings?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","amazon","unified","merchant-sku-mappings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"List Merchant SKU Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Update Merchant SKU Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/merchant-sku-mappings/bulk","host":["{{baseUrl}}"],"path":["api","amazon","unified","merchant-sku-mappings","bulk"]},"description":"Bulk Update Merchant SKU Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": []\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Merchant SKU Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/merchant-sku-mappings/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","merchant-sku-mappings",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Update Merchant SKU Mapping\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": null\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Ship From Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","ship-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List FBA inbound ship-from location mappings for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","ship-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"ship_from_location\": \"US-WEST\",\n      \"warehouse_id\": 3,\n      \"warehouse_name\": \"West Coast Warehouse\"\n    }\n  ]\n}"}]},{"name":"Update Ship From Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","ship-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Update ship-from location to warehouse mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"ship_from_location\": \"US-WEST\",\n      \"warehouse_id\": 3\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","ship-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Ship-from mappings updated successfully\"\n}"}]},{"name":"Show AWD Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Get details of a specific AWD shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"shipment_id\": \"AWD-12345\",\n    \"status\": \"SHIPPED\",\n    \"items\": [\n      {\n        \"sku\": \"WIDGET-RED\",\n        \"quantity\": 100\n      }\n    ]\n  }\n}"}]},{"name":"Refresh AWD Shipment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Refresh a specific AWD shipment from Amazon API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD shipment refreshed successfully\"\n}"}]},{"name":"Export AWD Shipment Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment","export"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Export items from a specific AWD shipment as CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/shipments/{shipment}/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","shipments",":shipment","export"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"shipment_id,sku,quantity\nAWD-12345,WIDGET-RED,100"}]},{"name":"LPN Lookup","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/lpn-lookup?lpn=LPN123456789","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","lpn-lookup"],"query":[{"key":"lpn","value":"LPN123456789","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Look up a License Plate Number (LPN) to find associated inventory items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/lpn-lookup?lpn=LPN123456789","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","lpn-lookup"],"query":[{"key":"lpn","value":"LPN123456789","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"lpn\": \"LPN123456789\",\n    \"fnsku\": \"X001ABC123\",\n    \"quantity\": 50\n  }\n}"}]},{"name":"List Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/warehouses","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List Amazon FBA warehouses/fulfillment centers for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/warehouses","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"PHX7\",\n      \"name\": \"Phoenix FC\",\n      \"country\": \"US\"\n    }\n  ]\n}"}]},{"name":"Get available fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","amazon","mappings","available-fields"]},"description":"Returns the catalog of fields that can participate in a mapping: all Amazon listing fields (`seller_sku`, `asin1`, `item_name`, `brand`, `price`, etc.) and all SKU.io product fields (static fields like `sku`, `name`, plus dynamic fields like product pricing tiers, supplier pricing tiers, and custom product attributes). This endpoint is global (not scoped to an integration instance) and is used to populate the source/target dropdowns in the mapping configuration UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","amazon","mappings","available-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"amazon_fields\": {\n      \"seller_sku\": {\n        \"name\": \"seller_sku\",\n        \"label\": \"Seller SKU\",\n        \"type\": \"string\",\n        \"description\": \"Amazon seller SKU\",\n        \"group\": \"Identifiers\"\n      },\n      \"asin1\": {\n        \"name\": \"asin1\",\n        \"label\": \"ASIN\",\n        \"type\": \"string\",\n        \"description\": \"Amazon Standard Identification Number\",\n        \"group\": \"Identifiers\"\n      },\n      \"item_name\": {\n        \"name\": \"item_name\",\n        \"label\": \"Item Name\",\n        \"type\": \"string\",\n        \"description\": \"Amazon listing title\",\n        \"group\": \"Product Info\"\n      },\n      \"brand\": {\n        \"name\": \"brand\",\n        \"label\": \"Brand\",\n        \"type\": \"string\",\n        \"description\": \"Product brand\",\n        \"group\": \"Product Info\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"decimal\",\n        \"description\": \"Listing price\",\n        \"group\": \"Pricing\"\n      },\n      \"quantity\": {\n        \"name\": \"quantity\",\n        \"label\": \"Quantity\",\n        \"type\": \"integer\",\n        \"description\": \"Available inventory quantity\",\n        \"group\": \"Inventory\"\n      }\n    },\n    \"sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Stock Keeping Unit\",\n        \"group\": \"Basic Info\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Product name/title\",\n        \"group\": \"Basic Info\"\n      },\n      \"unit_cost\": {\n        \"name\": \"unit_cost\",\n        \"label\": \"Unit Cost\",\n        \"type\": \"decimal\",\n        \"description\": \"Product cost price\",\n        \"group\": \"Pricing\"\n      },\n      \"price.Default.value\": {\n        \"name\": \"price.Default.value\",\n        \"label\": \"Pricing: Default\",\n        \"type\": \"decimal\",\n        \"description\": \"Price value for Default pricing tier\",\n        \"group\": \"Pricing Tiers\"\n      },\n      \"attributes.Color\": {\n        \"name\": \"attributes.Color\",\n        \"label\": \"Attribute: Color\",\n        \"type\": \"string\",\n        \"description\": \"Product attribute: Color\",\n        \"group\": \"Product Attributes\"\n      }\n    }\n  }\n}"}]},{"name":"Get mappings for integration instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"ID of the Amazon integration instance (AmazonIntegrationInstance route-model binding)"}]},"description":"Returns the full field-mapping picture for the given Amazon integration instance:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `mappings` / `effective_mappings`: the merged set of listing→sku field mappings that are actually applied during sync (custom mappings override defaults).\n- `default_mappings`: the built-in system defaults (e.g. `seller_sku → sku`, `item_name → item_name`, `brand → brand`, `manufacturer → vendor`, `price → price.<default-tier>.value`).\n- `custom_mappings`: any per-instance overrides that have been persisted via the update endpoint.\n- `available_amazon_fields`: the same catalog of Amazon listing fields returned by `GET /api/amazon/mappings/available-fields`.\n- `available_sku_fields`: the same catalog of SKU.io fields (static + dynamic pricing tiers / supplier pricing tiers / attributes)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"ID of the Amazon integration instance (AmazonIntegrationInstance route-model binding)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Acme US Amazon\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps seller_sku to sku\"\n      },\n      {\n        \"listing_field\": \"item_name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps item_name to item_name\"\n      },\n      {\n        \"listing_field\": \"brand\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand → brand\"\n      }\n    ],\n    \"available_amazon_fields\": {\n      \"seller_sku\": {\n        \"name\": \"seller_sku\",\n        \"label\": \"Seller SKU\",\n        \"type\": \"string\",\n        \"description\": \"Amazon seller SKU\",\n        \"group\": \"Identifiers\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Stock Keeping Unit\",\n        \"group\": \"Basic Info\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps seller_sku to sku\"\n      },\n      {\n        \"listing_field\": \"item_name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps item_name to item_name\"\n      },\n      {\n        \"listing_field\": \"brand\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps brand to brand\"\n      },\n      {\n        \"listing_field\": \"manufacturer\",\n        \"sku_field\": \"vendor\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps manufacturer to vendor\"\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price.Default.value\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps price to price.Default.value\"\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"brand\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: brand → brand\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps seller_sku to sku\"\n      }\n    ]\n  }\n}"}]},{"name":"Update mappings for integration instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"ID of the Amazon integration instance (AmazonIntegrationInstance route-model binding)"}]},"description":"Persists the full set of custom field mappings for the given Amazon integration instance. The payload completely replaces the previously stored custom mappings for the `listings` mapping group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body (validated via `UpdateAmazonFieldMappingsData`):\n- `mappings` (array, required): list of mapping entries. Each entry contains:\n  - `listing_field` (string, required): the Amazon listing field name (e.g. `seller_sku`, `item_name`, `brand`, `price`). Must match one of the keys returned by `GET /api/amazon/mappings/available-fields` under `amazon_fields`.\n  - `sku_field` (string, required): the SKU.io target field. Either a static field (e.g. `sku`, `name`, `vendor`), a pricing tier path (e.g. `price.Default.value`), a supplier pricing tier path (e.g. `supplier_pricing.Wholesale.value`), or an attribute path (e.g. `attributes.Color`).\n  - `parsers` (array, required): zero or more parser transformations applied in order to the incoming Amazon value before it is written to the SKU.io field. Each parser has a `rule` (must be one of the supported `FieldParserFactory::SUPPORTED_PARSERS` rules) and a stringified `args` payload.\n\nThe response echoes back the integration instance id/name plus the updated `mappings` and `effective_mappings` (custom merged on top of defaults).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"seller_sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"item_name\",\n      \"sku_field\": \"name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"brand\",\n      \"sku_field\": \"brand\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"price\",\n      \"sku_field\": \"price.Default.value\",\n      \"parsers\": [\n        {\n          \"rule\": \"trim\",\n          \"args\": \"\"\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"ID of the Amazon integration instance (AmazonIntegrationInstance route-model binding)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Acme US Amazon\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: seller_sku → sku\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: seller_sku → sku\"\n      },\n      {\n        \"listing_field\": \"item_name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": [],\n        \"source\": \"default\",\n        \"description\": \"Maps item_name to item_name\"\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]},"description":"List every shipping method mapping for the Amazon integration's sales channel. Each row pairs an Amazon shipping method name (e.g. \"Standard\", \"Expedited\") with an optional internal SKU.io shipping method (eager-loaded with its carrier). Returns 404 if the integration has no sales channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 21,\n      \"sales_channel_id\": 9,\n      \"sales_channel_method\": \"Econ US Dom\",\n      \"shipping_method_id\": null,\n      \"shipping_method\": null,\n      \"created_at\": \"2025-06-13T15:50:43.000000Z\",\n      \"updated_at\": \"2025-06-13T15:50:43.000000Z\"\n    },\n    {\n      \"id\": 22,\n      \"sales_channel_id\": 9,\n      \"sales_channel_method\": \"Expedited\",\n      \"shipping_method_id\": 2,\n      \"shipping_method\": {\n        \"id\": 2,\n        \"name\": \"2nd Day Air AM\",\n        \"full_name\": \"UPS 2nd Day Air AM\",\n        \"carrier_id\": 1,\n        \"carrier_name\": \"UPS\"\n      },\n      \"created_at\": \"2025-06-13T15:50:43.000000Z\",\n      \"updated_at\": \"2026-06-02T20:27:59.000000Z\"\n    }\n  ]\n}"}]},{"name":"Save Shipping Method Mappings (bulk upsert)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]},"description":"Bulk upsert mappings. Each row is matched by (sales_channel_id, sales_channel_method); existing rows are updated, new method names create rows. A null shipping_method_id clears the mapping but keeps the row. After each upsert, the new shipping_method_id is propagated to all open sales orders (order_status != closed) for that sales_channel + requested_shipping_method, so the SKU.io SO display stays in sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- mappings — required, array, min:1\n- mappings.*.sales_channel_method — required, string, max:255\n- mappings.*.shipping_method_id — nullable, integer, exists:shipping_methods,id\n\nAuthentication: Bearer token.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_method\": \"Standard\",\n      \"shipping_method_id\": 1\n    },\n    {\n      \"sales_channel_method\": \"Expedited\",\n      \"shipping_method_id\": 2\n    },\n    {\n      \"sales_channel_method\": \"NextDay\",\n      \"shipping_method_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"sales_channel_id\": 9,\n      \"sales_channel_method\": \"Standard\",\n      \"shipping_method_id\": 1,\n      \"shipping_method\": {\n        \"id\": 1,\n        \"name\": \"2nd Day Air\",\n        \"full_name\": \"UPS 2nd Day Air\",\n        \"carrier_id\": 1,\n        \"carrier_name\": \"UPS\"\n      },\n      \"created_at\": \"2025-06-13T09:31:47.000000Z\",\n      \"updated_at\": \"2026-06-02T20:27:59.000000Z\"\n    }\n  ],\n  \"message\": \"Shipping method mappings saved.\"\n}"}]},{"name":"Delete Shipping Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings",":mapping"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"},{"key":"mapping","value":"22","description":"ShippingMethodMappingsSalesChannelToSku ID"}]},"description":"Delete a single shipping method mapping. Open sales orders that requested this shipping method (and belong to the same sales_channel) have their shipping_method_id cleared so SO display stays consistent. Returns 404 if the mapping belongs to a different integration's sales channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/{mapping}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings",":mapping"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"},{"key":"mapping","value":"22","description":"ShippingMethodMappingsSalesChannelToSku ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Import Shipping Method Mappings (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings","import"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]},"description":"Bulk import shipping method mappings from a CSV upload. Existing rows with the same amazon_method are updated, new method names create rows. Rows with an unresolvable shipping_method_id or shipping_method_full_name are skipped and reported in the response's errors array (the rest of the import still succeeds). Same propagation to open sales orders as the bulk save endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nContent-Type: multipart/form-data\n\nValidation:\n- file — required, file, mimes:csv,txt, max:5120 (KB)\n\nAuthentication: Bearer token.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings","import"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 2,\n    \"updated\": 4,\n    \"skipped\": 1,\n    \"errors\": [\n      {\n        \"row\": 5,\n        \"amazon_method\": \"UnknownPlan\",\n        \"message\": \"Shipping method not found (use a known shipping_method_id or shipping_method_full_name, or leave blank to clear the mapping).\"\n      }\n    ]\n  },\n  \"message\": \"2 created, 4 updated, 1 skipped, 1 error(s).\"\n}"}]},{"name":"Export Shipping Method Mappings (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings","export"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]},"description":"Stream every shipping method mapping for the integration as a CSV download. Header row: amazon_method,shipping_method_id,shipping_method_full_name,carrier_name. Round-trip-compatible with the import endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse Content-Type: text/csv (file download named amazon-shipping-mappings-{instanceId}-{date}.csv).\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/shipping-method-mappings/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","shipping-method-mappings","export"],"variable":[{"key":"integrationInstance","value":"10","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"amazon_method,shipping_method_id,shipping_method_full_name,carrier_name\n\"Econ US Dom\",,,\nExpedited,2,\"UPS 2nd Day Air AM\",UPS\nNextDay,,,\nSecondDay,,,\nStandard,1,\"UPS 2nd Day Air\",UPS\n\"Std US D2D Dom\",,,\n"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders?page=1&limit=20&search=&sort=-id&archived=0","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"limit","value":"20","description":"Maximum number of results to return.","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"sort","value":"-id","description":"Prefix with - for descending","disabled":true},{"key":"archived","value":"0","description":"0 = active, 1 = archived","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List Amazon orders for an integration instance (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params:\n- page, limit: pagination\n- search: text search\n- sort: sort field (prefix with - for desc)\n- archived: 0 or 1"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders?page=1&limit=20&search=&sort=-id&archived=0","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"limit","value":"20","description":"Maximum number of results to return.","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"sort","value":"-id","description":"Prefix with - for descending","disabled":true},{"key":"archived","value":"0","description":"0 = active, 1 = archived","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"AmazonOrderId\": \"114-1234567-1234567\",\n      \"OrderStatus\": \"Shipped\",\n      \"PurchaseDate\": \"2024-06-01T10:00:00Z\",\n      \"LastUpdateDate\": \"2024-06-03T08:00:00Z\",\n      \"integration_instance_id\": 1,\n      \"sku_sales_order\": {\n        \"id\": 55,\n        \"number\": \"SO-2024-0055\"\n      },\n      \"archived_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 20,\n  \"total\": 1250\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]},"description":"Get details of a specific Amazon order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"AmazonOrderId\": \"114-1234567-1234567\",\n    \"OrderStatus\": \"Shipped\",\n    \"PurchaseDate\": \"2024-06-01T10:00:00Z\",\n    \"sku_sales_order\": {\n      \"id\": 55,\n      \"number\": \"SO-2024-0055\"\n    }\n  }\n}"}]},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]},"description":"Delete a single Amazon order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order deleted successfully\"\n}"}]},{"name":"Archive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]},"description":"Archive a single Amazon order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]},"description":"Unarchive a single Amazon order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archive multiple Amazon orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- ids: array of integers (required_without apply_to_all)\n- apply_to_all: boolean\n- filters: array of filter conditions","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unarchive multiple Amazon orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders unarchived successfully\",\n  \"unarchived_count\": 3\n}"}]},{"name":"Bulk Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Delete multiple Amazon orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders deleted successfully\",\n  \"deleted_count\": 3\n}"}]},{"name":"Create SKU Orders from Amazon Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Create SKU.io sales orders from this instance's Amazon orders. Runs synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers, optional) — internal Amazon order record IDs (the SKU.io row ids, not Amazon marketplace order numbers) to convert. When specific ids are given, the configured order start-date restriction is bypassed and the response includes the created sales orders.\n- create_all_orders (boolean, default false) — set true to convert all pending orders regardless of the integration's configured order start date (the \"Create All\" behaviour).\n- filters (string, optional) — JSON string in the same flat-filter format as the orders list ({\"conjunction\",\"filterSet\":[...]}). When present, ids is overwritten server-side with the order ids matching the filter set for this instance.\n\nWhen neither ids nor create_all_orders is provided, all pending orders dated after the integration's configured order start date are converted. For each created sales order, automated fulfillment rules are evaluated by a background job. When specific ids all fail to convert, a 422 is returned with the first failure reason (for example an unmapped product, or an order currency that does not exist in Settings > Currencies).\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1024,\n    1025\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created_sales_orders\": [\n      {\n        \"id\": 8817,\n        \"sales_order_number\": \"SO-2026-08817\"\n      },\n      {\n        \"id\": 8818,\n        \"sales_order_number\": \"SO-2026-08818\"\n      }\n    ]\n  },\n  \"message\": \"Sku.io sales orders successfully created\",\n  \"status\": \"success\"\n}"}]},{"name":"Refresh Orders from Amazon","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Refresh this instance's Amazon orders from the Amazon Selling Partner API. Queues a background job on a serialized queue that pulls new and updated orders since the last sync; the request returns immediately with a confirmation message. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, orders will be refreshed shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Order Details (by path)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{orderId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":orderId"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"orderId","value":"YmPxcdTqk","description":"Amazon removal order ID. Path-param accepts any characters including `/` via `where('orderId', '.*')`. Use the query-string variant when the ID contains URL-unsafe characters such as a trailing slash that Apache would strip."}]},"description":"Aggregates removal orders + removal shipments for the given order ID, hydrates FNSKU products and metadata, and revalidates the receipt status when applicable. Returns 404 if neither orders nor shipments exist for the order ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{orderId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":orderId"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"orderId","value":"YmPxcdTqk","description":"Amazon removal order ID. Path-param accepts any characters including `/` via `where('orderId', '.*')`. Use the query-string variant when the ID contains URL-unsafe characters such as a trailing slash that Apache would strip."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order_id\": \"YmPxcdTqk\",\n    \"integration_instance_id\": 1,\n    \"order_type\": \"Return\",\n    \"order_status\": \"Completed\",\n    \"metadata\": {\n      \"id\": 17,\n      \"integration_instance_id\": 1,\n      \"removal_order_id\": \"YmPxcdTqk\",\n      \"receiving_warehouse_id\": 4,\n      \"receipt_status\": \"partially_received\",\n      \"created_at\": \"2026-05-12T14:35:30.000000Z\",\n      \"updated_at\": \"2026-05-14T08:21:55.000000Z\",\n      \"receipt_status_data\": {\n        \"value\": \"partially_received\",\n        \"label\": \"Partially Received\",\n        \"color\": \"primary\",\n        \"icon\": \"mdi-truck-delivery\"\n      }\n    },\n    \"order_lines\": [\n      {\n        \"id\": 4521,\n        \"fnsku\": \"X001ABC123\",\n        \"fnsku_product_id\": 7,\n        \"fnsku_product\": {\n          \"id\": 7,\n          \"fnsku\": \"X001ABC123\",\n          \"product\": {\n            \"id\": 333,\n            \"sku\": \"PARENT-001\",\n            \"name\": \"Parent Product\"\n          }\n        },\n        \"sku\": \"ABC-001\",\n        \"product_sku\": \"PARENT-001\",\n        \"product_id\": 333,\n        \"product_name\": \"Parent Product\",\n        \"disposition\": \"Sellable\",\n        \"requested_quantity\": 10,\n        \"shipped_quantity\": 10,\n        \"cancelled_quantity\": 0,\n        \"disposed_quantity\": 0,\n        \"in_process_quantity\": 0,\n        \"removal_fee\": 5.5,\n        \"currency\": \"USD\",\n        \"request_date\": \"2026-05-12T14:35:00.000000Z\",\n        \"last_updated_date\": \"2026-05-13T09:11:02.000000Z\",\n        \"is_unknown_item\": false,\n        \"sku_link_id\": 901,\n        \"sku_link_type\": \"App\\\\Models\\\\WarehouseTransferLine\",\n        \"detail_link_id\": 88,\n        \"detail_link_type\": \"App\\\\Models\\\\WarehouseTransfer\"\n      }\n    ],\n    \"shipments\": [\n      {\n        \"id\": 9011,\n        \"uniqueId\": \"shipment_0\",\n        \"fnsku\": \"X001ABC123\",\n        \"fnsku_product_id\": 7,\n        \"fnsku_product\": {\n          \"id\": 7,\n          \"fnsku\": \"X001ABC123\",\n          \"product\": {\n            \"id\": 333,\n            \"sku\": \"PARENT-001\",\n            \"name\": \"Parent Product\"\n          }\n        },\n        \"sku\": \"ABC-001\",\n        \"product_sku\": \"PARENT-001\",\n        \"product_id\": 333,\n        \"product_name\": \"Parent Product\",\n        \"disposition\": \"Sellable\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"carrier\": \"UPS\",\n        \"shipment_date\": \"2026-05-13T00:00:00.000000Z\",\n        \"request_date\": \"2026-05-12T14:35:00.000000Z\",\n        \"shipped_quantity\": 10,\n        \"qty_discarded\": 0,\n        \"qty_reconciled_pretracking\": 0,\n        \"received_quantity\": 4,\n        \"pending_quantity\": 6,\n        \"is_pre_tracking\": false,\n        \"receipt_status\": \"partially_received\",\n        \"removal_order_type\": \"Return\",\n        \"receipts\": [\n          {\n            \"id\": 2201,\n            \"adjustment_date\": \"2026-05-14\",\n            \"quantity\": 4,\n            \"unit_cost\": 1.25,\n            \"notes\": \"Partial receive\",\n            \"warehouse_id\": 4,\n            \"warehouse_name\": \"Main WH\",\n            \"created_at\": \"2026-05-14T08:21:55.000000Z\"\n          }\n        ]\n      },\n      {\n        \"id\": 9012,\n        \"uniqueId\": \"shipment_1\",\n        \"fnsku\": \"X001ABC123\",\n        \"fnsku_product_id\": 7,\n        \"fnsku_product\": {\n          \"id\": 7,\n          \"fnsku\": \"X001ABC123\",\n          \"product\": {\n            \"id\": 333,\n            \"sku\": \"PARENT-001\",\n            \"name\": \"Parent Product\"\n          }\n        },\n        \"sku\": \"ABC-001\",\n        \"product_sku\": \"PARENT-001\",\n        \"product_id\": 333,\n        \"product_name\": \"Parent Product\",\n        \"disposition\": \"Sellable\",\n        \"tracking_number\": \"1Z999AA10123456785\",\n        \"carrier\": \"UPS\",\n        \"shipment_date\": \"2024-11-20T00:00:00.000000Z\",\n        \"request_date\": \"2024-11-18T14:35:00.000000Z\",\n        \"shipped_quantity\": 8,\n        \"qty_discarded\": 0,\n        \"qty_reconciled_pretracking\": 8,\n        \"received_quantity\": 0,\n        \"pending_quantity\": 0,\n        \"is_pre_tracking\": true,\n        \"receipt_status\": \"reconciled_at_go_live\",\n        \"removal_order_type\": \"Return\",\n        \"receipts\": []\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Order Details (by query string)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/order-details?order_id=YmPxcdTqk/","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","order-details"],"query":[{"key":"order_id","value":"YmPxcdTqk/","description":"Removal order ID. Required. Use this endpoint for IDs containing characters Apache's trailing-slash redirect would strip from a path segment (e.g. a trailing `/`).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Query-string variant of `getOrderDetails`. Returns 422 when `order_id` is missing/empty, 404 when no matching orders or shipments exist. Response payload is identical to the path-param variant.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/order-details?order_id=YmPxcdTqk/","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","order-details"],"query":[{"key":"order_id","value":"YmPxcdTqk/","description":"Removal order ID. Required. Use this endpoint for IDs containing characters Apache's trailing-slash redirect would strip from a path segment (e.g. a trailing `/`).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the [Errors guide](https://developer.sku.io/docs/guides/errors).","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unauthenticated.\"\n}"}]},{"name":"Set Receiving Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/set-warehouse","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","set-warehouse"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Assigns (or replaces) the receiving warehouse on a removal order's metadata. Validation (`SetRemovalOrderWarehouseData`):\n- `removal_order_id` (string, required)\n- `warehouse_id` (integer, required, exists in `warehouses.id`)\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the resulting `RemovalOrderWarehouseData` (`removal_order_id`, `receiving_warehouse_id`).","body":{"mode":"raw","raw":"{\n  \"removal_order_id\": \"YmPxcdTqk\",\n  \"warehouse_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/set-warehouse","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","set-warehouse"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"removal_order_id\": \"YmPxcdTqk\",\n    \"receiving_warehouse_id\": 4\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Unprocess Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unprocess removal orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Removal orders unprocessed\"\n}"}]},{"name":"Archive Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Bulk-archives removal orders (sets `archived_at = now()`). Request body uses `IdSelectionData`:\n- `ids` (array of integers, required) — removal order row IDs\n- `value` (string, optional) — opaque selection identifier (e.g. `selected`, `all`)\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNote: this endpoint does NOT take an integration instance filter on the database update; the route is namespaced by `{integrationInstance}` but the manager only filters by the supplied IDs.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4521,\n    4522,\n    4523\n  ],\n  \"value\": \"selected\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Removal orders archived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Unarchive Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Bulk-unarchives removal orders (sets `archived_at = null`). Request body uses `IdSelectionData`:\n- `ids` (array of integers, required) — removal order row IDs\n- `value` (string, optional) — opaque selection identifier\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4521,\n    4522,\n    4523\n  ],\n  \"value\": \"selected\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Removal orders unarchived successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Mark Item As Unknown","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrder}/mark-item-as-unknown","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrder","mark-item-as-unknown"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrder","value":"4521","description":"Primary key of the AmazonFbaReportRemovalOrder row."}]},"description":"Marks a single removal order row as an unknown item (`is_unknown_item = true`). No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrder}/mark-item-as-unknown","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrder","mark-item-as-unknown"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrder","value":"4521","description":"Primary key of the AmazonFbaReportRemovalOrder row."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Item marked as unknown\",\n  \"status\": \"success\"\n}"}]},{"name":"Unmark Item As Unknown","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrder}/unmark-item-as-unknown","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrder","unmark-item-as-unknown"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrder","value":"4521","description":"Primary key of the AmazonFbaReportRemovalOrder row."}]},"description":"Reverses the unknown-item flag on a removal order row (`is_unknown_item = false`). No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrder}/unmark-item-as-unknown","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrder","unmark-item-as-unknown"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrder","value":"4521","description":"Primary key of the AmazonFbaReportRemovalOrder row."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Item unmarked as unknown\",\n  \"status\": \"success\"\n}"}]},{"name":"Close Receiving","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/close-receiving","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","close-receiving"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts slashes via `where('removalOrderId', '.*')`."}]},"description":"Closes receiving for a removal order. The status manager automatically derives the next receipt status based on current receipts:\n- `received_for_less` → 'Removal order marked as received for less'\n- `closed_without_receipt` → 'Removal order closed without receipt'\n- otherwise → 'Removal order status updated'\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 with the exception message if the status transition is invalid (`InvalidArgumentException`).","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/close-receiving","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","close-receiving"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts slashes via `where('removalOrderId', '.*')`."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"new_status\": \"closed_without_receipt\"\n  },\n  \"message\": \"Removal order closed without receipt\",\n  \"status\": \"success\"\n}"}]},{"name":"Resume Receiving","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/resume-receiving","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","resume-receiving"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts slashes via `where('removalOrderId', '.*')`."}]},"description":"Re-opens receiving for a removal order by re-evaluating the receipt status against current shipments + receipts. Returns the resulting status value.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/resume-receiving","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","resume-receiving"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts slashes via `where('removalOrderId', '.*')`."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"new_status\": \"partially_received\"\n  },\n  \"message\": \"Removal order reopened for receiving\",\n  \"status\": \"success\"\n}"}]},{"name":"Clear Receiving Warehouse","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/clear-warehouse","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","clear-warehouse"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts any characters including slashes (`where('removalOrderId', '.*')`)."}]},"description":"Clears the receiving warehouse from a removal order's metadata. Returns `Warehouse cleared successfully` if a value was cleared, or `No warehouse to clear` if there was nothing to remove.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{removalOrderId}/clear-warehouse","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":removalOrderId","clear-warehouse"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalOrderId","value":"YmPxcdTqk","description":"Removal order ID. Accepts any characters including slashes (`where('removalOrderId', '.*')`)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Warehouse cleared successfully\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Unlinked Removal Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Returns distinct removal orders of type `Return` that are not yet linked to a SKU (warehouse transfer line). Grouped by `order_id`, sorted by request_date desc. Each row exposes only `order_id` and `date` (earliest request date).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"order_id\": \"YmPxcdTqk\",\n      \"date\": \"2026-05-12\"\n    },\n    {\n      \"order_id\": \"AbCdEfGhI\",\n      \"date\": \"2026-05-10\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Backfill Straddle Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/backfill-straddle","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","backfill-straddle"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"One-time repair for removal orders that straddle the integration's FBA inventory tracking start date. Before the straddle fix, removal shipments dispatched before go-live were dropped during report import, leaving the surviving removal orders with zero receivable shipments and phantom shrinkage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQueues a background job; returns a job id (tracked_job_log_id) for polling progress. Per instance, the job: (1) re-creates the dropped removal shipment rows by replaying the stored report payloads where they still exist (replay is idempotent — checksum de-duplication re-inserts only the previously-missing rows and never touches existing receipts, discards or inventory adjustments), (2) surfaces reports whose source payload is no longer available so an operator can act (quantities are never fabricated), and (3) re-evaluates the receipt status of every straddling removal order. Instances without an FBA inventory tracking start date no-op cleanly.\n\nBody fields:\n- dry_run (boolean, optional, default false) — compute and record the same counts in the job results without writing any changes.","body":{"mode":"raw","raw":"{\n  \"dry_run\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/backfill-straddle","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders","backfill-straddle"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Backfill started\",\n  \"status\": \"success\"\n}"}]},{"name":"Show Removal Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID"}]},"description":"Fetch a single removal shipment with its parent removal order eager-loaded. Returns 404 if the shipment does not belong to the supplied integration instance. NOTE: this route is registered twice — under `/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}` and under `/api/amazon/{integrationInstance}/ledgers/removal-shipments/{removalShipment}` — both invoke the same controller method.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12345,\n    \"event_datetime\": \"2026-04-12T14:32:00.000000Z\",\n    \"request_date\": \"2026-04-10T00:00:00.000000Z\",\n    \"shipment_date\": \"2026-04-11T00:00:00.000000Z\",\n    \"order_id\": \"AMZ-REMOVAL-1234567\",\n    \"sku\": \"SKU-ABC-001\",\n    \"fnsku\": \"X001ABCDEF\",\n    \"disposition\": \"SELLABLE\",\n    \"shipped_quantity\": 25,\n    \"carrier\": \"UPS\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"removal_order_type\": \"Return\",\n    \"created_at\": \"2026-04-12T14:35:00.000000Z\",\n    \"updated_at\": \"2026-04-12T14:35:00.000000Z\"\n  }\n}"}]},{"name":"Receive Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/receive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","receive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID to receive"}]},"description":"Record receipt of a removal shipment. Splits returned units into new (resellable), discarded (damaged), and optionally blemished. `items[].blemished_configurations` is an array where each entry represents ONE blemished unit. The shipment must belong to the supplied integration instance (404 otherwise).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `receipt_date` — required, date\n- `items` — required, min:1\n- `items[].quantity_new` — required integer >= 0\n- `items[].quantity_discarded` — required integer >= 0\n- `items[].cogs_per_unit` — required numeric >= 0\n- `items[].product_id` — required, exists:products,id\n- `items[].removal_shipment_id` — nullable integer\n- `items[].quantity_blemished` — nullable integer >= 0\n- `items[].blemished_configurations` — nullable array","body":{"mode":"raw","raw":"{\n  \"receipt_date\": \"2026-05-15\",\n  \"items\": [\n    {\n      \"quantity_new\": 20,\n      \"quantity_discarded\": 2,\n      \"cogs_per_unit\": 4.75,\n      \"product_id\": 4567,\n      \"removal_shipment_id\": 12345,\n      \"quantity_blemished\": 3,\n      \"blemished_configurations\": [\n        {\n          \"reason\": \"Damaged Packaging\",\n          \"discount_percent\": 25\n        },\n        {\n          \"reason\": \"Damaged Packaging\",\n          \"discount_percent\": 25\n        },\n        {\n          \"reason\": \"Used\",\n          \"discount_percent\": 40\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/receive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","receive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID to receive"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipment_id\": 12345,\n    \"receipts_created\": [\n      {\n        \"id\": 88001,\n        \"product_id\": 4567,\n        \"warehouse_id\": 12,\n        \"quantity\": 20,\n        \"type\": \"new\",\n        \"receipt_date\": \"2026-05-15\",\n        \"cogs_per_unit\": 4.75\n      },\n      {\n        \"id\": 88002,\n        \"product_id\": 4567,\n        \"warehouse_id\": 12,\n        \"quantity\": 2,\n        \"type\": \"discarded\",\n        \"receipt_date\": \"2026-05-15\",\n        \"cogs_per_unit\": 4.75\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Receive Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/receive-bulk","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments","receive-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Receive multiple removal shipments in one call, all into the same warehouse with the same receipt date. Each shipment must belong to the supplied integration instance — the controller validates this up-front and returns 404 if any shipment is missing or belongs to another integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `warehouse_id` — required, exists:warehouses,id\n- `receipt_date` — required, date\n- `shipments` — required, min:1\n- `shipments[].shipment_id` — required, exists:amazon_fba_report_removal_shipments,id\n- `shipments[].items` — required, min:1 — same item shape as the single receive endpoint.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 12,\n  \"receipt_date\": \"2026-05-15\",\n  \"shipments\": [\n    {\n      \"shipment_id\": 12345,\n      \"items\": [\n        {\n          \"quantity_new\": 20,\n          \"quantity_discarded\": 2,\n          \"cogs_per_unit\": 4.75,\n          \"product_id\": 4567,\n          \"removal_shipment_id\": 12345,\n          \"quantity_blemished\": 0,\n          \"blemished_configurations\": null\n        }\n      ]\n    },\n    {\n      \"shipment_id\": 12346,\n      \"items\": [\n        {\n          \"quantity_new\": 15,\n          \"quantity_discarded\": 0,\n          \"cogs_per_unit\": 8.1,\n          \"product_id\": 4568,\n          \"removal_shipment_id\": 12346,\n          \"quantity_blemished\": 1,\n          \"blemished_configurations\": [\n            {\n              \"reason\": \"Damaged Packaging\",\n              \"discount_percent\": 30\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/receive-bulk","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments","receive-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouse_id\": 12,\n    \"receipt_date\": \"2026-05-15\",\n    \"shipments_processed\": 2,\n    \"receipts_created\": 4,\n    \"shipment_ids\": [\n      12345,\n      12346\n    ]\n  }\n}"}]},{"name":"Remove Receipt (Single Shipment)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/remove-receipt","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","remove-receipt"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID whose receipt should be removed"}]},"description":"Reverse the receipt for a single removal shipment, deleting the inventory adjustments created when it was received. Returns 404 if the shipment does not belong to the supplied integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 when the receipt cannot be reversed:\n- it would consume stock hard-allocated to a shipment whose label cannot be voided (void it at the carrier first, or supply a `void_confirmations` entry to void it as part of the request), or\n- it would consume stock committed to another in-flight process (a warehouse transfer or an FBA inbound plan): cancel or adjust that transfer/plan first.\n\nIf the received units have already been sold or consumed with no live reservation to release, the reversal fails with a server error (not a 422) — a data anomaly worth investigating rather than a routine rejection."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/remove-receipt","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","remove-receipt"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID whose receipt should be removed"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipment_id\": 12345,\n    \"receipts_removed\": 2,\n    \"inventory_adjustments_deleted\": [\n      88001,\n      88002\n    ]\n  }\n}"}]},{"name":"Bulk Remove Receipts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/bulk-remove-receipts","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments","bulk-remove-receipts"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Remove multiple receipts (inventory_adjustments rows) by ID for the given integration instance. Useful when undoing a batch of receipts at once.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `receipt_ids` — required, array, min:1\n- `receipt_ids.*` — integer, exists:inventory_adjustments,id\n\nReturns 422 when the receipt cannot be reversed:\n- it would consume stock hard-allocated to a shipment whose label cannot be voided (void it at the carrier first, or supply a `void_confirmations` entry to void it as part of the request), or\n- it would consume stock committed to another in-flight process (a warehouse transfer or an FBA inbound plan): cancel or adjust that transfer/plan first.\n\nIf the received units have already been sold or consumed with no live reservation to release, the reversal fails with a server error (not a 422) — a data anomaly worth investigating rather than a routine rejection.","body":{"mode":"raw","raw":"{\n  \"receipt_ids\": [\n    88001,\n    88002,\n    88003,\n    88004\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/bulk-remove-receipts","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments","bulk-remove-receipts"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"receipt_ids_requested\": [\n      88001,\n      88002,\n      88003,\n      88004\n    ],\n    \"receipts_removed\": 4,\n    \"shipments_affected\": [\n      12345,\n      12346\n    ]\n  }\n}"}]},{"name":"Bulk Remove Discards","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipment-discards/bulk-remove","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipment-discards","bulk-remove"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Bulk-remove discard records by their IDs for the given integration instance. Each deleted discard decrements the parent shipment's `qty_discarded` counter so the legacy column stays in sync with the audit-trail rows. Discards belonging to shipments outside the supplied integration instance are silently skipped (not an error). After deletion, the removal order's receipt_status is recomputed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `discard_ids` — required, array, min:1\n- `discard_ids.*` — integer\n\nIntroduced alongside the first-class discards refactor that replaced the standalone `qty_discarded` counter with an auditable `amazon_fba_removal_shipment_discards` table.","body":{"mode":"raw","raw":"{\n  \"discard_ids\": [\n    9001,\n    9002,\n    9003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipment-discards/bulk-remove","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipment-discards","bulk-remove"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"discard_ids_requested\": [\n      9001,\n      9002,\n      9003\n    ],\n    \"discards_removed\": 3,\n    \"total_quantity_restored\": 7,\n    \"shipments_affected\": [\n      12345,\n      12346\n    ],\n    \"removed_discards\": [\n      {\n        \"id\": 9001,\n        \"removal_shipment_id\": 12345,\n        \"product_id\": null,\n        \"warehouse_id\": null,\n        \"quantity\": 2,\n        \"notes\": null\n      },\n      {\n        \"id\": 9002,\n        \"removal_shipment_id\": 12345,\n        \"product_id\": null,\n        \"warehouse_id\": null,\n        \"quantity\": 3,\n        \"notes\": \"Damaged on arrival\"\n      },\n      {\n        \"id\": 9003,\n        \"removal_shipment_id\": 12346,\n        \"product_id\": null,\n        \"warehouse_id\": null,\n        \"quantity\": 2,\n        \"notes\": null\n      }\n    ]\n  }\n}"}]},{"name":"Remove Single Discard","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipment-discards/{discard}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipment-discards",":discard"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"discard","value":"9001","description":"AmazonFbaRemovalShipmentDiscard ID to remove"}]},"description":"Remove a single discard record. The parent shipment's `qty_discarded` counter is decremented by the deleted row's quantity (backward-compat column kept in sync with the new `amazon_fba_removal_shipment_discards` audit table). Returns 404 if the discard does not belong to the supplied integration instance. After deletion, the removal order's receipt_status is recomputed (e.g. an order that was `fully_discarded` may transition back to `pending` if there are no other discards or receipts).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipment-discards/{discard}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipment-discards",":discard"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"discard","value":"9001","description":"AmazonFbaRemovalShipmentDiscard ID to remove"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"removed_discards_count\": 1,\n    \"removed_quantity\": 2,\n    \"affected_shipment_ids\": [\n      12345\n    ],\n    \"affected_order_ids\": [\n      \"AMZ-REMOVAL-1234567\"\n    ],\n    \"message\": \"Discard removed successfully\"\n  }\n}"}]},{"name":"Undo All Receipts for Removal Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{orderId}/undo-all-receipts","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":orderId","undo-all-receipts"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"orderId","value":"AMZ-REMOVAL-1234567","description":"Amazon removal order_id string (route uses `where('orderId', '.*')` so it accepts characters like `/` or `.`)"}]},"description":"Undo every receipt across all shipments for a single Amazon removal order. The endpoint verifies that at least one shipment exists for the given `order_id` and integration instance, otherwise returns 404.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Voiding hard-allocated labels (`void_confirmations`):** When this removal would consume stock that is hard-allocated to a fulfillment (a printed shipping label), include a `void_confirmations` array in the request body — one entry per fulfillment you authorize voiding: `{ \"fulfillment_id\": <int>, \"attempt_void\": true, \"reason\": <string|null> }`. Each confirmed label is voided first so the removal can proceed. Omit `void_confirmations` (or leave out a fulfillment that is in the way) and the request is rejected with 422 when hard-allocated stock blocks the operation. Call the matching preview-impact endpoint first to see exactly which fulfillments block it.\n\nThe request is also rejected with 422 when the stock is committed to another in-flight process (a warehouse transfer or an FBA inbound plan): cancel or adjust that transfer/plan first.\n\nIf the received units have already been sold or consumed with no live reservation to release, the reversal fails with a server error (not a 422) — a data anomaly worth investigating rather than a routine rejection."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-orders/{orderId}/undo-all-receipts","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-orders",":orderId","undo-all-receipts"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"orderId","value":"AMZ-REMOVAL-1234567","description":"Amazon removal order_id string (route uses `where('orderId', '.*')` so it accepts characters like `/` or `.`)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"order_id\": \"AMZ-REMOVAL-1234567\",\n    \"shipments_affected\": [\n      12345,\n      12346\n    ],\n    \"receipts_removed\": 4\n  }\n}"}]},{"name":"Reconcile Pre-Tracking Units (Straddle)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/reconcile-pretracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","reconcile-pretracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID (must be a straddle/pre-tracking shipment)"}]},"description":"Quarantine pre-tracking units on a STRADDLE removal shipment (one that shipped before the integration's FBA inventory tracking start date). These units were already counted in opening inventory at go-live, so they are closed out into the `qty_reconciled_pretracking` bucket instead of being received into inventory — no stock, no COGS, no FBA ledger impact. Capped at the shipment's remaining pending quantity.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe shipment must belong to the supplied integration instance (404 otherwise).\n\nValidation:\n- `quantity` — required, integer, min:1\n- `notes` — nullable, string\n\nErrors:\n- 404 — shipment does not belong to the integration instance\n- 422 — shipment is not a straddle (post-go-live) shipment, or quantity exceeds remaining pending","body":{"mode":"raw","raw":"{\n  \"quantity\": 5,\n  \"notes\": \"Counted in opening inventory at go-live\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/reconcile-pretracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","reconcile-pretracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID (must be a straddle/pre-tracking shipment)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"removal_shipment_id\": 12345,\n    \"qty_reconciled_pretracking\": 5,\n    \"pending_quantity\": 5,\n    \"order_receipt_status\": \"reconciled_at_go_live\",\n    \"message\": \"Pre-tracking units reconciled successfully\"\n  }\n}"}]},{"name":"Undo Reconcile Pre-Tracking (Straddle)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/reconcile-pretracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","reconcile-pretracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID"}]},"description":"Undo a pre-tracking reconciliation: resets the shipment's `qty_reconciled_pretracking` bucket back to zero and returns those units to pending. The shipment must belong to the supplied integration instance (404 otherwise).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/removal-shipments/{removalShipment}/reconcile-pretracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","removal-shipments",":removalShipment","reconcile-pretracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"removalShipment","value":"12345","description":"AmazonFbaReportRemovalShipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"removal_shipment_id\": 12345,\n    \"qty_reconciled_pretracking\": 0,\n    \"pending_quantity\": 10,\n    \"order_receipt_status\": \"pending\",\n    \"message\": \"Pre-tracking reconciliation undone successfully\"\n  }\n}"}]},{"name":"Show Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Get details of a specific legacy FBA inbound shipment, including its items (eager loaded), SKU link, integration instance, and counts for items and receipts. Powers the legacy inbound shipment detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAdditional fields exposed on the resource:\n- FromCountryCode\n- cached_shipment_date\n- destination_country (computed via getDestinationCountry)\n- status (lowercased enum value or raw ShipmentStatus)\n- items_count, receipts_count\n- items (collection of Amazon FBA inbound shipment item object)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 88,\n    \"integration_instance_id\": 3,\n    \"integration_instance_name\": \"Amazon US - Main\",\n    \"ShipmentId\": \"FBA15XYZABC\",\n    \"ShipmentName\": \"FBA (05/15/2026 10:22 AM) - 1 SKU(s)\",\n    \"ShipFromName\": \"Main Warehouse\",\n    \"DestinationFulfillmentCenterId\": \"PHX7\",\n    \"ShipmentStatus\": \"CLOSED\",\n    \"LabelPrepType\": \"SELLER_LABEL\",\n    \"BoxContentsSource\": \"FEED\",\n    \"FromCountryCode\": \"US\",\n    \"cached_shipment_date\": \"2026-05-15T10:22:00.000000Z\",\n    \"destination_country\": \"US\",\n    \"status\": \"CLOSED\",\n    \"errorLog\": null,\n    \"is_before_initial_count\": false,\n    \"sku_link\": {\n      \"id\": 5521,\n      \"type\": \"App\\\\Models\\\\Product\",\n      \"name\": \"ACME-HOODIE-MD-BLU\",\n      \"displayType\": \"Product\"\n    },\n    \"items_count\": 2,\n    \"receipts_count\": 1,\n    \"items\": [\n      {\n        \"SellerSKU\": \"ACME-HOODIE-MD-BLU\",\n        \"FulfillmentNetworkSKU\": \"X001ABC123\",\n        \"QuantityShipped\": 100,\n        \"item_name\": \"Acme Hoodie Medium Blue\",\n        \"item_asin\": \"B07XYZ1234\",\n        \"fnsku_product\": {\n          \"id\": 778,\n          \"fnsku\": \"X001ABC123\",\n          \"location\": \"A-12-3\",\n          \"product\": {\n            \"id\": 5521,\n            \"name\": \"Acme Hoodie Medium Blue\",\n            \"sku\": \"ACME-HOODIE-MD-BLU\",\n            \"inventory_available\": 240\n          }\n        }\n      }\n    ],\n    \"created_at\": \"2026-05-15T10:22:00.000000Z\",\n    \"updated_at\": \"2026-05-16T08:05:00.000000Z\"\n  }\n}"}]},{"name":"Delete Inbound Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"6289","description":"The shipment ID."}]},"description":"Permanently delete a legacy FBA inbound shipment and its downloaded items. Deletion is blocked with a 422 response when the shipment is linked to a purchase order or warehouse transfer — unprocess the shipment first to remove the link. Deleting only removes the local record; the shipment on Amazon is unaffected and an active shipment can reappear on the next refresh.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"6289","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Inbound shipment deleted\"\n}"}]},{"name":"Get Activity Log for Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Get the Spatie activity log for a specific legacy FBA inbound shipment. Returns the most recent 200 activities, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe shipment model uses the Spatie LogsActivity trait and logs changes to: ShipmentStatus, ShipmentId, ShipmentName, ShipFromName, DestinationFulfillmentCenterId, FromCountryCode, sku_link_id, sku_link_type, is_before_initial_count, errorLog, cached_shipment_date.\n\nEach entry includes:\n- id, description, event (created/updated/deleted)\n- causer: { id, name } — the user who triggered the change, or null for system changes\n- properties: { old: {...}, attributes: {...} } — Spatie diff of changed fields\n- created_at\n\nNote: activity logging was added in this release — entries for older shipments will not be backfilled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88231,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": {\n        \"id\": 17,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"properties\": {\n        \"old\": {\n          \"ShipmentStatus\": \"IN_TRANSIT\"\n        },\n        \"attributes\": {\n          \"ShipmentStatus\": \"DELIVERED\"\n        }\n      },\n      \"created_at\": \"2026-05-28T17:42:00.000000Z\"\n    },\n    {\n      \"id\": 88102,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": null,\n      \"properties\": {\n        \"old\": {\n          \"errorLog\": \"Rate limit\"\n        },\n        \"attributes\": {\n          \"errorLog\": null\n        }\n      },\n      \"created_at\": \"2026-05-27T08:11:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Get Items For Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/items?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","items"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Paginated list of items for a single legacy FBA inbound shipment. Powers the Items tab on the legacy shipment detail page using the canonical sku.io list view stack (server-side pagination, search, sort, advanced filters).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filters and sorts. The `filter[search]` parameter uses AdvancedSearchFilter to search across the item's SellerSKU and FulfillmentNetworkSKU.\n\nAllowed sorts: id, SellerSKU, FulfillmentNetworkSKU, QuantityShipped, QuantityReceived, QuantityInCase, ReleaseDate. Prefix with `-` for descending order (e.g. `sort=-QuantityShipped`).\n\nDefault page size is 25."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/items?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","items"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"SellerSKU\": \"ACME-HOODIE-MD-BLU\",\n      \"FulfillmentNetworkSKU\": \"X001ABC123\",\n      \"QuantityShipped\": 100,\n      \"item_name\": \"Acme Hoodie Medium Blue\",\n      \"item_asin\": \"B07XYZ1234\",\n      \"fnsku_product\": {\n        \"id\": 778,\n        \"fnsku\": \"X001ABC123\",\n        \"location\": \"A-12-3\",\n        \"product\": {\n          \"id\": 5521,\n          \"name\": \"Acme Hoodie Medium Blue\",\n          \"sku\": \"ACME-HOODIE-MD-BLU\",\n          \"inventory_available\": 240\n        }\n      }\n    },\n    {\n      \"SellerSKU\": \"ACME-TEE-LG-RED\",\n      \"FulfillmentNetworkSKU\": \"X002DEF456\",\n      \"QuantityShipped\": 50,\n      \"item_name\": \"Acme Tee Large Red\",\n      \"item_asin\": \"B08QWERTY2\",\n      \"fnsku_product\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon/1/inbound/shipments/1/items?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/amazon/1/inbound/shipments/1/items\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Inbound Shipment Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/receipts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","receipts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Paginated list of Receipt-type AmazonLedger entries for a single legacy FBA inbound shipment. Receipts are matched by integration_instance_id, reference_id (= shipment ShipmentId), and event_type = Receipts. Powers the Ledgers tab on the legacy shipment detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filters and sorts. The `filter[search]` parameter uses AdvancedSearchFilter to search across msku/fnsku/asin/title/fulfillment_center.\n\nAllowed sorts: id, date, event_datetime, msku, fnsku, asin, quantity, reconciled_quantity, reconciled_at. Default: -event_datetime. Prefix with `-` for descending order.\n\nNote: legacy shipments may have zero linked receipts if the ledger→shipment linking job did not run for that period — in which case this endpoint returns an empty page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/receipts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","receipts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9981,\n      \"msku\": \"ACME-HOODIE-MD-BLU\",\n      \"fnsku\": \"X001ABC123\",\n      \"asin\": \"B07XYZ1234\",\n      \"title\": \"Acme Hoodie Medium Blue\",\n      \"event_type\": \"Receipts\",\n      \"event_datetime\": \"2026-05-16T08:00:00.000000Z\",\n      \"reference_id\": \"FBA15XYZABC\",\n      \"fulfillment_center\": \"PHX7\",\n      \"quantity\": 100,\n      \"reconciled_quantity\": 100,\n      \"reconciled_at\": \"2026-05-16T09:30:00.000000Z\",\n      \"disposition\": \"SELLABLE\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon/1/inbound/shipments/1/receipts?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/amazon/1/inbound/shipments/1/receipts\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Refresh Inbound Shipments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Refresh FBA inbound shipments from Amazon API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Refresh started\"\n}"}]},{"name":"Process Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/process","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Process FBA inbound shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"shipment_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/process","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipments processed\"\n}"}]},{"name":"Process All Shipments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/process-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","process-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Process all unprocessed FBA inbound shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/process-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","process-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All shipments processing started\"\n}"}]},{"name":"Unprocess Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unprocess FBA inbound shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 when a selected shipment is linked to a purchase order that has purchase invoices attached - the invoices must be deleted before the shipment can be unprocessed.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipments unprocessed\"\n}"}]},{"name":"Get Unlinked Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get unlinked FBA inbound shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"shipment_id\": \"FBA15N999999\",\n      \"status\": \"SHIPPED\"\n    }\n  ]\n}"}]},{"name":"Set Sent Before Initial Count","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/set-sent-before-initial-count","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","set-sent-before-initial-count"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Mark shipments as sent before the initial count was taken.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"shipment_ids\": [\n    1,\n    2\n  ],\n  \"sent_before_initial_count\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/set-sent-before-initial-count","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","set-sent-before-initial-count"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Updated\"\n}"}]},{"name":"Get Shipment from Amazon","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/get-shipment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","get-shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Fetch a specific shipment directly from Amazon API by shipment ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"shipment_id\": \"FBA15N123456\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/get-shipment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","get-shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipment_id\": \"FBA15N123456\",\n    \"status\": \"SHIPPED\"\n  }\n}"}]},{"name":"Preview Process with Stock Take","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/process-preview","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","process-preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Preview the covering stock take that the \"Process with Stock Take\" action would create for this legacy FBA inbound. Resolves the source warehouse (from the ship-from mapping) and destination FBA warehouse, aggregates the inbound's items per product, and computes each product's source-warehouse shortfall (max(0, needed − on-hand available).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns:\n- `can_process` (bool) — false when any hard blocker is present\n- `source_warehouse` / `destination_warehouse` — {id, name} or null when unresolved\n- `lines[]` — per-product {line_id, sku, product_id, needed_qty, current_available, shortfall}\n- `skipped_lines[]` — unmapped inbound lines that will be ignored {line_id, sku, reason}\n- `blockers[]` — hard blockers as {code, message}; codes: NoSourceWarehouse, IneligibleStatus, AlreadyProcessed, AwdSource, PoRouted, NoMappedLines\n- `totals` — {units, shortfall}\n\nThis is a read-only computation — it does not create a stock take or mutate inventory. Use it to populate the confirm dialog and to disable the confirm button (with the blocker message as the tooltip reason) when `can_process` is false."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/process-preview","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","process-preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"can_process\": true,\n    \"source_warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"destination_warehouse\": {\n      \"id\": 8,\n      \"name\": \"Amazon FBA (US)\"\n    },\n    \"lines\": [\n      {\n        \"line_id\": 4471,\n        \"sku\": \"ACME-HOODIE-MD-BLU\",\n        \"product_id\": 1024,\n        \"needed_qty\": 100,\n        \"current_available\": 60,\n        \"shortfall\": 40\n      },\n      {\n        \"line_id\": 4472,\n        \"sku\": \"ACME-TEE-LG-RED\",\n        \"product_id\": 1025,\n        \"needed_qty\": 50,\n        \"current_available\": 50,\n        \"shortfall\": 0\n      }\n    ],\n    \"skipped_lines\": [\n      {\n        \"line_id\": 4473,\n        \"sku\": \"UNMAPPED-SKU-XYZ\",\n        \"reason\": \"No matching product found for this line\"\n      }\n    ],\n    \"blockers\": [],\n    \"totals\": {\n      \"units\": 150,\n      \"shortfall\": 40\n    }\n  }\n}"}]},{"name":"Process Inbound with Stock Take","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/process-with-stock-take","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","process-with-stock-take"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Dispatch the tracked job that injects each product's source-warehouse shortfall via a covering stock take and then processes the legacy FBA inbound into its warehouse transfer (source warehouse → FBA warehouse).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe covering stock take runs in adjustment mode with backorder auto-release SUPPRESSED, and the source inventory pool lock is held across inject→process so the injected units flow into the transfer's own Allocated reservation and are never stolen by a pending backorder. No InventoryHold is used.\n\nRequest body (both optional):\n- `notes` (string, max 1000) — appended to the covering stock take's note\n- `source_warehouse_id` (integer, exists:warehouses) — overrides the resolved source warehouse\n\nReturns the tracked job log ID so the frontend can follow progress via the tracked job log endpoints (job name: \"Process FBA Inbound with Stock Take: {ShipmentConfirmationId}\"). The operation is idempotent — a shipment already linked to a transfer returns early without creating a second stock take.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Covering stock take for FBA15XYZABC\",\n  \"source_warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/{shipment}/process-with-stock-take","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments",":shipment","process-with-stock-take"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 123\n  },\n  \"message\": \"Processing inbound with stock take — track progress in the job tray\"\n}"}]},{"name":"Bulk Delete Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk delete legacy FBA inbound shipments by ID. Shipments that are linked to a purchase order or warehouse transfer are skipped and returned in the blocked array; unprocess them first to remove the link. Deleting only removes the local records; the shipments on Amazon are unaffected.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6289,\n    6290\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound/shipments/delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound","shipments","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": 1,\n    \"blocked\": [\n      {\n        \"id\": 6290,\n        \"ShipmentId\": \"FBA17WHH38R2\",\n        \"sku_link_type\": \"Purchase Order\"\n      }\n    ]\n  },\n  \"status\": \"success\",\n  \"message\": \"1 inbound shipment(s) deleted — 1 skipped (linked to a purchase order / warehouse transfer)\"\n}"}]},{"name":"Show New Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Get a specific new FBA inbound shipment with full detail.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEager loads: amazonFbaInboundShipmentItems.amazonProduct, skuLink, receipts, integrationInstance, shipFromMapping.link, pendingInbound.\n\nResponse includes:\n- Identifiers: shipmentId, shipmentConfirmationId, amazonReferenceId, name, sourceName\n- Status fields: status, pending_status, errorLog, is_before_initial_count, is_archived, archived_at\n- Destination: destinationCountry, destinationWarehouse, destinationType, destinationAddress, destination\n- Transportation/placement IDs and cached_shipment_date\n- sku_link: the user-bound source (PurchaseOrder or WarehouseTransfer) — polymorphic with id, type, name, displayType\n- actual_source: resolved from sku_link (Supplier for PO, Warehouse for WT) — { name, type, link_type, link_id, route }\n- ship_from_mapping: current mapping target — UI compares to actual_source to detect divergence and strike-through the current mapping when they differ\n- pending_inbound: linked PendingInbound row with status/shipped_at\n- receipts: linked inventory receipt/ledger entries\n- items: per-line with id, msku, fnsku, quantity, item_name, item_asin, amazon_product_id, fnsku_product (with product + inventory_available when ship-from is a Warehouse)\n\nShelf-life compliance: the shipment includes aggregate `shelf_life_warnings_count` and `has_shelf_life_warnings`. Each item carries `shelf_life_compliance` (or null when the product is not lot-tracked, has no dated source lots, or ships from a non-warehouse source). The compliance object reports `expiry_date`, `remaining_shelf_life_days`, `min_remaining_shelf_life_days`, `is_compliant`, `will_be_auto_disposed` (within Amazon's 50-day auto-disposal window), and `disposal_window_days`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 3,\n    \"integration_instance_name\": \"Amazon US - Main\",\n    \"shipmentId\": \"sps-1234-5678-90ab\",\n    \"shipmentConfirmationId\": \"FBA17ABCXYZ\",\n    \"amazonReferenceId\": \"AMZN-REF-9988\",\n    \"name\": \"FBA STA (06/01/2026) - Main Warehouse\",\n    \"sourceName\": \"Main Warehouse\",\n    \"status\": \"WORKING\",\n    \"pending_status\": \"READY_TO_SHIP\",\n    \"errorLog\": null,\n    \"is_before_initial_count\": false,\n    \"is_archived\": false,\n    \"archived_at\": null,\n    \"destinationCountry\": \"US\",\n    \"destinationWarehouse\": \"LEX1\",\n    \"destinationType\": \"SELLER\",\n    \"destinationAddress\": \"1850 Mercer Rd, Lexington, KY 40511, US\",\n    \"destination\": {\n      \"warehouse\": \"LEX1\",\n      \"country\": \"US\",\n      \"address\": \"1850 Mercer Rd, Lexington, KY 40511, US\"\n    },\n    \"selectedTransportationOptionId\": \"to-aaaa-bbbb\",\n    \"placementOptionId\": \"po-cccc-dddd\",\n    \"cached_shipment_date\": \"2026-06-01T00:00:00.000000Z\",\n    \"sku_link\": {\n      \"id\": 442,\n      \"type\": \"App\\\\Models\\\\PurchaseOrder\",\n      \"name\": \"PO-2026-0442\",\n      \"displayType\": \"Purchase Order\"\n    },\n    \"actual_source\": {\n      \"name\": \"Acme Manufacturing Co.\",\n      \"type\": \"Supplier\",\n      \"link_type\": \"App\\\\Models\\\\Supplier\",\n      \"link_id\": 88,\n      \"route\": \"/crm/suppliers/88\"\n    },\n    \"ship_from_mapping\": {\n      \"name\": \"Main Warehouse\",\n      \"mapping_id\": 17,\n      \"target\": {\n        \"name\": \"Main Warehouse\",\n        \"type\": \"Warehouse\",\n        \"link_type\": \"App\\\\Models\\\\Warehouse\",\n        \"link_id\": 4,\n        \"route\": \"/crm/warehouses/4\"\n      }\n    },\n    \"pending_inbound\": {\n      \"id\": 2210,\n      \"status\": \"shipped\",\n      \"shipped_at\": \"2026-05-28T17:42:00.000000Z\"\n    },\n    \"receipts\": [\n      {\n        \"id\": 9981,\n        \"quantity\": 100,\n        \"created_at\": \"2026-05-30T11:00:00.000000Z\"\n      }\n    ],\n    \"items\": [\n      {\n        \"id\": 9101,\n        \"msku\": \"ACME-HOODIE-MD-BLU\",\n        \"fnsku\": \"X001ABC123\",\n        \"quantity\": 100,\n        \"item_name\": \"Acme Hoodie Medium Blue\",\n        \"item_asin\": \"B07XYZ1234\",\n        \"amazon_product_id\": 552,\n        \"fnsku_product\": {\n          \"id\": 778,\n          \"fnsku\": \"X001ABC123\",\n          \"location\": \"A-12-3\",\n          \"product\": {\n            \"id\": 5521,\n            \"name\": \"Acme Hoodie Medium Blue\",\n            \"sku\": \"ACME-HOODIE-MD-BLU\",\n            \"inventory_available\": 240\n          }\n        },\n        \"shelf_life_compliance\": {\n          \"expiry_date\": \"2026-07-20\",\n          \"remaining_shelf_life_days\": 49,\n          \"min_remaining_shelf_life_days\": 105,\n          \"is_compliant\": false,\n          \"will_be_auto_disposed\": true,\n          \"disposal_window_days\": 50\n        }\n      }\n    ],\n    \"created_at\": \"2026-05-20T14:30:00.000000Z\",\n    \"updated_at\": \"2026-05-21T09:15:00.000000Z\",\n    \"shelf_life_warnings_count\": 1,\n    \"has_shelf_life_warnings\": true\n  }\n}"}]},{"name":"Get Activity Log for New Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Get the Spatie activity log for a specific new FBA inbound shipment. Returns the most recent 200 activities, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe shipment model uses the Spatie LogsActivity trait and logs changes to fields including status, sku_link_id, sku_link_type, shipmentConfirmationId, amazonReferenceId, shipmentId, selectedTransportationOptionId, placementOptionId, is_before_initial_count, archived_at, errorLog, cached_shipment_date.\n\nEach entry includes:\n- id, description, event (created/updated/deleted)\n- causer: { id, name } — the user who triggered the change, or null for system changes\n- properties: { old: {...}, attributes: {...} } — Spatie diff of changed fields\n- created_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88231,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": {\n        \"id\": 17,\n        \"name\": \"Kalvin Mizzi\"\n      },\n      \"properties\": {\n        \"old\": {\n          \"status\": \"WORKING\"\n        },\n        \"attributes\": {\n          \"status\": \"SHIPPED\"\n        }\n      },\n      \"created_at\": \"2026-05-28T17:42:00.000000Z\"\n    },\n    {\n      \"id\": 88102,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": null,\n      \"properties\": {\n        \"old\": {\n          \"errorLog\": \"Rate limit\"\n        },\n        \"attributes\": {\n          \"errorLog\": null\n        }\n      },\n      \"created_at\": \"2026-05-27T08:11:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Get Items For Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/items?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","items"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Paginated list of items for a single new FBA inbound shipment. Powers the Items tab on the shipment detail page using the canonical sku.io list view stack (server-side pagination, search, sort, advanced filters, saved views, column selector).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filters and sorts. The `filter[search]` parameter uses AdvancedSearchFilter to search across the item's msku/fnsku/asin and the related amazonProduct's item_name/asin1.\n\nAllowed sorts: id, msku, fnsku, asin, quantity. Prefix with `-` for descending order (e.g. `sort=-quantity`).\n\nDefault page size is 25.\n\nShelf-life compliance: each item carries `shelf_life_compliance` — `expiry_date`, `remaining_shelf_life_days`, `min_remaining_shelf_life_days`, `is_compliant`, `will_be_auto_disposed` (within Amazon's 50-day auto-disposal window), `disposal_window_days` — or null when the product is not lot-tracked, has no dated source lots, or ships from a non-warehouse source."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/items?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","items"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"msku\": \"SKU-12345\",\n      \"fnsku\": \"X001ABCDEF\",\n      \"quantity\": 24,\n      \"item_name\": \"Acme Widget 4-Pack\",\n      \"item_asin\": \"B07ABCXYZ1\",\n      \"amazon_product_id\": 4421,\n      \"fnsku_product\": {\n        \"id\": 882,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"AISLE-7\",\n        \"product\": {\n          \"id\": 5571,\n          \"name\": \"Acme Widget 4-Pack\",\n          \"sku\": \"AW-4PK\",\n          \"inventory_available\": 152\n        }\n      },\n      \"shelf_life_compliance\": {\n        \"expiry_date\": \"2026-11-15\",\n        \"remaining_shelf_life_days\": 167,\n        \"min_remaining_shelf_life_days\": 105,\n        \"is_compliant\": true,\n        \"will_be_auto_disposed\": false,\n        \"disposal_window_days\": 50\n      }\n    },\n    {\n      \"id\": 1002,\n      \"msku\": \"SKU-67890\",\n      \"fnsku\": \"X002GHIJKL\",\n      \"quantity\": 8,\n      \"item_name\": \"Acme Gizmo Standard\",\n      \"item_asin\": \"B08QWERTY2\",\n      \"amazon_product_id\": 4520,\n      \"fnsku_product\": null,\n      \"shelf_life_compliance\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon/1/new-inbound/shipments/1/items?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/amazon/1/new-inbound/shipments/1/items\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get New Inbound Shipment Receipts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/receipts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","receipts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]},"description":"Paginated list of receipt ledger entries for a single new FBA inbound shipment. Powers the Ledgers tab on the shipment detail page using the canonical sku.io list view stack (server-side pagination, search, sort, advanced filters, saved views, column selector).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReceipts are AmazonLedger rows scoped by:\n- `event_type` = 'Receipts'\n- `integration_instance_id` = shipment.integration_instance_id\n- `reference_id` = shipment.shipmentConfirmationId\n\nSupports Spatie QueryBuilder filters and sorts. The `filter[search]` parameter uses AdvancedSearchFilter to search across msku, fnsku, asin, and title.\n\nAllowed sorts: id, date, event_datetime, msku, fnsku, asin, quantity, reconciled_quantity, reconciled_at. Prefix with `-` for descending order (e.g. `sort=-event_datetime`). Default sort is `-event_datetime`.\n\nDefault page size is 25.\n\nThe `status` filter accepts 'reconciled' or 'unreconciled' which maps to reconciled_at IS NOT NULL / IS NULL respectively.\n\nDate filters use m/d/Y format (e.g. 05/15/2026)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/{shipment}/receipts?page=1&per_page=25","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments",":shipment","receipts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"25","description":"Items per page (default: 25)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"1","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5501,\n      \"event_type\": \"Receipts\",\n      \"quantity\": 24,\n      \"event_datetime\": \"2026-05-22T14:30:00.000000Z\",\n      \"date\": \"2026-05-22\",\n      \"fnsku\": \"X001ABCDEF\",\n      \"asin\": \"B07ABCXYZ1\",\n      \"msku\": \"SKU-12345\",\n      \"title\": \"Acme Widget 4-Pack\",\n      \"country\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"reference_id\": \"FBA17ABCXYZ\",\n      \"reconciled_at\": \"2026-05-23T10:15:00.000000Z\",\n      \"reconciled_quantity\": 24,\n      \"unreconciled_quantity\": 0,\n      \"status\": \"reconciled\",\n      \"fulfillment_center\": \"LEX1\",\n      \"reason\": null,\n      \"created_at\": \"2026-05-22T15:00:00.000000Z\",\n      \"updated_at\": \"2026-05-23T10:15:00.000000Z\",\n      \"computed_cogs\": 4.75,\n      \"computed_extended_cogs\": 114\n    },\n    {\n      \"id\": 5502,\n      \"event_type\": \"Receipts\",\n      \"quantity\": 8,\n      \"event_datetime\": \"2026-05-22T14:30:00.000000Z\",\n      \"date\": \"2026-05-22\",\n      \"fnsku\": \"X002GHIJKL\",\n      \"asin\": \"B08QWERTY2\",\n      \"msku\": \"SKU-67890\",\n      \"title\": \"Acme Gizmo Standard\",\n      \"country\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"reference_id\": \"FBA17ABCXYZ\",\n      \"reconciled_at\": null,\n      \"reconciled_quantity\": 0,\n      \"unreconciled_quantity\": 8,\n      \"status\": \"unreconciled\",\n      \"fulfillment_center\": \"LEX1\",\n      \"reason\": null,\n      \"created_at\": \"2026-05-22T15:00:00.000000Z\",\n      \"updated_at\": \"2026-05-22T15:00:00.000000Z\",\n      \"computed_cogs\": null,\n      \"computed_extended_cogs\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon/1/new-inbound/shipments/1/receipts?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/amazon/1/new-inbound/shipments/1/receipts\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Process New Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/process","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Process the given new FBA inbound shipments. For each ID this resolves the SKU link source (purchase order or warehouse transfer), creates / updates the linked PendingInbound, and applies inventory movement.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse behaviour:\n- All succeed → 200 with success message and the processed shipments\n- Mix of success + failure → 207 Multi-Status, message lists the unique errors and processed shipments are returned\n- All fail → 422 with combined error message\n- Hard exception (e.g. integration not connected) → 422 with single error message\n\nThe per-shipment errorLog field on each returned resource is the source of truth for partial failures.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/process","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipments processed\",\n  \"data\": [\n    {\n      \"id\": 101,\n      \"status\": \"SHIPPED\",\n      \"pending_status\": \"shipped\",\n      \"errorLog\": null\n    },\n    {\n      \"id\": 102,\n      \"status\": \"SHIPPED\",\n      \"pending_status\": \"shipped\",\n      \"errorLog\": null\n    }\n  ]\n}"}]},{"name":"Process All Unprocessed New Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","process-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Process every unprocessed new FBA inbound shipment for this integration instance. Returns immediately with a success message regardless of per-shipment outcomes — check the index endpoint afterwards to see updated statuses and any errorLog entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","process-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipments processed\"\n}"}]},{"name":"Unprocess New Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reverse the processing of the given new FBA inbound shipments. Detaches PendingInbound rows and reverses any inventory movement that was created when the shipments were processed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 when a selected shipment is linked to a purchase order that has purchase invoices attached - the invoices must be deleted before the shipment can be unprocessed.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unprocess","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unprocess"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipments unprocessed\"\n}"}]},{"name":"Archive New Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archive the given new FBA inbound shipments by setting archived_at to now. Archived shipments are hidden from the default list view but remain in the database for audit/history. Returns the count actually archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Archived 2 inbound shipments\"\n}"}]},{"name":"Get Unlinked New Inbound Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List new FBA inbound shipments for this integration instance that have not been linked to a SKU source (no purchase order or warehouse transfer assigned). Used by the UI to surface shipments that still need source assignment before they can be processed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 215,\n      \"shipmentConfirmationId\": \"FBA17UNLINKED1\",\n      \"sourceName\": \"East Coast Warehouse\",\n      \"status\": \"WORKING\",\n      \"created_at\": \"2026-05-22T10:00:00.000000Z\"\n    },\n    {\n      \"id\": 216,\n      \"shipmentConfirmationId\": \"FBA17UNLINKED2\",\n      \"sourceName\": \"West Coast Warehouse\",\n      \"status\": \"WORKING\",\n      \"created_at\": \"2026-05-23T09:30:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Set Sent Before Initial Count","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/set-sent-before-initial-count","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","set-sent-before-initial-count"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk toggle the is_before_initial_count flag on the given shipments. Pass value as the string 'true' or 'false'. When set, the shipment is treated as sent prior to the integration's initial inventory count and excluded from inbound inventory math. Also clears the errorLog on the affected shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ],\n  \"value\": \"true\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/set-sent-before-initial-count","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","set-sent-before-initial-count"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipments updated\"\n}"}]},{"name":"Unarchive New Inbound Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Restore previously archived shipments by clearing archived_at. Returns the count actually unarchived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/shipments/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","shipments","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unarchived 2 inbound shipments\"\n}"}]},{"name":"List Draft Plans (Drafts Tab)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/list","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","list"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance ID"}]},"description":"Paginated Drafts-tab listing for the list view.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Scope:** in-progress drafts that have NOT yet been submitted to Amazon (no linked Amazon plan) — plus ABORTED drafts regardless of submission, so a plan voided on Amazon (e.g. via Cancel & Create Draft) stays visible as history. Live submitted drafts appear on the Inbound Plans tab instead.\n\nResponse includes `unfiltered_total` (for the export modal) and `status_counts` (total / in_progress / finalized / aborted, powering the metric cards).\n\nRequires Bearer token.\n\nAborted rows additionally carry `aborted_at` / `aborted_by` (from the status-transition activity log) for the Cancelled column."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/list","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","list"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 58,\n      \"name\": \"QA Aborted After Submit\",\n      \"status\": \"aborted\",\n      \"workflow_step\": 5,\n      \"source_mode\": \"warehouse_transfer\",\n      \"source_type\": \"warehouse\",\n      \"source_warehouse_name\": \"ShipMyOrders Warehouse\",\n      \"supplier_name\": null,\n      \"destination_warehouse_name\": \"FBA US (AMZ partusa)\",\n      \"item_count\": 22,\n      \"created_at\": \"2026-07-02T23:56:00.000000Z\",\n      \"updated_at\": \"2026-07-02T23:56:00.000000Z\",\n      \"aborted_at\": \"2026-07-03T07:20:00.000000Z\",\n      \"aborted_by\": \"Kalvin Mizzi\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 35,\n  \"from\": 1,\n  \"to\": 15,\n  \"unfiltered_total\": 35,\n  \"status_counts\": {\n    \"total\": 35,\n    \"in_progress\": 3,\n    \"finalized\": 0,\n    \"aborted\": 32\n  }\n}"}]},{"name":"List Draft Inbound Plans","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List draft FBA inbound plans for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Q2 Restock\",\n      \"status\": \"draft\",\n      \"warehouse_id\": 3\n    }\n  ]\n}"}]},{"name":"Create Draft Inbound Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Create a new draft FBA inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Q2 Restock Plan\",\n  \"warehouse_id\": 3,\n  \"destination_marketplace\": \"ATVPDKIKX0DER\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Q2 Restock Plan\",\n    \"status\": \"draft\"\n  }\n}"}]},{"name":"Show Draft Inbound Plan","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Get details of a specific draft FBA inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`prep_details_snapshot`** (object|null): the last successful Amazon prep-details fetch persisted on the plan — `{details: [{msku, prepCategory, prepTypes[], labelOwnerConstraint, prepOwnerConstraint, allOwnersConstraint}], invalid_mskus: [msku], fetched_at: ISO8601}`. Lets the Configuration page render prep requirements after a reload without re-hitting Amazon; refreshed on every successful `list-prep-details` call."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Q2 Restock\",\n    \"status\": \"draft\",\n    \"warehouse\": {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\"\n    },\n    \"items\": [\n      {\n        \"id\": 1,\n        \"product_id\": 42,\n        \"quantity\": 100\n      }\n    ],\n    \"prep_details_snapshot\": {\n      \"details\": [\n        {\n          \"msku\": \"ACME-SKU-A\",\n          \"prepCategory\": \"FRAGILE\",\n          \"prepTypes\": [\n            \"ITEM_BUBBLEWRAP\",\n            \"ITEM_LABELING\"\n          ],\n          \"labelOwnerConstraint\": null,\n          \"prepOwnerConstraint\": null,\n          \"allOwnersConstraint\": null\n        }\n      ],\n      \"invalid_mskus\": [],\n      \"fetched_at\": \"2026-07-07T05:00:00+00:00\"\n    }\n  }\n}"}]},{"name":"Update Draft Inbound Plan","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Update a draft FBA inbound plan. Advancing the plan to a verified state reserves source-warehouse stock; if the warehouse lacks enough on-hand quantity the request returns 400 with a product error.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Kit lines:** a kit line in `kit_stock` mode that lacks pre-built stock — but whose components could assemble the requested quantity — returns a dedicated 400 error including `buildable_from_components`, hinting that the line should be switched to `components` mode (PATCH the item with `kit_fulfillment_mode: components`) so verification can allocate the component stock instead.","body":{"mode":"raw","raw":"{\n  \"name\": \"Q2 Restock Plan - Updated\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Q2 Restock Plan - Updated\"\n  }\n}"}]},{"name":"Delete Draft Inbound Plan","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Delete a draft FBA inbound plan and its associated warehouse transfer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Draft inbound plan deleted successfully.\"\n}"}]},{"name":"List Plan Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/allocations","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","allocations"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance id."},{"key":"draft_inbound_plan","value":"1","description":"Draft inbound plan id."}]},"description":"List the inventory allocations reserved against a draft inbound plan's line items. These are the source-stock reservations (`InventoryAllocation` rows linked to `DraftAmazonFbaInboundPlanItem`) created when the plan is verified, and — after Amazon splits the plan into shipments — their migrated/fulfilled states. Backs the plan detail page's \"Allocations\" tab.\n\nAuthentication: requires Bearer token.\n\nFilters: `filter[search]` (allocation id / product SKU / product name), `filter[status]` (exact: allocated, planned, awaiting_receipt, fulfilled, cancelled), `filter[warehouse_id]` (exact).\nSort: `sort` — allowed: id, quantity, status, created_at (prefix with - for DESC; default -id).\nPagination: `page`, `per_page` (default 10).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/allocations","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","allocations"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance id."},{"key":"draft_inbound_plan","value":"1","description":"Draft inbound plan id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"product_id\": 1,\n      \"product\": {\n        \"id\": 1,\n        \"sku\": \"WIDGET-BLUE-01\",\n        \"name\": \"Blue Widget — Standard\"\n      },\n      \"warehouse_id\": 12,\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Main Distribution Center\"\n      },\n      \"link_id\": 1,\n      \"link_type\": \"Modules\\\\Amazon\\\\Entities\\\\DraftAmazonFbaInboundPlanItem\",\n      \"link_type_label\": \"FBA Inbound Plan\",\n      \"link_route\": null,\n      \"link_reference\": null,\n      \"date\": null,\n      \"quantity\": 120,\n      \"status\": \"allocated\",\n      \"status_label\": \"Allocated\",\n      \"priority\": null,\n      \"supplier_id\": null,\n      \"purchase_order_line_id\": null,\n      \"is_tight_coverage\": false,\n      \"release_source_id\": null,\n      \"release_source_type\": null,\n      \"fulfilled_at\": null,\n      \"cancelled_at\": null,\n      \"created_at\": \"2026-06-19T16:45:28.000000Z\",\n      \"updated_at\": \"2026-06-19T16:45:28.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 3,\n  \"from\": 1,\n  \"to\": 3,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Search Inbound Products (Plan Context)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/inbound-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","inbound-products"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Search the Amazon inbound product catalog (amazon_inbound_products_view) with plan context for the SKU Selection step. Each row is an Amazon listing joined to its internal product with FBA quantities, label/prep owners, source-warehouse availability for the plan's source, and the product's case pack.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`case_pack_qty` resolves from the per-product replenishment-settings override, else the instance default, else the product's shipping-settings case quantity. `case_pack_rounding` is one of `always_round_up`, `always_round_down`, `round_nearest`.\n\nRequires Bearer token.\n\nEach product includes an eligibility object { shippable: bool, reason: string|null } — false with a reason when the SKU can't be inbounded (no FNSKU, removed from Amazon, or an inactive listing)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/inbound-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","inbound-products"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"msku\": \"80707522-FBA\",\n      \"asin\": \"B0EXAMPLE1\",\n      \"fnsku\": \"X001ABC123\",\n      \"product_id\": 1979,\n      \"product_sku\": \"80707522\",\n      \"product_name\": \"Reusable Swim Diaper Snaps L\",\n      \"product_image\": \"https://cdn.example.com/image.jpg\",\n      \"country_code\": \"US\",\n      \"warehouse_quantity\": 71,\n      \"fulfillable_quantity\": 65,\n      \"unsellable_quantity\": 0,\n      \"reserved_quantity\": 6,\n      \"inbound_quantity\": 12,\n      \"inbound_working_quantity\": 12,\n      \"inbound_shipped_quantity\": 0,\n      \"inbound_receiving_quantity\": 0,\n      \"label_owner\": \"SELLER\",\n      \"prep_owner\": \"SELLER\",\n      \"source_quantity\": \"71\",\n      \"case_pack_qty\": 12,\n      \"case_pack_rounding\": \"always_round_down\"\n    }\n  ]\n}"}]},{"name":"Lookup Inbound Products by Identifiers (Bulk Add)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/lookup-by-mskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","lookup-by-mskus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Bulk-resolve identifiers to Amazon inbound products with plan context — powers the Bulk Add flow on the SKU Selection step.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nModes via `identifier_type`:\n- `auto` (default): try MSKU first, fall back to product SKU for not-found identifiers\n- `msku`: only match Amazon seller SKUs\n- `sku`: only match internal product SKUs\n\nA product SKU mapping to multiple MSKUs is returned under `multiple_msku_matches` for the operator to pick. Products include the same fields as the inbound-products search (including `case_pack_qty`/`case_pack_rounding`).\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mskus\": [\n    \"80707522-FBA\",\n    \"80707568\"\n  ],\n  \"identifier_type\": \"auto\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/lookup-by-mskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","lookup-by-mskus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"products\": [\n      {\n        \"msku\": \"80707522-FBA\",\n        \"asin\": \"B0EXAMPLE1\",\n        \"fnsku\": \"X001ABC123\",\n        \"product_id\": 1979,\n        \"product_sku\": \"80707522\",\n        \"product_name\": \"Reusable Swim Diaper Snaps L\",\n        \"product_image\": \"https://cdn.example.com/image.jpg\",\n        \"country_code\": \"US\",\n        \"warehouse_quantity\": 71,\n        \"fulfillable_quantity\": 65,\n        \"unsellable_quantity\": 0,\n        \"reserved_quantity\": 6,\n        \"inbound_quantity\": 12,\n        \"inbound_working_quantity\": 12,\n        \"inbound_shipped_quantity\": 0,\n        \"inbound_receiving_quantity\": 0,\n        \"label_owner\": \"SELLER\",\n        \"prep_owner\": \"SELLER\",\n        \"source_quantity\": \"71\",\n        \"case_pack_qty\": 12,\n        \"case_pack_rounding\": \"always_round_down\"\n      }\n    ],\n    \"found_identifiers\": [\n      \"80707522-FBA\",\n      \"80707568\"\n    ],\n    \"not_found_identifiers\": [\n      \"UNKNOWN-1\"\n    ],\n    \"multiple_msku_matches\": {\n      \"80707568\": [\n        {\n          \"msku\": \"80707568-FBA-1\",\n          \"asin\": \"B0EXAMPLE1\",\n          \"fnsku\": \"X001ABC123\",\n          \"product_id\": 1981,\n          \"product_sku\": \"80707568\",\n          \"product_name\": \"Reusable Swim Diaper Snaps L\",\n          \"product_image\": \"https://cdn.example.com/image.jpg\",\n          \"country_code\": \"US\",\n          \"warehouse_quantity\": 71,\n          \"fulfillable_quantity\": 65,\n          \"unsellable_quantity\": 0,\n          \"reserved_quantity\": 6,\n          \"inbound_quantity\": 12,\n          \"inbound_working_quantity\": 12,\n          \"inbound_shipped_quantity\": 0,\n          \"inbound_receiving_quantity\": 0,\n          \"label_owner\": \"SELLER\",\n          \"prep_owner\": \"SELLER\",\n          \"source_quantity\": \"71\",\n          \"case_pack_qty\": 12,\n          \"case_pack_rounding\": \"always_round_down\"\n        },\n        {\n          \"msku\": \"80707568-FBA-2\",\n          \"asin\": \"B0EXAMPLE1\",\n          \"fnsku\": \"X001ABC123\",\n          \"product_id\": 1981,\n          \"product_sku\": \"80707568\",\n          \"product_name\": \"Reusable Swim Diaper Snaps L\",\n          \"product_image\": \"https://cdn.example.com/image.jpg\",\n          \"country_code\": \"US\",\n          \"warehouse_quantity\": 71,\n          \"fulfillable_quantity\": 65,\n          \"unsellable_quantity\": 0,\n          \"reserved_quantity\": 6,\n          \"inbound_quantity\": 12,\n          \"inbound_working_quantity\": 12,\n          \"inbound_shipped_quantity\": 0,\n          \"inbound_receiving_quantity\": 0,\n          \"label_owner\": \"SELLER\",\n          \"prep_owner\": \"SELLER\",\n          \"source_quantity\": \"71\",\n          \"case_pack_qty\": 12,\n          \"case_pack_rounding\": \"always_round_down\"\n        }\n      ]\n    },\n    \"found_mskus\": [\n      \"80707522-FBA\"\n    ],\n    \"not_found_mskus\": [\n      \"UNKNOWN-1\"\n    ]\n  }\n}"}]},{"name":"Submit Plan to Amazon","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/submit-to-amazon","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","submit-to-amazon"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Submit a draft inbound plan to Amazon's API for processing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Pre-flight validation:** every plan item must carry an Amazon listing (MSKU). Items without one (e.g. a bulk-add identifier that matched a local product SKU only) fail with a 422 `items` error naming the offending product SKUs — nothing is sent to Amazon."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/submit-to-amazon","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","submit-to-amazon"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"status\": \"submitted\",\n    \"amazon_plan_id\": \"PLAN-123456\"\n  }\n}"}]},{"name":"Cancel Amazon Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/cancel-amazon-plan","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","cancel-amazon-plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Cancel a draft inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Never-submitted plans** are simply marked ABORTED locally and their reserved inventory is released.\n\n**Submitted plans** are voided on Amazon; the original draft stays bound to its now-VOIDED Amazon plan as ABORTED history and remains visible on the Drafts tab. With `create_draft=true` (default) a fresh duplicate draft is returned for resubmission.\n\n**Flagged-SKU handling:** MSKUs Amazon named in the plan's rejection problems (e.g. FBA_INB_0465 manufacturer-barcode errors) are automatically left out of the duplicate — unless `msku_replacements` maps them to an alternate listing (from → to), in which case the item is carried into the copy under the replacement MSKU with its label owner reset for reconfiguration. Dropped MSKUs are returned in `excluded_flagged_mskus`; applied swaps in `replaced_mskus`.\n\nThe resubmission copy preserves per-line kit assembly consent (`kit_fulfillment_mode`) and case-pack snapshots.\n\nRequires Bearer token.\n\nWhen a resubmission draft is created, the returned duplicate carries: excluded_flagged_mskus (SKUs Amazon flagged as invalid, dropped from the copy), replaced_mskus (flagged->alternate swaps applied), and — for fixable rejections that keep every SKU — resubmission_expiration_mskus (SKUs needing an expiration date), resubmission_address_issue (bool; the ship-from address needs fixing) and resubmission_other_problems (other messages to resolve before resubmitting).","body":{"mode":"raw","raw":"{\n  \"create_draft\": true,\n  \"msku_replacements\": [\n    {\n      \"from\": \"1727570-FBA\",\n      \"to\": \"1727570-FBA-NEW\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/cancel-amazon-plan","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","cancel-amazon-plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 58,\n    \"integration_instance_id\": 2,\n    \"name\": \"SMO Inbound Order 20260702 (Resubmit)\",\n    \"status\": \"source_selected\",\n    \"workflow_step\": 1,\n    \"source_mode\": \"warehouse_transfer\",\n    \"source_warehouse_id\": 12,\n    \"warehouse_transfer_id\": null,\n    \"amazon_new_fba_inbound_plan\": null,\n    \"items\": [],\n    \"excluded_flagged_mskus\": [\n      \"1726527-FBA\"\n    ],\n    \"created_at\": \"2026-07-02T23:10:00.000000Z\",\n    \"updated_at\": \"2026-07-02T23:10:00.000000Z\",\n    \"replaced_mskus\": {\n      \"1727570-FBA\": \"1727570-FBA-NEW\"\n    }\n  }\n}"}]},{"name":"Generate Packing Options","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Generate packing options for a submitted draft FBA inbound plan via the Amazon FBA Inbound API (v2024-03-20 generatePackingOptions operation).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Generate FBA Packing Options: {plan name}`. When the job completes, the offered packing options (with their packing groups and items) are persisted locally and can be retrieved with **List Packing Options**.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 123\n  },\n  \"message\": \"Packing options generation started\"\n}"}]},{"name":"List Packing Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List the packing options generated for a draft FBA inbound plan, including each option's packing groups and their items (with linked product details).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach option includes:\n- `status` — one of `offered`, `confirmed`, `expired`\n- `discounts` / `fees` — Amazon-quoted incentives for the option\n- `expiration` — when the offered option expires on Amazon's side\n- `supported_shipping_configurations` — shipping mode/solution pairs the option supports\n- `packing_groups[].items[]` — the MSKUs and quantities that must be packed together, with `prep_owner` / `label_owner`, the linked SKU.io product, and the product's per-unit `weight` / `weight_unit` and `length` / `width` / `height` / `dimension_unit` plus its `case_pack_qty`. Missing weight/dimension figures are returned as `null` with `weight_estimated` / `dims_estimated` set to `true` so the UI can flag them as estimates in load & transport calculations.\n\nRun **Generate Packing Options** first; this endpoint reads the locally persisted results."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"packing_option_id\": \"po-1f2e3d4c-5b6a-7980-bcde-f01234567890\",\n      \"status\": \"offered\",\n      \"discounts\": [],\n      \"fees\": [\n        {\n          \"target\": \"Placement Services\",\n          \"type\": \"FEE\",\n          \"value\": {\n            \"amount\": 0.3,\n            \"code\": \"USD\"\n          }\n        }\n      ],\n      \"expiration\": \"2026-06-19T00:00:00Z\",\n      \"supported_shipping_configurations\": [\n        {\n          \"shippingMode\": \"GROUND_SMALL_PARCEL\",\n          \"shippingSolution\": \"AMAZON_PARTNERED_CARRIER\"\n        },\n        {\n          \"shippingMode\": \"FREIGHT_LTL\",\n          \"shippingSolution\": \"USE_YOUR_OWN_CARRIER\"\n        }\n      ],\n      \"packing_groups\": [\n        {\n          \"id\": 12,\n          \"packing_group_id\": \"pg-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n          \"content_information_source\": null,\n          \"packing_submitted_at\": null,\n          \"items\": [\n            {\n              \"id\": 31,\n              \"msku\": \"WIDGET-BLUE-L\",\n              \"fnsku\": \"X001ABC123\",\n              \"quantity\": 40,\n              \"expiration_date\": null,\n              \"prep_owner\": \"SELLER\",\n              \"label_owner\": \"SELLER\",\n              \"draft_amazon_fba_inbound_plan_item_id\": 88,\n              \"case_pack_qty\": 10,\n              \"weight\": 1.25,\n              \"weight_unit\": \"lb\",\n              \"weight_estimated\": false,\n              \"length\": 6,\n              \"width\": 4,\n              \"height\": 2,\n              \"dimension_unit\": \"in\",\n              \"dims_estimated\": false,\n              \"product\": {\n                \"id\": 42,\n                \"sku\": \"WIDGET-BLUE-L\",\n                \"name\": \"Blue Widget - Large\",\n                \"image_url\": \"https://cdn.sku.io/products/42/primary.jpg\"\n              }\n            },\n            {\n              \"id\": 32,\n              \"msku\": \"WIDGET-RED-S\",\n              \"fnsku\": \"X001DEF456\",\n              \"quantity\": 12,\n              \"expiration_date\": null,\n              \"prep_owner\": \"AMAZON\",\n              \"label_owner\": \"SELLER\",\n              \"draft_amazon_fba_inbound_plan_item_id\": 89,\n              \"case_pack_qty\": null,\n              \"weight\": null,\n              \"weight_unit\": null,\n              \"weight_estimated\": true,\n              \"length\": null,\n              \"width\": null,\n              \"height\": null,\n              \"dimension_unit\": null,\n              \"dims_estimated\": true,\n              \"product\": {\n                \"id\": 43,\n                \"sku\": \"WIDGET-RED-S\",\n                \"name\": \"Red Widget - Small\",\n                \"image_url\": \"https://cdn.sku.io/products/43/primary.jpg\"\n              }\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Confirm Packing Option","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options/{packing_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options",":packing_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"packing_option","value":"7","description":"The packing option ID."}]},"description":"Confirm one of the offered packing options for the plan (Amazon FBA Inbound v2024-03-20 confirmPackingOption operation). Once confirmed, the plan's packing groups are fixed and boxes can be packed against them.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Confirm FBA Packing Option: {plan name}`.\n\nReturns 404 if the packing option does not belong to the draft inbound plan.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing-options/{packing_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing-options",":packing_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"packing_option","value":"7","description":"The packing option ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 124\n  },\n  \"message\": \"Packing option confirmation started\"\n}"}]},{"name":"List Boxes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List all locally managed boxes for a draft FBA inbound plan, across all of its packing groups, including each box's items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach box includes its `box_number` (unique per plan), dimensions/weight with units, `status` (`open`, `packed`, or `submitted`), the packing group it belongs to, the optional carton template it was created from, and its packed items (plan item reference, quantity, optional expiration date)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"box_number\": 1,\n      \"amazon_fba_inbound_packing_group_id\": 12,\n      \"amazon_fba_carton_template_id\": 3,\n      \"length\": \"18.00\",\n      \"width\": \"14.00\",\n      \"height\": \"12.00\",\n      \"dimension_unit\": \"IN\",\n      \"weight\": \"32.50\",\n      \"weight_unit\": \"LB\",\n      \"status\": \"open\",\n      \"items\": [\n        {\n          \"id\": 501,\n          \"draft_amazon_fba_inbound_plan_item_id\": 88,\n          \"quantity\": 24,\n          \"expiration_date\": \"2027-01-31\"\n        },\n        {\n          \"id\": 502,\n          \"draft_amazon_fba_inbound_plan_item_id\": 89,\n          \"quantity\": 12,\n          \"expiration_date\": null\n        }\n      ]\n    },\n    {\n      \"id\": 102,\n      \"box_number\": 2,\n      \"amazon_fba_inbound_packing_group_id\": 12,\n      \"amazon_fba_carton_template_id\": null,\n      \"length\": \"20.00\",\n      \"width\": \"16.00\",\n      \"height\": \"10.00\",\n      \"dimension_unit\": \"IN\",\n      \"weight\": \"28.00\",\n      \"weight_unit\": \"LB\",\n      \"status\": \"open\",\n      \"items\": [\n        {\n          \"id\": 503,\n          \"draft_amazon_fba_inbound_plan_item_id\": 88,\n          \"quantity\": 16,\n          \"expiration_date\": \"2027-01-31\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Create Box","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Create a new (empty) box in a packing group of the draft inbound plan. The box is assigned the next sequential `box_number` for the plan and starts with status `open`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `amazon_fba_inbound_packing_group_id` (integer, **required**) — the packing group the box belongs to; must exist and must belong to this draft inbound plan (422 otherwise)\n- `amazon_fba_carton_template_id` (integer, optional, nullable) — a carton template to prefill from; must exist. When set, any omitted `length`/`width`/`height` are filled from the template, `weight` defaults to the template's `tare_weight`, and the units default to the template's units\n- `length` (numeric, optional, nullable, > 0)\n- `width` (numeric, optional, nullable, > 0)\n- `height` (numeric, optional, nullable, > 0)\n- `weight` (numeric, optional, nullable, > 0)\n- `dimension_unit` (string, optional, `IN` or `CM`, default `IN`)\n- `weight_unit` (string, optional, `LB` or `KG`, default `LB`)\n\nAdd items to the box afterwards with **Update Box**.","body":{"mode":"raw","raw":"{\n  \"amazon_fba_inbound_packing_group_id\": 12,\n  \"amazon_fba_carton_template_id\": 3,\n  \"length\": 18,\n  \"width\": 14,\n  \"height\": 12,\n  \"weight\": 1.25,\n  \"dimension_unit\": \"IN\",\n  \"weight_unit\": \"LB\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 103,\n    \"box_number\": 3,\n    \"amazon_fba_inbound_packing_group_id\": 12,\n    \"amazon_fba_carton_template_id\": 3,\n    \"length\": \"18.00\",\n    \"width\": \"14.00\",\n    \"height\": \"12.00\",\n    \"dimension_unit\": \"IN\",\n    \"weight\": \"1.25\",\n    \"weight_unit\": \"LB\",\n    \"status\": \"open\",\n    \"items\": []\n  }\n}"}]},{"name":"Update Box","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/{box}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes",":box"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"box","value":"101","description":"The box ID."}]},"description":"Update a box's attributes and/or its packed items. Returns 404 if the box does not belong to the draft inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields (all optional):**\n- `amazon_fba_carton_template_id` (integer, nullable) — must exist in carton templates\n- `length` (numeric, nullable, > 0)\n- `width` (numeric, nullable, > 0)\n- `height` (numeric, nullable, > 0)\n- `weight` (numeric, nullable, > 0)\n- `dimension_unit` (string, `IN` or `CM`)\n- `weight_unit` (string, `LB` or `KG`)\n- `items` (array) — **full-replace** set of the box's items. When present, ALL existing box items are deleted and replaced with this set:\n  - `items.*.draft_amazon_fba_inbound_plan_item_id` (integer, **required**) — must exist, must belong to this plan, and its MSKU must be part of the box's packing group (422 otherwise)\n  - `items.*.quantity` (integer, **required**, min 1)\n  - `items.*.expiration_date` (date, optional, nullable, must be today or later — \"Expiration dates cannot be in the past.\")\n\nThe authenticated user is recorded as `packed_by_user_id` on each created item.","body":{"mode":"raw","raw":"{\n  \"length\": 18,\n  \"width\": 14,\n  \"height\": 12,\n  \"weight\": 32.5,\n  \"dimension_unit\": \"IN\",\n  \"weight_unit\": \"LB\",\n  \"items\": [\n    {\n      \"draft_amazon_fba_inbound_plan_item_id\": 88,\n      \"quantity\": 24,\n      \"expiration_date\": \"2027-01-31\"\n    },\n    {\n      \"draft_amazon_fba_inbound_plan_item_id\": 89,\n      \"quantity\": 12\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/{box}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes",":box"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"box","value":"101","description":"The box ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"box_number\": 1,\n    \"amazon_fba_inbound_packing_group_id\": 12,\n    \"amazon_fba_carton_template_id\": 3,\n    \"length\": \"18.00\",\n    \"width\": \"14.00\",\n    \"height\": \"12.00\",\n    \"dimension_unit\": \"IN\",\n    \"weight\": \"32.50\",\n    \"weight_unit\": \"LB\",\n    \"status\": \"open\",\n    \"items\": [\n      {\n        \"id\": 501,\n        \"draft_amazon_fba_inbound_plan_item_id\": 88,\n        \"quantity\": 24,\n        \"expiration_date\": \"2027-01-31\"\n      },\n      {\n        \"id\": 502,\n        \"draft_amazon_fba_inbound_plan_item_id\": 89,\n        \"quantity\": 12,\n        \"expiration_date\": null\n      }\n    ]\n  }\n}"}]},{"name":"Delete Box","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/{box}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes",":box"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"box","value":"101","description":"The box ID."}]},"description":"Delete a box (and its items) from the draft inbound plan. Returns 404 if the box does not belong to the plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/{box}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes",":box"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"box","value":"101","description":"The box ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Box deleted successfully.\"\n}"}]},{"name":"Import Boxes (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Import box contents for a packing group from a CSV file (multipart/form-data). Boxes are created or updated by `box_number` and item quantities are added per row.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Form fields:**\n- `file` (file, **required**) — CSV file (`.csv`/`.txt`), max 2MB\n- `amazon_fba_inbound_packing_group_id` (integer, **required**) — must exist and must belong to this draft inbound plan (422 otherwise)\n\n**CSV columns** (header row required; column names are case-insensitive):\n- `box_number` (**required**) — positive whole number; rows with the same box number go into the same box. A box number already used by a DIFFERENT packing group on this plan is rejected\n- `sku` (**required**) — matched case-insensitively against the plan items' product SKU or MSKU; must resolve to an item that is part of the selected packing group\n- `quantity` (**required**) — positive whole number; added to the box's quantity for that item\n- `weight`, `length`, `width`, `height` (optional) — numbers > 0; when present they update the box's measurements\n\n**The import is all-or-nothing:** every row is validated first, and any invalid row aborts the entire import with row-numbered error messages (422). On success the response includes a summary (`boxes_created`, `items_imported`) plus the full refreshed box list for the plan.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]},{"key":"amazon_fba_inbound_packing_group_id","type":"text","value":""}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/boxes/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","boxes","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"boxes_created\": 2,\n    \"items_imported\": 3,\n    \"boxes\": [\n      {\n        \"id\": 101,\n        \"box_number\": 1,\n        \"amazon_fba_inbound_packing_group_id\": 12,\n        \"amazon_fba_carton_template_id\": 3,\n        \"length\": \"18.00\",\n        \"width\": \"14.00\",\n        \"height\": \"12.00\",\n        \"dimension_unit\": \"IN\",\n        \"weight\": \"32.50\",\n        \"weight_unit\": \"LB\",\n        \"status\": \"open\",\n        \"items\": [\n          {\n            \"id\": 501,\n            \"draft_amazon_fba_inbound_plan_item_id\": 88,\n            \"quantity\": 24,\n            \"expiration_date\": \"2027-01-31\"\n          },\n          {\n            \"id\": 502,\n            \"draft_amazon_fba_inbound_plan_item_id\": 89,\n            \"quantity\": 12,\n            \"expiration_date\": null\n          }\n        ]\n      },\n      {\n        \"id\": 102,\n        \"box_number\": 2,\n        \"amazon_fba_inbound_packing_group_id\": 12,\n        \"amazon_fba_carton_template_id\": null,\n        \"length\": \"20.00\",\n        \"width\": \"16.00\",\n        \"height\": \"10.00\",\n        \"dimension_unit\": \"IN\",\n        \"weight\": \"28.00\",\n        \"weight_unit\": \"LB\",\n        \"status\": \"open\",\n        \"items\": [\n          {\n            \"id\": 503,\n            \"draft_amazon_fba_inbound_plan_item_id\": 88,\n            \"quantity\": 16,\n            \"expiration_date\": \"2027-01-31\"\n          }\n        ]\n      }\n    ]\n  },\n  \"message\": \"Boxes imported successfully.\"\n}"}]},{"name":"Submit Packing Information","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing/submit","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Submit box content information for **every packing group of the plan's confirmed packing option** in a single request (FBA Inbound v2024-03-20 setPackingInformation operation). Amazon requires all of the confirmed option's package grouping ids together, so submission is plan-level rather than per-group — submitting one group at a time is rejected with \"Provided package grouping ids are incorrect. Expected all of [...]\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `sources` (object, optional) — map of packing group id => content information source. Each value is one of `BOX_CONTENT_PROVIDED`, `MANUAL_PROCESS`, `BARCODE_2D`. Groups omitted from the map (or the whole `sources` object omitted) default to `BOX_CONTENT_PROVIDED`. With `BOX_CONTENT_PROVIDED` a group's per-box item contents are submitted; `MANUAL_PROCESS` and `BARCODE_2D` submit box dimensions/weights without item contents\n\n**Confirmed packing option required:** if the plan has no confirmed packing option, returns 422 with the message under `errors.packing_option` (\"Confirm a packing option before submitting box contents.\").\n\n**Pre-flight validation** (applies to each group whose source is `BOX_CONTENT_PROVIDED`; any failure returns 422 with messages under `errors.packing_group`):\n- The packing group must have at least one box\n- Every box must have length, width, height, AND weight greater than zero\n- The plan may not exceed 5,000 boxes\n- Per-MSKU packed totals across the group's boxes must EXACTLY equal the packing group's planned quantities (no shortfalls, overages, or MSKUs outside the group)\n- No box item may have an expiration date in the past\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Submit FBA Box Contents: {plan name}`.","body":{"mode":"raw","raw":"{\n  \"sources\": {\n    \"12\": \"BOX_CONTENT_PROVIDED\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/packing/submit","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","packing","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 125\n  },\n  \"message\": \"Box content submission started\"\n}"}]},{"name":"List Carton Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List all ACTIVE carton templates. Soft-retired templates (`is_active` = false) are excluded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCarton templates are reusable carton (box) presets used by the FBA packing station — selecting a template when creating a box prefills its dimensions, units, and tare weight."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Standard Large Carton\",\n      \"length\": \"18.00\",\n      \"width\": \"14.00\",\n      \"height\": \"12.00\",\n      \"dimension_unit\": \"IN\",\n      \"tare_weight\": \"1.25\",\n      \"weight_unit\": \"LB\",\n      \"is_active\": true,\n      \"created_at\": \"2026-06-01T10:15:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:15:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Carton Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Create a reusable carton template.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `name` (string, **required**, max 255) — must be unique across carton templates\n- `length` (numeric, **required**, > 0)\n- `width` (numeric, **required**, > 0)\n- `height` (numeric, **required**, > 0)\n- `dimension_unit` (string, optional, `IN` or `CM`, default `IN`)\n- `tare_weight` (numeric, optional, nullable, min 0) — empty-carton weight, used as the default box weight when a box is created from this template\n- `weight_unit` (string, optional, `LB` or `KG`, default `LB`)\n- `is_active` (boolean, optional, default `true`)","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Large Carton\",\n  \"length\": 18,\n  \"width\": 14,\n  \"height\": 12,\n  \"dimension_unit\": \"IN\",\n  \"tare_weight\": 1.25,\n  \"weight_unit\": \"LB\",\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Standard Large Carton\",\n    \"length\": \"18.00\",\n    \"width\": \"14.00\",\n    \"height\": \"12.00\",\n    \"dimension_unit\": \"IN\",\n    \"tare_weight\": \"1.25\",\n    \"weight_unit\": \"LB\",\n    \"is_active\": true,\n    \"created_at\": \"2026-06-01T10:15:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:15:00.000000Z\"\n  }\n}"}]},{"name":"Update Carton Template","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates/{carton_template}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates",":carton_template"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"carton_template","value":"3","description":"The carton template ID."}]},"description":"Update a carton template. All fields are optional; only provided fields are changed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields (all optional):**\n- `name` (string, max 255) — must be unique across carton templates (the current template is ignored)\n- `length` (numeric, > 0)\n- `width` (numeric, > 0)\n- `height` (numeric, > 0)\n- `dimension_unit` (string, `IN` or `CM`)\n- `tare_weight` (numeric, nullable, min 0)\n- `weight_unit` (string, `LB` or `KG`)\n- `is_active` (boolean) — set false to retire, true to reactivate","body":{"mode":"raw","raw":"{\n  \"name\": \"Standard Large Carton (Reinforced)\",\n  \"tare_weight\": 1.5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates/{carton_template}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates",":carton_template"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"carton_template","value":"3","description":"The carton template ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Standard Large Carton (Reinforced)\",\n    \"length\": \"18.00\",\n    \"width\": \"14.00\",\n    \"height\": \"12.00\",\n    \"dimension_unit\": \"IN\",\n    \"tare_weight\": \"1.50\",\n    \"weight_unit\": \"LB\",\n    \"is_active\": true,\n    \"created_at\": \"2026-06-01T10:15:00.000000Z\",\n    \"updated_at\": \"2026-06-12T09:30:00.000000Z\"\n  }\n}"}]},{"name":"Delete Carton Template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates/{carton_template}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates",":carton_template"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"carton_template","value":"3","description":"The carton template ID."}]},"description":"Delete (soft-retire) a carton template. The template is deactivated (`is_active` = false) rather than removed, so historical boxes keep their carton template reference. Retired templates no longer appear in **List Carton Templates**.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba/carton-templates/{carton_template}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba","carton-templates",":carton_template"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"carton_template","value":"3","description":"The carton template ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Carton template deleted successfully.\"\n}"}]},{"name":"Generate Placement Options","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Generate placement options for the draft FBA inbound plan via the Amazon FBA Inbound API (v2024-03-20 generatePlacementOptions operation). Each placement option is a possible shipment split — Amazon proposes different ways to spread the plan's inventory across fulfillment centers, with different placement fees and discounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Generate FBA Placement Options: {plan name}`. When the job completes, the offered placement options (with their preview shipments) are persisted locally and can be retrieved with **List Placement Options**.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 201\n  },\n  \"message\": \"Placement options generation started\"\n}"}]},{"name":"List Placement Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List the placement options generated for the draft FBA inbound plan, including each option's preview shipments (the shipment split Amazon would create if that option is confirmed).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach option includes:\n- `status` — one of `offered`, `confirmed`, `expired` (lowercase)\n- `fees` / `discounts` — Amazon-quoted placement fees and incentives for the option\n- `expiration` — when the offered option expires on Amazon's side\n- `shipment_ids` — the Amazon shipment ids making up the option's split\n- `shipments[]` — preview shipments with `destination_fc`, `destination_address`, and `amazon_status`\n\nUse this to compare splits (fee vs. number of destinations) before confirming one with **Confirm Placement Option** — confirmation is irreversible.\n\nRun **Generate Placement Options** first; this endpoint reads the locally persisted results.\n\nEach shipment includes `distance_miles` (integer|null): the great-circle distance in miles from the plan origin (source warehouse) to that fulfillment center, computed from internal zip coordinates. Null when a zip cannot be geocoded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"placement_option_id\": \"pl-9f8e7d6c-5b4a-3210-fedc-ba9876543210\",\n      \"status\": \"offered\",\n      \"fees\": [\n        {\n          \"target\": \"Placement Services\",\n          \"type\": \"FEE\",\n          \"value\": {\n            \"amount\": 0,\n            \"code\": \"USD\"\n          }\n        }\n      ],\n      \"discounts\": [\n        {\n          \"target\": \"Placement Services\",\n          \"type\": \"DISCOUNT\",\n          \"value\": {\n            \"amount\": 42.6,\n            \"code\": \"USD\"\n          }\n        }\n      ],\n      \"expiration\": \"2026-06-19T00:00:00.000000Z\",\n      \"shipment_ids\": [\n        \"sh-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n        \"sh-1b2c3d4e-5f6a-7890-bcde-f01234567890\"\n      ],\n      \"shipments\": [\n        {\n          \"id\": 15,\n          \"amazon_shipment_id\": \"sh-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n          \"name\": \"Shipment 1 of 2\",\n          \"destination_fc\": \"TEB9\",\n          \"destination_address\": {\n            \"name\": \"Amazon.com Services LLC (TEB9)\",\n            \"addressLine1\": \"2170 State Route 27\",\n            \"city\": \"Edison\",\n            \"stateOrProvinceCode\": \"NJ\",\n            \"postalCode\": 8817,\n            \"countryCode\": \"US\"\n          },\n          \"distance_miles\": 1536,\n          \"amazon_status\": \"UNCONFIRMED\"\n        },\n        {\n          \"id\": 16,\n          \"amazon_shipment_id\": \"sh-1b2c3d4e-5f6a-7890-bcde-f01234567890\",\n          \"name\": \"Shipment 2 of 2\",\n          \"destination_fc\": \"FTW1\",\n          \"destination_address\": {\n            \"name\": \"Amazon.com Services LLC (FTW1)\",\n            \"addressLine1\": \"33333 LBJ FWY\",\n            \"city\": \"Dallas\",\n            \"stateOrProvinceCode\": \"TX\",\n            \"postalCode\": \"75241\",\n            \"countryCode\": \"US\"\n          },\n          \"distance_miles\": 1536,\n          \"amazon_status\": \"UNCONFIRMED\"\n        }\n      ]\n    },\n    {\n      \"id\": 4,\n      \"placement_option_id\": \"pl-8e7d6c5b-4a39-2810-edcb-a98765432109\",\n      \"status\": \"offered\",\n      \"fees\": [\n        {\n          \"target\": \"Placement Services\",\n          \"type\": \"FEE\",\n          \"value\": {\n            \"amount\": 42.6,\n            \"code\": \"USD\"\n          }\n        }\n      ],\n      \"discounts\": [],\n      \"expiration\": \"2026-06-19T00:00:00.000000Z\",\n      \"shipment_ids\": [\n        \"sh-2c3d4e5f-6a7b-8901-cdef-012345678901\"\n      ],\n      \"shipments\": [\n        {\n          \"id\": 17,\n          \"amazon_shipment_id\": \"sh-2c3d4e5f-6a7b-8901-cdef-012345678901\",\n          \"name\": \"Shipment 1 of 1\",\n          \"destination_fc\": \"TEB9\",\n          \"destination_address\": {\n            \"name\": \"Amazon.com Services LLC (TEB9)\",\n            \"addressLine1\": \"2170 State Route 27\",\n            \"city\": \"Edison\",\n            \"stateOrProvinceCode\": \"NJ\",\n            \"postalCode\": 8817,\n            \"countryCode\": \"US\"\n          },\n          \"distance_miles\": 1536,\n          \"amazon_status\": \"UNCONFIRMED\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Placement Transport Estimates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-transport-estimates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-transport-estimates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Own-carrier small-parcel (SPD) transport cost estimates for every OFFERED placement option of the draft plan, so the operator can compare \"placement fee + transport\" totals in real dollars before confirming an option.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFor each offered option, every preview shipment's physical load (derived from the plan items' product weights/dimensions) is approximated into SPD parcels (max 50 lb / 25\" per box), rated from the plan's source-warehouse zip to the shipment's destination FC via EasyPost, and the cheapest carrier service per shipment is summed into the option total.\n\nResponse fields per estimate:\n- `placement_option_id` — the local placement option id\n- `total` — summed cheapest-rate transport cost for the option (null when `incomplete`)\n- `currency` — quote currency (USD)\n- `incomplete` — true when at least one shipment could not be estimated (missing product weight/dims, missing zips, or rating failure)\n- `shipments[]` — per-shipment breakdown: `shipment_id`, `destination_fc`, `quote` (`carrier`, `service`, `amount`, `currency`, `parcels`) or null when inestimable, `skipped_reason` (null when quoted; otherwise why the shipment could not be rated, e.g. `missing_product_dimensions`), and `missing_dims_mskus` (MSKUs lacking weight/dimensions when `skipped_reason` is `missing_product_dimensions`; empty otherwise)\n\n`origin_zip` is the source warehouse zip used as the rating origin.\n\nEach shipment also carries an `assumptions` object describing the physical load the rate is built on: `source`, `units`, `weight_lb`, `volume_cuft`, `estimated_pallets`, `parcel_count`, `parcel_weight_lb`, `parcel_side_in`, `items_missing_data`, `missing_data_mskus`. `assumptions.source` is `box_config` when the shipment has real packed cartons (amazon_fba_inbound_boxes with complete dims + weight) — then `weight_lb` / `volume_cuft` / `estimated_pallets` / `parcel_count` reflect those actual boxes — or `estimated` when the load is inferred from the plan items' product unit dimensions.\n\n`estimated_at` (top level) is the ISO-8601 time the persisted estimates were last computed (null when none stored). The estimate is a ROUGH approximation whenever `source` is `estimated`; once real box configurations exist for a shipment its rate uses them. Confirmed/expired options are skipped. Requires placement options to have been generated first."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-transport-estimates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-transport-estimates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"estimates\": [\n      {\n        \"placement_option_id\": 12,\n        \"total\": 148.62,\n        \"currency\": \"USD\",\n        \"incomplete\": false,\n        \"shipments\": [\n          {\n            \"shipment_id\": 341,\n            \"destination_fc\": \"SCK8\",\n            \"quote\": {\n              \"carrier\": \"USPS\",\n              \"carrier_label\": \"USPS\",\n              \"service\": \"GroundAdvantage\",\n              \"service_label\": \"USPS Ground Advantage\",\n              \"amount\": 74.31,\n              \"currency\": \"USD\",\n              \"delivery_days\": 3,\n              \"parcels\": 3\n            },\n            \"options\": [\n              {\n                \"carrier\": \"USPS\",\n                \"carrier_label\": \"USPS\",\n                \"service\": \"GroundAdvantage\",\n                \"service_label\": \"USPS Ground Advantage\",\n                \"amount\": 74.31,\n                \"currency\": \"USD\",\n                \"delivery_days\": 3,\n                \"parcels\": 3\n              },\n              {\n                \"carrier\": \"UPSDAP\",\n                \"carrier_label\": \"UPS\",\n                \"service\": \"Ground\",\n                \"service_label\": \"UPS Ground\",\n                \"amount\": 78.9,\n                \"currency\": \"USD\",\n                \"delivery_days\": 2,\n                \"parcels\": 3\n              },\n              {\n                \"carrier\": \"FedExDefault\",\n                \"carrier_label\": \"FedEx\",\n                \"service\": \"FEDEX_GROUND\",\n                \"service_label\": \"FedEx Ground\",\n                \"amount\": 81.15,\n                \"currency\": \"USD\",\n                \"delivery_days\": 2,\n                \"parcels\": 3\n              }\n            ],\n            \"assumptions\": {\n              \"source\": \"box_config\",\n              \"units\": 120,\n              \"weight_lb\": 105,\n              \"volume_cuft\": 12.4,\n              \"estimated_pallets\": null,\n              \"parcel_count\": 3,\n              \"parcel_weight_lb\": 35,\n              \"parcel_side_in\": 18,\n              \"items_missing_data\": 0,\n              \"missing_data_mskus\": []\n            },\n            \"skipped_reason\": null,\n            \"missing_dims_mskus\": []\n          },\n          {\n            \"shipment_id\": 342,\n            \"destination_fc\": \"CLT2\",\n            \"quote\": {\n              \"carrier\": \"UPSDAP\",\n              \"carrier_label\": \"UPS\",\n              \"service\": \"Ground\",\n              \"service_label\": \"UPS Ground\",\n              \"amount\": 74.31,\n              \"currency\": \"USD\",\n              \"delivery_days\": 2,\n              \"parcels\": 3\n            },\n            \"options\": [\n              {\n                \"carrier\": \"UPSDAP\",\n                \"carrier_label\": \"UPS\",\n                \"service\": \"Ground\",\n                \"service_label\": \"UPS Ground\",\n                \"amount\": 74.31,\n                \"currency\": \"USD\",\n                \"delivery_days\": 2,\n                \"parcels\": 3\n              },\n              {\n                \"carrier\": \"USPS\",\n                \"carrier_label\": \"USPS\",\n                \"service\": \"GroundAdvantage\",\n                \"service_label\": \"USPS Ground Advantage\",\n                \"amount\": 76.4,\n                \"currency\": \"USD\",\n                \"delivery_days\": 3,\n                \"parcels\": 3\n              }\n            ],\n            \"assumptions\": {\n              \"source\": \"estimated\",\n              \"units\": 96,\n              \"weight_lb\": 88,\n              \"volume_cuft\": 10.1,\n              \"estimated_pallets\": null,\n              \"parcel_count\": 2,\n              \"parcel_weight_lb\": 44,\n              \"parcel_side_in\": 20,\n              \"items_missing_data\": 0,\n              \"missing_data_mskus\": []\n            },\n            \"skipped_reason\": null,\n            \"missing_dims_mskus\": []\n          }\n        ]\n      },\n      {\n        \"placement_option_id\": 13,\n        \"total\": null,\n        \"currency\": \"USD\",\n        \"incomplete\": true,\n        \"shipments\": [\n          {\n            \"shipment_id\": 343,\n            \"destination_fc\": \"TEB9\",\n            \"quote\": null,\n            \"options\": [],\n            \"assumptions\": {\n              \"source\": \"estimated\",\n              \"units\": 24,\n              \"weight_lb\": null,\n              \"volume_cuft\": null,\n              \"estimated_pallets\": null,\n              \"parcel_count\": null,\n              \"parcel_weight_lb\": null,\n              \"parcel_side_in\": null,\n              \"items_missing_data\": 1,\n              \"missing_data_mskus\": [\n                \"MSKU-ABC-123\"\n              ]\n            },\n            \"skipped_reason\": \"missing_dims\",\n            \"missing_dims_mskus\": [\n              \"MSKU-ABC-123\"\n            ]\n          }\n        ]\n      }\n    ],\n    \"origin_zip\": \"95206\",\n    \"estimated_at\": \"2026-07-03T18:00:00+00:00\"\n  }\n}"}]},{"name":"Confirm Placement Option","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options/{placement_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options",":placement_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"placement_option","value":"3","description":"The placement option ID."}]},"description":"Confirm one of the offered placement options for the plan (Amazon FBA Inbound v2024-03-20 confirmPlacementOption operation). **Confirmation is irreversible** — once a placement option is confirmed the other options expire, and only the confirmed split's shipments remain the plan's real shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Confirm FBA Placement Option: {plan name}`. When the job completes, the option is marked `confirmed`, every other option of the plan is marked `expired`, and the confirmed shipments can be retrieved with **List Shipments**.\n\nPre-flight validation (HTTP 422, checked synchronously before the job is dispatched):\n- the placement option must not be expired (status `expired` or `expiration` in the past)\n- no placement option may already be confirmed for the plan — including this one (placement confirmation is irreversible)\n\nReturns 404 when the placement option does not belong to the draft inbound plan.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-options/{placement_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-options",":placement_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"placement_option","value":"3","description":"The placement option ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 202\n  },\n  \"message\": \"Placement option confirmation started\"\n}"}]},{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List the plan shipments of the draft FBA inbound plan with all placement/transport details nested: `items`, `pallets`, `transportation_options`, and `delivery_window_options`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Note:** once a placement option has been confirmed, only the confirmed split's shipments are returned — preview shipments belonging to the rejected (expired) placement options are excluded.\n\nField notes:\n- `local_status` — lowercase, one of `pending`, `ready`, `shipped`, `checked_in`, `receiving`, `closed`, `cancelled`\n- `amazon_status` — Amazon's raw shipment status (e.g. `UNCONFIRMED`, `WORKING`, `SHIPPED`)\n- `confirmed_delivery_window` — populated after a delivery window option is confirmed for the shipment\n- `transportation_options[]` / `delivery_window_options[]` — same shape as the corresponding list endpoints\n- `tracking_summary` / `freight_bill_numbers` / `shipped_at` — filled in later by the shipping workflow\n\nEach shipment includes `distance_miles` (integer|null): the great-circle distance in miles from the plan origin (source warehouse) to that fulfillment center, computed from internal zip coordinates. Null when a zip cannot be geocoded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 15,\n      \"amazon_shipment_id\": \"sh-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n      \"shipment_confirmation_id\": \"FBA15K7Z9QXM\",\n      \"name\": \"Shipment 1 of 2\",\n      \"destination_fc\": \"TEB9\",\n      \"destination_address\": {\n        \"name\": \"Amazon.com Services LLC (TEB9)\",\n        \"addressLine1\": \"2170 State Route 27\",\n        \"city\": \"Edison\",\n        \"stateOrProvinceCode\": \"NJ\",\n        \"postalCode\": 8817,\n        \"countryCode\": \"US\"\n      },\n      \"distance_miles\": 1536,\n      \"amazon_status\": \"WORKING\",\n      \"local_status\": \"pending\",\n      \"tracking_summary\": null,\n      \"freight_bill_numbers\": null,\n      \"delivery_window_option_id\": null,\n      \"confirmed_delivery_window\": null,\n      \"shipped_at\": null,\n      \"items\": [\n        {\n          \"id\": 61,\n          \"msku\": \"WIDGET-BLUE-L\",\n          \"fnsku\": \"X001ABC123\",\n          \"quantity_shipped\": 40,\n          \"quantity_received\": 0\n        },\n        {\n          \"id\": 62,\n          \"msku\": \"WIDGET-RED-S\",\n          \"fnsku\": \"X001DEF456\",\n          \"quantity_shipped\": 12,\n          \"quantity_received\": 0\n        }\n      ],\n      \"pallets\": [\n        {\n          \"id\": 9,\n          \"length\": 48,\n          \"width\": 40,\n          \"height\": 52,\n          \"dimension_unit\": \"IN\",\n          \"weight\": 480,\n          \"weight_unit\": \"LB\",\n          \"stackability\": \"NON_STACKABLE\",\n          \"quantity\": 2\n        }\n      ],\n      \"transportation_options\": [\n        {\n          \"id\": 21,\n          \"amazon_fba_inbound_plan_shipment_id\": 15,\n          \"transportation_option_id\": \"to-3c4d5e6f-7a8b-9012-cdef-345678901234\",\n          \"program\": \"AMAZON_PARTNERED_CARRIER\",\n          \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n          \"carrier\": {\n            \"alphaCode\": \"UPSN\",\n            \"name\": \"United Parcel Service Inc.\"\n          },\n          \"quote\": {\n            \"cost\": {\n              \"amount\": 124.52,\n              \"code\": \"USD\"\n            },\n            \"expiration\": \"2026-06-13T00:00:00Z\"\n          },\n          \"preconditions\": [],\n          \"status\": \"OFFERED\",\n          \"confirmed_at\": null,\n          \"void_deadline\": null\n        },\n        {\n          \"id\": 22,\n          \"amazon_fba_inbound_plan_shipment_id\": 15,\n          \"transportation_option_id\": \"to-4d5e6f7a-8b9c-0123-def4-456789012345\",\n          \"program\": \"USE_YOUR_OWN_CARRIER\",\n          \"shipping_mode\": \"FREIGHT_LTL\",\n          \"carrier\": {\n            \"alphaCode\": \"OTHR\",\n            \"name\": \"Other carrier\"\n          },\n          \"quote\": null,\n          \"preconditions\": [\n            \"CONFIRMED_DELIVERY_WINDOW\"\n          ],\n          \"status\": \"OFFERED\",\n          \"confirmed_at\": null,\n          \"void_deadline\": null\n        }\n      ],\n      \"delivery_window_options\": [\n        {\n          \"id\": 4,\n          \"delivery_window_option_id\": \"dw-5e6f7a8b-9c0d-1234-ef56-678901234567\",\n          \"start_date\": \"2026-06-22T08:00:00.000000Z\",\n          \"end_date\": \"2026-06-28T20:00:00.000000Z\",\n          \"availability_type\": \"AVAILABLE\",\n          \"valid_until\": \"2026-06-15T00:00:00.000000Z\",\n          \"status\": \"OFFERED\"\n        }\n      ]\n    },\n    {\n      \"id\": 16,\n      \"amazon_shipment_id\": \"sh-1b2c3d4e-5f6a-7890-bcde-f01234567890\",\n      \"shipment_confirmation_id\": \"FBA15K7Z9QXN\",\n      \"name\": \"Shipment 2 of 2\",\n      \"destination_fc\": \"FTW1\",\n      \"destination_address\": {\n        \"name\": \"Amazon.com Services LLC (FTW1)\",\n        \"addressLine1\": \"33333 LBJ FWY\",\n        \"city\": \"Dallas\",\n        \"stateOrProvinceCode\": \"TX\",\n        \"postalCode\": \"75241\",\n        \"countryCode\": \"US\"\n      },\n      \"distance_miles\": 1536,\n      \"amazon_status\": \"WORKING\",\n      \"local_status\": \"ready\",\n      \"tracking_summary\": null,\n      \"freight_bill_numbers\": null,\n      \"delivery_window_option_id\": \"dw-6f7a8b9c-0d1e-2345-f678-789012345678\",\n      \"confirmed_delivery_window\": {\n        \"startDate\": \"2026-06-22T08:00Z\",\n        \"endDate\": \"2026-06-28T20:00Z\",\n        \"availabilityType\": \"AVAILABLE\",\n        \"editableUntil\": \"2026-06-20T00:00Z\"\n      },\n      \"shipped_at\": null,\n      \"items\": [\n        {\n          \"id\": 63,\n          \"msku\": \"WIDGET-BLUE-L\",\n          \"fnsku\": \"X001ABC123\",\n          \"quantity_shipped\": 24,\n          \"quantity_received\": 0\n        }\n      ],\n      \"pallets\": [],\n      \"transportation_options\": [\n        {\n          \"id\": 24,\n          \"amazon_fba_inbound_plan_shipment_id\": 16,\n          \"transportation_option_id\": \"to-5e6f7a8b-9c0d-1234-ef56-567890123456\",\n          \"program\": \"AMAZON_PARTNERED_CARRIER\",\n          \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n          \"carrier\": {\n            \"alphaCode\": \"UPSN\",\n            \"name\": \"United Parcel Service Inc.\"\n          },\n          \"quote\": {\n            \"cost\": {\n              \"amount\": 86.1,\n              \"code\": \"USD\"\n            },\n            \"expiration\": \"2026-06-13T00:00:00Z\"\n          },\n          \"preconditions\": [],\n          \"status\": \"CONFIRMED\",\n          \"confirmed_at\": \"2026-06-12T15:04:05.000000Z\",\n          \"void_deadline\": \"2026-06-13T15:04:05.000000Z\"\n        }\n      ],\n      \"delivery_window_options\": [\n        {\n          \"id\": 5,\n          \"delivery_window_option_id\": \"dw-6f7a8b9c-0d1e-2345-f678-789012345678\",\n          \"start_date\": \"2026-06-22T08:00:00.000000Z\",\n          \"end_date\": \"2026-06-28T20:00:00.000000Z\",\n          \"availability_type\": \"AVAILABLE\",\n          \"valid_until\": \"2026-06-15T00:00:00.000000Z\",\n          \"status\": \"CONFIRMED\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Generate Transportation Options","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Generate transportation options (carrier quotes) for the confirmed placement's shipments via the Amazon FBA Inbound API (v2024-03-20 generateTransportationOptions operation). Amazon returns partnered-carrier and own-carrier options per shipping mode for each shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Generate FBA Transportation Options: {plan name}`. When the job completes, the offered options are persisted locally and can be retrieved with **List Transportation Options** or nested on **List Shipments**.\n\n**Request body fields:**\n- `shipments` (array, **required**, min 1) — one entry per shipment to quote\n- `shipments.*.shipment_id` (integer, **required**) — LOCAL plan-shipment row id (not the Amazon shipment id); must belong to this draft inbound plan (422 otherwise)\n- `shipments.*.ready_to_ship_date` (date, **required**) — must be today or later (422: “The ready-to-ship date must be today or later.”)\n- `shipments.*.pallets` (array, optional) — pallet configuration, needed for freight (LTL/FTL) quotes\n- `shipments.*.pallets.*.length` / `width` / `height` (numeric, **required**, > 0)\n- `shipments.*.pallets.*.weight` (numeric, **required**, > 0)\n- `shipments.*.pallets.*.dimension_unit` (string, optional, `IN` or `CM`)\n- `shipments.*.pallets.*.weight_unit` (string, optional, `LB` or `KG`)\n- `shipments.*.pallets.*.stackability` (string, optional, nullable, `STACKABLE` or `NON_STACKABLE`)\n- `shipments.*.pallets.*.quantity` (integer, **required**, min 1)\n\nPre-flight validation (HTTP 422, checked synchronously before the job is dispatched):\n- a placement option must already be confirmed for the plan\n- every `shipment_id` must belong to this draft inbound plan","body":{"mode":"raw","raw":"{\n  \"shipments\": [\n    {\n      \"shipment_id\": 15,\n      \"ready_to_ship_date\": \"2026-06-18\",\n      \"pallets\": [\n        {\n          \"length\": 48,\n          \"width\": 40,\n          \"height\": 52,\n          \"weight\": 480,\n          \"dimension_unit\": \"IN\",\n          \"weight_unit\": \"LB\",\n          \"stackability\": \"NON_STACKABLE\",\n          \"quantity\": 2\n        }\n      ]\n    },\n    {\n      \"shipment_id\": 16,\n      \"ready_to_ship_date\": \"2026-06-18\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 203\n  },\n  \"message\": \"Transportation options generation started\"\n}"}]},{"name":"List Transportation Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List all transportation options generated for the draft FBA inbound plan, across all of its shipments. Use `amazon_fba_inbound_plan_shipment_id` to group options by shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach option includes:\n- `program` — `AMAZON_PARTNERED_CARRIER` or `USE_YOUR_OWN_CARRIER` (uppercase)\n- `shipping_mode` — uppercase, one of `GROUND_SMALL_PARCEL`, `FREIGHT_LTL`, `FREIGHT_FTL_PALLET`, `FREIGHT_FTL_NONPALLET`, `OCEAN_LCL`, `OCEAN_FCL`, `AIR_SMALL_PARCEL`, `AIR_SMALL_PARCEL_EXPRESS`\n- `carrier` — Amazon carrier object (`alphaCode`, `name`)\n- `quote` — partnered-carrier cost quote (`cost.amount` / `cost.code`); `null` for own-carrier options\n- `preconditions` — e.g. `CONFIRMED_DELIVERY_WINDOW` on non-partnered (nPCP) options that require a confirmed delivery window before they can be confirmed\n- `status` — `OFFERED`, `CONFIRMED`, or `VOIDED` (uppercase)\n- `confirmed_at` / `void_deadline` — set when the option is confirmed; the void deadline is the cut-off for cancelling a partnered confirmation without carrier charges\n\nRun **Generate Transportation Options** first; this endpoint reads the locally persisted results."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 21,\n      \"amazon_fba_inbound_plan_shipment_id\": 15,\n      \"transportation_option_id\": \"to-3c4d5e6f-7a8b-9012-cdef-345678901234\",\n      \"program\": \"AMAZON_PARTNERED_CARRIER\",\n      \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n      \"carrier\": {\n        \"alphaCode\": \"UPSN\",\n        \"name\": \"United Parcel Service Inc.\"\n      },\n      \"quote\": {\n        \"cost\": {\n          \"amount\": 124.52,\n          \"code\": \"USD\"\n        },\n        \"expiration\": \"2026-06-13T00:00:00Z\"\n      },\n      \"preconditions\": [],\n      \"status\": \"OFFERED\",\n      \"confirmed_at\": null,\n      \"void_deadline\": null\n    },\n    {\n      \"id\": 22,\n      \"amazon_fba_inbound_plan_shipment_id\": 15,\n      \"transportation_option_id\": \"to-4d5e6f7a-8b9c-0123-def4-456789012345\",\n      \"program\": \"USE_YOUR_OWN_CARRIER\",\n      \"shipping_mode\": \"FREIGHT_LTL\",\n      \"carrier\": {\n        \"alphaCode\": \"OTHR\",\n        \"name\": \"Other carrier\"\n      },\n      \"quote\": null,\n      \"preconditions\": [\n        \"CONFIRMED_DELIVERY_WINDOW\"\n      ],\n      \"status\": \"OFFERED\",\n      \"confirmed_at\": null,\n      \"void_deadline\": null\n    },\n    {\n      \"id\": 24,\n      \"amazon_fba_inbound_plan_shipment_id\": 16,\n      \"transportation_option_id\": \"to-5e6f7a8b-9c0d-1234-ef56-567890123456\",\n      \"program\": \"AMAZON_PARTNERED_CARRIER\",\n      \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n      \"carrier\": {\n        \"alphaCode\": \"UPSN\",\n        \"name\": \"United Parcel Service Inc.\"\n      },\n      \"quote\": {\n        \"cost\": {\n          \"amount\": 86.1,\n          \"code\": \"USD\"\n        },\n        \"expiration\": \"2026-06-13T00:00:00Z\"\n      },\n      \"preconditions\": [],\n      \"status\": \"CONFIRMED\",\n      \"confirmed_at\": \"2026-06-12T15:04:05.000000Z\",\n      \"void_deadline\": \"2026-06-13T15:04:05.000000Z\"\n    }\n  ]\n}"}]},{"name":"Confirm Transportation Options","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Confirm one transportation option per shipment of the confirmed placement (Amazon FBA Inbound v2024-03-20 confirmTransportationOptions operation). This is lock gate #2 of the inbound workflow — carrier charges apply once the void window passes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Confirm FBA Transportation: {plan name}`. When the job completes, the selected options are marked `CONFIRMED` with their void deadlines and the shipments are refreshed.\n\n**Request body fields:**\n- `selections` (array, **required**, min 1) — exactly one entry per shipment of the confirmed placement\n- `selections.*.shipment_id` (integer, **required**) — LOCAL plan-shipment row id\n- `selections.*.transportation_option_id` (integer, **required**) — LOCAL transportation-option row id\n\nBoth ids are LOCAL row ids — the confirm job maps them to Amazon ids before calling SP-API.\n\nPre-flight validation (HTTP 422, checked synchronously before the job is dispatched):\n- a placement option must be confirmed for the plan\n- each `shipment_id` must belong to the confirmed placement option of this plan\n- each shipment must have exactly one selection — no duplicates, and every shipment of the confirmed placement must be covered (none missing)\n- each `transportation_option_id` must belong to its selected shipment\n- non-partnered options carrying the `CONFIRMED_DELIVERY_WINDOW` precondition require the shipment to already have a confirmed delivery window\n- Amazon SPD rule: when any selection ships via small parcel (`GROUND_SMALL_PARCEL`), every selection must use the same carrier and the same program\n\n**Void-window semantics:** on confirmation each option's `void_deadline` is set to now + 24 hours for partnered small parcel, now + 1 hour for partnered freight (LTL/FTL), and `null` for own-carrier options (nothing to void).","body":{"mode":"raw","raw":"{\n  \"selections\": [\n    {\n      \"shipment_id\": 15,\n      \"transportation_option_id\": 21\n    },\n    {\n      \"shipment_id\": 16,\n      \"transportation_option_id\": 24\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/transportation-options/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","transportation-options","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 204\n  },\n  \"message\": \"Transportation confirmation started\"\n}"}]},{"name":"Generate Delivery Window Options","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]},"description":"Generate delivery window options for a single plan shipment (Amazon FBA Inbound v2024-03-20 generateDeliveryWindowOptions operation). Delivery windows are required for non-partnered (own-carrier) transportation options that carry the `CONFIRMED_DELIVERY_WINDOW` precondition — confirm a window before confirming such a transportation option.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Generate FBA Delivery Windows: {plan name}`. When the job completes, the offered windows are persisted locally and can be retrieved with **List Delivery Window Options**.\n\nReturns 404 when the shipment does not belong to the draft inbound plan.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 205\n  },\n  \"message\": \"Delivery window options generation started\"\n}"}]},{"name":"List Delivery Window Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]},"description":"List the delivery window options generated for a plan shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach option includes:\n- `start_date` / `end_date` — the delivery window Amazon offers for the shipment\n- `availability_type` — e.g. `AVAILABLE` or `CONGESTED`\n- `valid_until` — when the offered window expires and can no longer be confirmed\n- `status` — `OFFERED`, `CONFIRMED`, or `EXPIRED` (uppercase)\n\nRun **Generate Delivery Window Options** first; this endpoint reads the locally persisted results. Returns 404 when the shipment does not belong to the draft inbound plan."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4,\n      \"delivery_window_option_id\": \"dw-5e6f7a8b-9c0d-1234-ef56-678901234567\",\n      \"start_date\": \"2026-06-22T08:00:00.000000Z\",\n      \"end_date\": \"2026-06-28T20:00:00.000000Z\",\n      \"availability_type\": \"AVAILABLE\",\n      \"valid_until\": \"2026-06-15T00:00:00.000000Z\",\n      \"status\": \"OFFERED\"\n    },\n    {\n      \"id\": 6,\n      \"delivery_window_option_id\": \"dw-7a8b9c0d-1e2f-3456-a789-890123456789\",\n      \"start_date\": \"2026-06-29T08:00:00.000000Z\",\n      \"end_date\": \"2026-07-05T20:00:00.000000Z\",\n      \"availability_type\": \"CONGESTED\",\n      \"valid_until\": \"2026-06-15T00:00:00.000000Z\",\n      \"status\": \"OFFERED\"\n    }\n  ]\n}"}]},{"name":"Confirm Delivery Window Option","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options/{delivery_window_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options",":delivery_window_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."},{"key":"delivery_window_option","value":"4","description":"The delivery window option ID."}]},"description":"Confirm a delivery window option for the shipment (Amazon FBA Inbound v2024-03-20 confirmDeliveryWindowOptions operation). Once confirmed, the shipment's `confirmed_delivery_window` is populated and transportation options that carry the `CONFIRMED_DELIVERY_WINDOW` precondition become confirmable.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is an asynchronous endpoint: it dispatches a tracked background job and returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately. Progress is visible via the tracked job log endpoints, and the underlying Amazon operation is resolved by the `amazon_inbound_operations` poller (a background job).\n\nTracked job name: `Confirm FBA Delivery Window: {plan name}`.\n\nPre-flight validation (HTTP 422, checked synchronously before the job is dispatched):\n- the delivery window option must not be expired (status `EXPIRED` or `valid_until` in the past)\n\nReturns 404 when the shipment does not belong to the draft inbound plan, or the delivery window option does not belong to the shipment.\n\nNo request body is required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/delivery-window-options/{delivery_window_option}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","delivery-window-options",":delivery_window_option","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."},{"key":"delivery_window_option","value":"4","description":"The delivery window option ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 206\n  },\n  \"message\": \"Delivery window confirmation started\"\n}"}]},{"name":"Estimate Placement Transport Costs","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-transport-estimates/estimate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-transport-estimates","estimate"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Kicks off a fresh own-carrier transport estimate for every OFFERED placement option on the draft inbound plan. **Queues a background job** (the estimate runs dozens of carrier rate calls, so it is taken off the request thread) and returns a job id (`tracked_job_log_id`) for polling progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFor each placement option the job rates every shipment against the connected carriers, keeps the cheapest quote per shipment, and sums them per option — letting you compare Amazon's placement fee plus your own transport cost across options. Results persist per option and are read back instantly via `GET .../placement-transport-estimates`.\n\nThe estimate is intentionally rough: parcels are derived from product weights/dimensions (or the plan's box configuration when available); the real box configuration confirmed later is authoritative. No request body or query parameters."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/placement-transport-estimates/estimate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","placement-transport-estimates","estimate"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Transport estimate started\"\n}"}]},{"name":"Create Item Labels (FNSKU)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/labels/item-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","labels","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Generate FNSKU (MSKU) item labels for products on the draft inbound plan via the synchronous Amazon FBA Inbound v2024-03-20 `createMarketplaceItemLabels` operation. Returns the label document download URL immediately (no tracked job) and records the print in the label-print audit trail (see **List Label Prints**; repeat prints are auto-flagged `is_reprint`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `label_type` (string, **required**) — `STANDARD_FORMAT` or `THERMAL_PRINTING`\n- `page_type` (string, **required**, max 64) — Amazon label page type, e.g. `Letter_30` (30-up letter sheet), `Letter_24`, `Thermal_NonPCP`. Pair thermal page types with `THERMAL_PRINTING`\n- `mskus` (array, **required**, min 1) — the MSKUs to print labels for:\n  - `mskus.*.msku` (string, **required**, max 255) — must be an MSKU that is part of this inbound plan (422 otherwise)\n  - `mskus.*.quantity` (integer, **required**, min 1) — number of labels for this MSKU\n\n**Response:** `url` (time-limited label document download URL), `expiration` (URL expiration timestamp, may be null), and `label_print_id` (the audit-trail record).\n\n**422 conditions:**\n- an `mskus.*.msku` value is not part of this inbound plan\n- the integration instance has no participating Amazon marketplace (re-sync marketplace participations)\n- Amazon rejects the request (SP-API error messages are parsed and surfaced per field)\n- Amazon does not return a label document","body":{"mode":"raw","raw":"{\n  \"label_type\": \"STANDARD_FORMAT\",\n  \"page_type\": \"Letter_30\",\n  \"mskus\": [\n    {\n      \"msku\": \"WIDGET-BLUE-L\",\n      \"quantity\": 24\n    },\n    {\n      \"msku\": \"WIDGET-RED-M\",\n      \"quantity\": 12\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/labels/item-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","labels","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://sellercentral.amazon.com/labels/download/amzn1.tortuga.4.na.aGVsbG8td29ybGQ.pdf?X-Amz-Expires=300\",\n    \"expiration\": \"2026-06-12T18:45:00Z\",\n    \"label_print_id\": 41\n  }\n}"}]},{"name":"Create Box Labels","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/labels/box-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","labels","box-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]},"description":"Generate box (carton) labels for a confirmed shipment via the Amazon Fulfillment Inbound v0 `getLabels` operation. **Requires a shipment confirmation ID** — confirm transportation first (422 otherwise). Returns the label document download URL synchronously and records the print in the audit trail.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `page_type` (string, **required**, max 64) — v0 PageType, e.g. `PackageLabel_Letter_6`, `PackageLabel_Thermal`, `PackageLabel_Plain_Paper`\n- `label_type` (string, optional, max 32, default `UNIQUE`) — v0 LabelType\n- `box_count` (integer, optional, nullable, min 1) — number of package labels (v0 NumberOfPackages). Defaults to the number of boxes packed for this shipment when omitted\n\n**422 conditions:**\n- the shipment has no `shipment_confirmation_id` yet (transportation not confirmed)\n- Amazon rejects the request or returns no label document (SP-API errors parsed per field)\n\nReturns 404 when the shipment does not belong to the draft inbound plan.","body":{"mode":"raw","raw":"{\n  \"page_type\": \"PackageLabel_Letter_6\",\n  \"label_type\": \"UNIQUE\",\n  \"box_count\": 8\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/labels/box-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","labels","box-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://fba-inbound-labels.s3.amazonaws.com/FBA15K7Q8XYZ/PackageLabel_Letter_6.pdf?X-Amz-Expires=300\",\n    \"label_print_id\": 42\n  }\n}"}]},{"name":"Create Pallet Labels","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/labels/pallet-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","labels","pallet-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]},"description":"Generate pallet labels for a confirmed LTL/FTL shipment via the Amazon Fulfillment Inbound v0 `getLabels` operation with `LabelType=PALLET`. The page type is fixed to `PackageLabel_Letter_4` (Amazon's standard letter-format pallet label sheet). **Requires a shipment confirmation ID** — confirm transportation first (422 otherwise). Records the print in the audit trail.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `count` (integer, **required**, min 1) — number of pallet labels (v0 NumberOfPallets). Amazon recommends 4 labels per pallet (one per side)\n\n**422 conditions:**\n- the shipment has no `shipment_confirmation_id` yet (transportation not confirmed)\n- Amazon rejects the request or returns no label document (SP-API errors parsed per field)\n\nReturns 404 when the shipment does not belong to the draft inbound plan.","body":{"mode":"raw","raw":"{\n  \"count\": 8\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/labels/pallet-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","labels","pallet-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://fba-inbound-labels.s3.amazonaws.com/FBA15K7Q8XYZ/PackageLabel_Letter_4.pdf?X-Amz-Expires=300\",\n    \"label_print_id\": 43\n  }\n}"}]},{"name":"Get Bill of Lading","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/bill-of-lading","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","bill-of-lading"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]},"description":"Fetch the bill of lading (BOL) document for a confirmed LTL/FTL shipment via the Amazon Fulfillment Inbound v0 `getBillOfLading` operation. Amazon only generates the BOL after the carrier is assigned — until then this endpoint returns **200 with `available: false`** (not an error), including when the shipment has no confirmation ID yet or Amazon responds 404/empty.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen the BOL is available, the response contains the download `url`, `available: true`, and a `label_print_id` (the fetch is recorded in the label-print audit trail as kind `BOL`).\n\nReturns 404 when the shipment does not belong to the draft inbound plan."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/bill-of-lading","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","bill-of-lading"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://fba-inbound-labels.s3.amazonaws.com/FBA15K7Q8XYZ/bill-of-lading.pdf?X-Amz-Expires=300\",\n    \"available\": true,\n    \"label_print_id\": 44\n  }\n}"}]},{"name":"Get 2D Barcode Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/labels/2d-barcode-data?packing_group_id=12","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","labels","2d-barcode-data"],"query":[{"key":"packing_group_id","value":"12","description":"(Required) The packing group ID. Must belong to this draft inbound plan and have been submitted with BARCODE_2D.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Get the 2D box-content barcode content strings for every box of a packing group that was submitted with the `BARCODE_2D` content information source. Returns one entry per box with the content string in Amazon's documented AMZN 2D box-content format:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`AMZN,PO:<shipment reference>,MSKU:<msku>,QTY:<qty>[,EXP:<YYYY-MM-DD>],MSKU:...`\n\nThe `PO:` reference is the shipment confirmation ID (FBA…) when available, falling back to the Amazon shipment ID, then `PLAN-{id}`. Each box item contributes an `MSKU:`/`QTY:` pair; `EXP:` follows the pair it applies to when the item has an expiration date.\n\n**Note:** this endpoint returns content STRINGS only — PDF417 graphic rendering is deferred (render client-side or in a later phase).\n\n**Query parameters:**\n- `packing_group_id` (integer, **required**) — the packing group; must belong to this draft inbound plan (404 otherwise)\n\n**422 condition:** the packing group was not submitted with the `BARCODE_2D` content information source."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/labels/2d-barcode-data?packing_group_id=12","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","labels","2d-barcode-data"],"query":[{"key":"packing_group_id","value":"12","description":"(Required) The packing group ID. Must belong to this draft inbound plan and have been submitted with BARCODE_2D.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"groups\": [\n      {\n        \"box_id\": 101,\n        \"box_number\": 1,\n        \"content_string\": \"AMZN,PO:FBA15K7Q8XYZ,MSKU:WIDGET-BLUE-L,QTY:12,MSKU:WIDGET-RED-M,QTY:6,EXP:2027-01-31\"\n      },\n      {\n        \"box_id\": 102,\n        \"box_number\": 2,\n        \"content_string\": \"AMZN,PO:FBA15K7Q8XYZ,MSKU:WIDGET-BLUE-L,QTY:24\"\n      }\n    ]\n  }\n}"}]},{"name":"List Label Prints","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/label-prints","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","label-prints"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"List the label-print audit trail for the draft inbound plan, newest first. Every successful label generation (item labels, box labels, pallet labels, BOL fetch) records an entry; repeat prints of the same kind for the same shipment (or plan, for plan-level kinds like FNSKU) are auto-flagged `is_reprint: true`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response fields (per entry):**\n- `id` (integer)\n- `label_kind` (string) — `FNSKU`, `BOX`, `PALLET`, `BOL`, or `CONTENT_2D`\n- `format` (string) — label format/page type as printed, e.g. `STANDARD_FORMAT/Letter_30`, `PackageLabel_Letter_6`, `PackageLabel_Letter_4`, `PDF`\n- `quantity` (integer) — number of labels printed\n- `document_url_snapshot` (string) — the (time-limited) document URL at print time\n- `is_reprint` (boolean)\n- `user` (object|null) — `{ id, name }` of the user who printed\n- `amazon_fba_inbound_plan_shipment_id` (integer|null) — the shipment, for shipment-level kinds; null for plan-level kinds (FNSKU)\n- `created_at` (datetime, UTC)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/label-prints","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","label-prints"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 44,\n      \"label_kind\": \"BOL\",\n      \"format\": \"PDF\",\n      \"quantity\": 1,\n      \"document_url_snapshot\": \"https://fba-inbound-labels.s3.amazonaws.com/FBA15K7Q8XYZ/bill-of-lading.pdf?X-Amz-Expires=300\",\n      \"is_reprint\": false,\n      \"user\": {\n        \"id\": 3,\n        \"name\": \"Jane Operator\"\n      },\n      \"amazon_fba_inbound_plan_shipment_id\": 5,\n      \"created_at\": \"2026-06-12T16:42:11.000000Z\"\n    },\n    {\n      \"id\": 42,\n      \"label_kind\": \"BOX\",\n      \"format\": \"PackageLabel_Letter_6\",\n      \"quantity\": 8,\n      \"document_url_snapshot\": \"https://fba-inbound-labels.s3.amazonaws.com/FBA15K7Q8XYZ/PackageLabel_Letter_6.pdf?X-Amz-Expires=300\",\n      \"is_reprint\": true,\n      \"user\": {\n        \"id\": 3,\n        \"name\": \"Jane Operator\"\n      },\n      \"amazon_fba_inbound_plan_shipment_id\": 5,\n      \"created_at\": \"2026-06-12T15:30:05.000000Z\"\n    },\n    {\n      \"id\": 41,\n      \"label_kind\": \"FNSKU\",\n      \"format\": \"STANDARD_FORMAT/Letter_30\",\n      \"quantity\": 36,\n      \"document_url_snapshot\": \"https://sellercentral.amazon.com/labels/download/amzn1.tortuga.4.na.aGVsbG8td29ybGQ.pdf?X-Amz-Expires=300\",\n      \"is_reprint\": false,\n      \"user\": {\n        \"id\": 3,\n        \"name\": \"Jane Operator\"\n      },\n      \"amazon_fba_inbound_plan_shipment_id\": null,\n      \"created_at\": \"2026-06-12T14:05:48.000000Z\"\n    }\n  ]\n}"}]},{"name":"Mark Shipment as Shipped","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/mark-shipped","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","mark-shipped"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]},"description":"Mark a shipment of the plan as shipped. Sets the shipment's local status to `shipped` (with `shipped_at`) and, for warehouse-sourced shipments (those with a linked warehouse transfer), transitions the linked warehouse transfer to **in-transit** via the existing FBA transfer pathway (physical-out movements + pending inbound). Supplier-sourced shipments (no warehouse transfer) skip the transfer step.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns in one DB transaction — a warehouse-transfer failure rolls back the status change and surfaces as a 422 with the underlying message.\n\nNo request body is required.\n\n**Response:** the refreshed shipment with `items`, `pallets`, `transportation_options`, and `delivery_window_options` loaded.\n\n**422 conditions:**\n- the shipment is already marked as shipped\n- the shipment has no confirmed transportation option (confirm transportation first)\n- the linked warehouse transfer fails to transition to in-transit (underlying message surfaced on `warehouse_transfer`)\n\nReturns 404 when the shipment does not belong to the draft inbound plan."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/mark-shipped","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","mark-shipped"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"amazon_shipment_id\": \"sh-1234abcd-5678-90ef-ghij-klmnopqrstuv\",\n    \"shipment_confirmation_id\": \"FBA15K7Q8XYZ\",\n    \"name\": \"Shipment 1 - IND9\",\n    \"destination_fc\": \"IND9\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com Services LLC\",\n      \"addressLine1\": \"1151 S Graham Rd\",\n      \"city\": \"Greenwood\",\n      \"stateOrProvinceCode\": \"IN\",\n      \"postalCode\": \"46143\",\n      \"countryCode\": \"US\"\n    },\n    \"amazon_status\": \"WORKING\",\n    \"local_status\": \"shipped\",\n    \"tracking_summary\": {\n      \"boxes\": [\n        {\n          \"box_id\": 101,\n          \"amazon_box_id\": \"FBA15K7Q8XYZU000001\",\n          \"box_number\": 1,\n          \"tracking_id\": \"1Z999AA10123456784\"\n        }\n      ]\n    },\n    \"freight_bill_numbers\": null,\n    \"delivery_window_option_id\": 7,\n    \"confirmed_delivery_window\": {\n      \"start_date\": \"2026-06-15\",\n      \"end_date\": \"2026-06-21\"\n    },\n    \"shipped_at\": \"2026-06-12T16:50:00.000000Z\",\n    \"items\": [\n      {\n        \"id\": 11,\n        \"msku\": \"WIDGET-BLUE-L\",\n        \"fnsku\": \"X0012ABCDE\",\n        \"quantity_shipped\": 24,\n        \"quantity_received\": 0\n      },\n      {\n        \"id\": 12,\n        \"msku\": \"WIDGET-RED-M\",\n        \"fnsku\": \"X0012FGHIJ\",\n        \"quantity_shipped\": 12,\n        \"quantity_received\": 0\n      }\n    ],\n    \"pallets\": [\n      {\n        \"id\": 2,\n        \"length\": 48,\n        \"width\": 40,\n        \"height\": 60,\n        \"dimension_unit\": \"IN\",\n        \"weight\": 450,\n        \"weight_unit\": \"LB\",\n        \"stackability\": \"NON_STACKABLE\",\n        \"quantity\": 2\n      }\n    ],\n    \"transportation_options\": [\n      {\n        \"id\": 9,\n        \"amazon_fba_inbound_plan_shipment_id\": 5,\n        \"transportation_option_id\": \"to-9876fedc-ba98-7654-3210-zyxwvutsrqpo\",\n        \"program\": \"USE_YOUR_OWN_CARRIER\",\n        \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n        \"carrier\": {\n          \"name\": \"United Parcel Service Inc.\",\n          \"alphaCode\": \"UPSN\"\n        },\n        \"quote\": null,\n        \"preconditions\": [],\n        \"status\": \"confirmed\",\n        \"confirmed_at\": \"2026-06-11T20:15:00.000000Z\",\n        \"void_deadline\": null\n      }\n    ],\n    \"delivery_window_options\": [\n      {\n        \"id\": 7,\n        \"delivery_window_option_id\": \"dw-1111aaaa-2222-bbbb-3333-cccc4444dddd\",\n        \"start_date\": \"2026-06-15\",\n        \"end_date\": \"2026-06-21\",\n        \"availability_type\": \"AVAILABLE\",\n        \"valid_until\": \"2026-06-14T00:00:00.000000Z\",\n        \"status\": \"confirmed\"\n      }\n    ]\n  }\n}"}]},{"name":"Submit Shipment Tracking","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/tracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","tracking"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]},"description":"Submit non-partnered-carrier (nPCP) tracking for a shipment. Provide **exactly ONE** of:\n- `box_tracking` — per-box tracking IDs (small parcel / SPD)\n- `freight_bill_numbers` — freight bill numbers (LTL/FTL)\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSending both (or neither) is a 422.\n\n**Fields:**\n- `box_tracking` (array, min 1, required without `freight_bill_numbers`, prohibits `freight_bill_numbers`):\n  - `box_tracking.*.box_id` (integer, **required**) — local box ID; must belong to this shipment/plan and must already have an Amazon box ID (submit packing information first — 422 otherwise)\n  - `box_tracking.*.tracking_id` (string, **required**, max 255) — carrier tracking number\n- `freight_bill_numbers` (array of strings, min 1, max 255 each, required without `box_tracking`)\n\nThe tracking is persisted locally first (boxes merged into the shipment's `tracking_summary.boxes`; freight bill numbers stored on the shipment), then a tracked background job submits it to Amazon via the FBA Inbound v2024-03-20 `updateShipmentTrackingDetails` operation. Returns `{ \"data\": { \"tracked_job_log_id\": <id> } }` immediately; progress is visible via the tracked job log endpoints.\n\nTracked job name: `Update FBA Shipment Tracking: {plan name}`. The job starts an asynchronous Amazon operation; the TrackedJobLog is completed (or failed) by the `amazon_inbound_operations` poller (a background job), which refreshes the shipment's `tracking_summary` from Amazon via `getShipment` on success.\n\n**422 conditions:**\n- neither or both of `box_tracking` / `freight_bill_numbers` provided\n- a `box_tracking.*.box_id` does not belong to this shipment or plan\n- a box has no Amazon box ID yet (packing information not submitted)\n\nReturns 404 when the shipment does not belong to the draft inbound plan.\n\n**LTL example body:**\n```json\n{\n  \"freight_bill_numbers\": [\"FBN-2026-0001\", \"FBN-2026-0002\"]\n}\n```","body":{"mode":"raw","raw":"{\n  \"box_tracking\": [\n    {\n      \"box_id\": 101,\n      \"tracking_id\": \"1Z999AA10123456784\"\n    },\n    {\n      \"box_id\": 102,\n      \"tracking_id\": \"1Z999AA10123456791\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/tracking","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","tracking"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"5","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 318\n  },\n  \"message\": \"Tracking submission started\"\n}"}]},{"name":"Get Shipment Board","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/board","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","board"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Post-ship shipment board for a draft inbound plan: every shipment of the plan's confirmed placement option with its items, extended with the Phase 7 monitoring fields. Data is refreshed hourly by the scheduled `amazon:fba-inbound:sync-shipments` sweep (and on demand via **Refresh Shipment**).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Board-only fields** (on top of the standard plan-shipment payload):\n- `days_since_shipped` (integer|null) — whole days since `shipped_at`; null when not yet marked shipped\n- `units_shipped` / `units_received` (integer) — sums of the item quantities\n- `boxes_count` (integer) — number of boxes on the shipment\n- `claim_deadline` (date|null) — `shipped_at` + 60 days (Amazon's reimbursement claim window, policy since Oct 2024); null when not shipped\n- `claim_days_remaining` (integer|null) — whole days until `claim_deadline` (negative once lapsed); null when not shipped\n- `reconciliation_status` (string) — shipment-level rollup of the item discrepancy statuses: `pending` (nothing decided yet, or some items still PENDING/undecided), `match` (every item MATCH), `short` (any SHORT), `over` (any OVER), `mixed` (both SHORT and OVER present)\n\n**Discrepancy mapping** (per item, recomputed on every sync):\n- `amazon_status` NOT in (`RECEIVING`, `CLOSED`) → `null` (too early to judge)\n- received == shipped → `MATCH`\n- received > shipped → `OVER`\n- received < shipped and `amazon_status` = `CLOSED` → `SHORT` (final shortage)\n- received < shipped and `amazon_status` = `RECEIVING` → `PENDING` (still being received)\n\nResponses include `items` (id, msku, fnsku, quantity_shipped, quantity_received). Pallets, transportation options, and delivery window options are NOT loaded on the board endpoint — use **List Shipments** (Placement & Transport) for those.\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/board","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","board"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipments\": [\n      {\n        \"id\": 15,\n        \"amazon_shipment_id\": \"sh-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n        \"shipment_confirmation_id\": \"FBA15K7Z9QXM\",\n        \"name\": \"Shipment 1 of 2\",\n        \"destination_fc\": \"TEB9\",\n        \"destination_address\": {\n          \"name\": \"Amazon.com Services LLC (TEB9)\",\n          \"addressLine1\": \"2170 State Route 27\",\n          \"city\": \"Edison\",\n          \"stateOrProvinceCode\": \"NJ\",\n          \"postalCode\": 8817,\n          \"countryCode\": \"US\"\n        },\n        \"amazon_status\": \"CLOSED\",\n        \"local_status\": \"shipped\",\n        \"tracking_summary\": null,\n        \"freight_bill_numbers\": null,\n        \"delivery_window_option_id\": null,\n        \"confirmed_delivery_window\": null,\n        \"shipped_at\": \"2026-05-04T00:00:00.000000Z\",\n        \"items\": [\n          {\n            \"id\": 61,\n            \"msku\": \"WIDGET-BLUE-L\",\n            \"fnsku\": \"X001ABC123\",\n            \"quantity_shipped\": 40,\n            \"quantity_received\": 36\n          },\n          {\n            \"id\": 62,\n            \"msku\": \"WIDGET-RED-S\",\n            \"fnsku\": \"X001DEF456\",\n            \"quantity_shipped\": 12,\n            \"quantity_received\": 12\n          }\n        ],\n        \"days_since_shipped\": 39,\n        \"units_shipped\": 52,\n        \"units_received\": 48,\n        \"boxes_count\": 6,\n        \"claim_deadline\": \"2026-07-03\",\n        \"claim_days_remaining\": 21,\n        \"reconciliation_status\": \"short\"\n      },\n      {\n        \"id\": 16,\n        \"amazon_shipment_id\": \"sh-1b2c3d4e-5f6a-7890-bcde-f01234567890\",\n        \"shipment_confirmation_id\": \"FBA15K8A2RLN\",\n        \"name\": \"Shipment 2 of 2\",\n        \"destination_fc\": \"ONT8\",\n        \"destination_address\": {\n          \"name\": \"Amazon.com Services LLC (ONT8)\",\n          \"addressLine1\": \"24300 Nandina Ave\",\n          \"city\": \"Moreno Valley\",\n          \"stateOrProvinceCode\": \"CA\",\n          \"postalCode\": \"92551\",\n          \"countryCode\": \"US\"\n        },\n        \"amazon_status\": \"RECEIVING\",\n        \"local_status\": \"receiving\",\n        \"tracking_summary\": null,\n        \"freight_bill_numbers\": [\n          \"FB123456789\"\n        ],\n        \"delivery_window_option_id\": \"dw-5e6f7a8b-9c0d-1234-ef56-678901234567\",\n        \"confirmed_delivery_window\": {\n          \"startDate\": \"2026-06-08T08:00:00Z\",\n          \"endDate\": \"2026-06-14T20:00:00Z\",\n          \"availabilityType\": \"AVAILABLE\"\n        },\n        \"shipped_at\": \"2026-06-01T00:00:00.000000Z\",\n        \"items\": [\n          {\n            \"id\": 63,\n            \"msku\": \"GADGET-GRN-M\",\n            \"fnsku\": \"X001GHI789\",\n            \"quantity_shipped\": 60,\n            \"quantity_received\": 25\n          }\n        ],\n        \"days_since_shipped\": 11,\n        \"units_shipped\": 60,\n        \"units_received\": 25,\n        \"boxes_count\": 4,\n        \"claim_deadline\": \"2026-07-31\",\n        \"claim_days_remaining\": 49,\n        \"reconciliation_status\": \"pending\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Reconciliation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/reconciliation","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","reconciliation"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Per-shipment reconciliation grid for a draft inbound plan: shipped vs received per item with the discrepancy delta, discrepancy status, and resolution state. Products are resolved through the plan's items by MSKU — `product` is null when the MSKU is not (or no longer) on the plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Shipment fields:** `id`, `name`, `shipment_confirmation_id`, `amazon_status`, `claim_deadline` (date|null, `shipped_at` + 60 days), `claim_days_remaining` (integer|null, negative once lapsed), `items[]`.\n\n**Item fields:**\n- `id` (integer) — shipment item id (use for the resolve/unresolve endpoints)\n- `msku` / `fnsku` (string)\n- `quantity_shipped` / `quantity_received` (integer)\n- `discrepancy` (integer) — `quantity_received - quantity_shipped` (negative = short, positive = over)\n- `discrepancy_status` (string|null) — `PENDING`, `MATCH`, `SHORT`, `OVER`, or null when the shipment is not yet RECEIVING/CLOSED\n- `discrepancy_resolved_at` (datetime|null) / `resolution_note` (string|null) — the acknowledge-resolution overlay (does not change `discrepancy_status`)\n- `product` (object|null) — `id`, `sku`, `name`, `image_url`\n\n**Discrepancy mapping** (per item, recomputed on every sync):\n- `amazon_status` NOT in (`RECEIVING`, `CLOSED`) → `null` (too early to judge)\n- received == shipped → `MATCH`\n- received > shipped → `OVER`\n- received < shipped and `amazon_status` = `CLOSED` → `SHORT` (final shortage)\n- received < shipped and `amazon_status` = `RECEIVING` → `PENDING` (still being received)\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/reconciliation","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","reconciliation"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipments\": [\n      {\n        \"id\": 15,\n        \"name\": \"Shipment 1 of 2\",\n        \"shipment_confirmation_id\": \"FBA15K7Z9QXM\",\n        \"amazon_status\": \"CLOSED\",\n        \"claim_deadline\": \"2026-07-03\",\n        \"claim_days_remaining\": 21,\n        \"items\": [\n          {\n            \"id\": 61,\n            \"msku\": \"WIDGET-BLUE-L\",\n            \"fnsku\": \"X001ABC123\",\n            \"quantity_shipped\": 40,\n            \"quantity_received\": 36,\n            \"discrepancy\": -4,\n            \"discrepancy_status\": \"SHORT\",\n            \"discrepancy_resolved_at\": null,\n            \"resolution_note\": null,\n            \"product\": {\n              \"id\": 412,\n              \"sku\": \"WIDGET-BLUE-L\",\n              \"name\": \"Widget - Blue, Large\",\n              \"image_url\": \"https://cdn.sku.io/products/412/primary.jpg\"\n            }\n          },\n          {\n            \"id\": 62,\n            \"msku\": \"WIDGET-RED-S\",\n            \"fnsku\": \"X001DEF456\",\n            \"quantity_shipped\": 12,\n            \"quantity_received\": 12,\n            \"discrepancy\": 0,\n            \"discrepancy_status\": \"MATCH\",\n            \"discrepancy_resolved_at\": null,\n            \"resolution_note\": null,\n            \"product\": {\n              \"id\": 413,\n              \"sku\": \"WIDGET-RED-S\",\n              \"name\": \"Widget - Red, Small\",\n              \"image_url\": \"https://cdn.sku.io/products/413/primary.jpg\"\n            }\n          }\n        ]\n      },\n      {\n        \"id\": 16,\n        \"name\": \"Shipment 2 of 2\",\n        \"shipment_confirmation_id\": \"FBA15K8A2RLN\",\n        \"amazon_status\": \"RECEIVING\",\n        \"claim_deadline\": \"2026-07-31\",\n        \"claim_days_remaining\": 49,\n        \"items\": [\n          {\n            \"id\": 63,\n            \"msku\": \"GADGET-GRN-M\",\n            \"fnsku\": \"X001GHI789\",\n            \"quantity_shipped\": 60,\n            \"quantity_received\": 25,\n            \"discrepancy\": -35,\n            \"discrepancy_status\": \"PENDING\",\n            \"discrepancy_resolved_at\": null,\n            \"resolution_note\": null,\n            \"product\": {\n              \"id\": 418,\n              \"sku\": \"GADGET-GRN-M\",\n              \"name\": \"Gadget - Green, Medium\",\n              \"image_url\": \"https://cdn.sku.io/products/418/primary.jpg\"\n            }\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Resolve Discrepancy Item","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/items/{shipment_item}/resolve","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","items",":shipment_item","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"shipment_item","value":"61","description":"The shipment item ID."}]},"description":"Acknowledge (resolve) a shipment item's discrepancy with a note — e.g. after filing an Amazon reimbursement case for a SHORT item. Resolution is an overlay: it stamps `discrepancy_resolved_at` and `resolution_note` but leaves `discrepancy_status` untouched. Resolved items drop out of the tenant-level discrepancies report (unless `filter[resolved]=1`). Reversible via **Unresolve Discrepancy Item**.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResolvable statuses: `SHORT`, `OVER`, and `PENDING`. Items with no discrepancy (`MATCH` or null status) return a 422.\n\n**Fields:**\n- `resolution_note` (string, **required**, max 1000) — why/how the discrepancy was handled\n\n**Response:** the updated reconciliation item payload (same shape as the **Get Reconciliation** items).\n\n**Errors:**\n- 404 — the shipment item does not belong to this draft inbound plan\n- 422 — the item has no discrepancy to resolve (status `MATCH` or null)\n- 422 — `resolution_note` missing or longer than 1000 characters\n\n**Authentication:** Bearer token (PAT).","body":{"mode":"raw","raw":"{\n  \"resolution_note\": \"Filed reimbursement case 12345-67890 with Amazon for the 4 missing units.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/items/{shipment_item}/resolve","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","items",":shipment_item","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"shipment_item","value":"61","description":"The shipment item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 61,\n    \"msku\": \"WIDGET-BLUE-L\",\n    \"fnsku\": \"X001ABC123\",\n    \"quantity_shipped\": 40,\n    \"quantity_received\": 36,\n    \"discrepancy\": -4,\n    \"discrepancy_status\": \"SHORT\",\n    \"discrepancy_resolved_at\": \"2026-06-12T15:21:09.000000Z\",\n    \"resolution_note\": \"Filed reimbursement case 12345-67890 with Amazon for the 4 missing units.\",\n    \"product\": {\n      \"id\": 412,\n      \"sku\": \"WIDGET-BLUE-L\",\n      \"name\": \"Widget - Blue, Large\",\n      \"image_url\": \"https://cdn.sku.io/products/412/primary.jpg\"\n    }\n  }\n}"}]},{"name":"Unresolve Discrepancy Item","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/items/{shipment_item}/unresolve","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","items",":shipment_item","unresolve"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"shipment_item","value":"61","description":"The shipment item ID."}]},"description":"Clear a shipment item's discrepancy resolution — nulls `discrepancy_resolved_at` and `resolution_note`, returning the item to the unresolved pool (it reappears in the tenant-level discrepancies report). `discrepancy_status` is untouched. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** the updated reconciliation item payload (same shape as the **Get Reconciliation** items).\n\n**Errors:**\n- 404 — the shipment item does not belong to this draft inbound plan\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/tracking/items/{shipment_item}/unresolve","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","tracking","items",":shipment_item","unresolve"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"shipment_item","value":"61","description":"The shipment item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 61,\n    \"msku\": \"WIDGET-BLUE-L\",\n    \"fnsku\": \"X001ABC123\",\n    \"quantity_shipped\": 40,\n    \"quantity_received\": 36,\n    \"discrepancy\": -4,\n    \"discrepancy_status\": \"SHORT\",\n    \"discrepancy_resolved_at\": null,\n    \"resolution_note\": null,\n    \"product\": {\n      \"id\": 412,\n      \"sku\": \"WIDGET-BLUE-L\",\n      \"name\": \"Widget - Blue, Large\",\n      \"image_url\": \"https://cdn.sku.io/products/412/primary.jpg\"\n    }\n  }\n}"}]},{"name":"Refresh Shipment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]},"description":"Synchronous on-demand refresh of one shipment from Amazon (the board's refresh button): runs SP-API `getShipment` (status + tracking) and `listShipmentItems` (shipped/received quantities), then recomputes the per-item discrepancy statuses. Returns the shipment's updated board entry. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReceived quantities are only updated when Amazon includes a received-quantity key — absent keys never zero out previously synced values. The same refresh also runs hourly for all non-terminal shipments via the scheduled `amazon:fba-inbound:sync-shipments` sweep (terminal Amazon statuses: `CLOSED`, `CANCELLED`, `DELETED`).\n\n**Response:** the updated shipment in **Get Shipment Board** entry shape (standard plan-shipment payload + `days_since_shipped`, `units_shipped`, `units_received`, `boxes_count`, `claim_deadline`, `claim_days_remaining`, `reconciliation_status`).\n\n**Errors:**\n- 404 — the shipment does not belong to this draft inbound plan\n- 422 — Amazon rejected the request (SP-API client-error messages are parsed and surfaced per field)\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"amazon_shipment_id\": \"sh-0a1b2c3d-4e5f-6789-abcd-ef0123456789\",\n    \"shipment_confirmation_id\": \"FBA15K7Z9QXM\",\n    \"name\": \"Shipment 1 of 2\",\n    \"destination_fc\": \"TEB9\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com Services LLC (TEB9)\",\n      \"addressLine1\": \"2170 State Route 27\",\n      \"city\": \"Edison\",\n      \"stateOrProvinceCode\": \"NJ\",\n      \"postalCode\": 8817,\n      \"countryCode\": \"US\"\n    },\n    \"amazon_status\": \"CLOSED\",\n    \"local_status\": \"shipped\",\n    \"tracking_summary\": null,\n    \"freight_bill_numbers\": null,\n    \"delivery_window_option_id\": null,\n    \"confirmed_delivery_window\": null,\n    \"shipped_at\": \"2026-05-04T00:00:00.000000Z\",\n    \"items\": [\n      {\n        \"id\": 61,\n        \"msku\": \"WIDGET-BLUE-L\",\n        \"fnsku\": \"X001ABC123\",\n        \"quantity_shipped\": 40,\n        \"quantity_received\": 36\n      },\n      {\n        \"id\": 62,\n        \"msku\": \"WIDGET-RED-S\",\n        \"fnsku\": \"X001DEF456\",\n        \"quantity_shipped\": 12,\n        \"quantity_received\": 12\n      }\n    ],\n    \"days_since_shipped\": 39,\n    \"units_shipped\": 52,\n    \"units_received\": 48,\n    \"boxes_count\": 6,\n    \"claim_deadline\": \"2026-07-03\",\n    \"claim_days_remaining\": 21,\n    \"reconciliation_status\": \"short\"\n  }\n}"}]},{"name":"Generate Content Update Previews","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]},"description":"Start generating content update previews (\"Adjust shipment\") for a shipped shipment via the async SP-API `generateShipmentContentUpdatePreviews` operation — used to correct box contents / item quantities after the fact. Dispatches the tracked job **\"Generate FBA Content Update Previews: {plan name}\"** and returns its `tracked_job_log_id` for the tracked job log endpoints; once the job completes, fetch the previews via **List Content Update Previews** and apply one via **Confirm Content Update Preview**.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBoxes and items are passed through to Amazon in SP-API shape — only the load-bearing keys are validated locally; everything else is validated by Amazon (failures surface on the tracked job).\n\n**Fields:**\n- `boxes` (array, **required**, min 1) — the full updated box list in SP-API shape: `contentInformationSource`, `dimensions` (length/width/height/unitOfMeasurement), `weight` (value/unit), `quantity`, and `items` (msku/quantity/labelOwner/prepOwner, optional expiration)\n- `items` (array, **required**, min 1) — the updated shipment item totals:\n  - `items.*.msku` (string, **required**, max 255)\n  - `items.*.quantity` (integer, **required**, min 0) — the new total shipped quantity for the MSKU\n  - `items.*.labelOwner` / `items.*.prepOwner` / `items.*.expiration` — passed through to Amazon when provided\n\n**Errors:**\n- 404 — the shipment does not belong to this draft inbound plan\n- 422 — validation failure (`boxes`/`items` missing or empty, item rows missing `msku`/`quantity`)\n\n**Authentication:** Bearer token (PAT).","body":{"mode":"raw","raw":"{\n  \"boxes\": [\n    {\n      \"contentInformationSource\": \"BOX_CONTENT_PROVIDED\",\n      \"dimensions\": {\n        \"length\": 18,\n        \"width\": 14,\n        \"height\": 12,\n        \"unitOfMeasurement\": \"IN\"\n      },\n      \"weight\": {\n        \"value\": 28.5,\n        \"unit\": \"LB\"\n      },\n      \"quantity\": 1,\n      \"items\": [\n        {\n          \"msku\": \"WIDGET-BLUE-L\",\n          \"quantity\": 36,\n          \"labelOwner\": \"SELLER\",\n          \"prepOwner\": \"SELLER\"\n        },\n        {\n          \"msku\": \"WIDGET-RED-S\",\n          \"quantity\": 12,\n          \"labelOwner\": \"SELLER\",\n          \"prepOwner\": \"SELLER\"\n        }\n      ]\n    }\n  ],\n  \"items\": [\n    {\n      \"msku\": \"WIDGET-BLUE-L\",\n      \"quantity\": 36,\n      \"labelOwner\": \"SELLER\",\n      \"prepOwner\": \"SELLER\"\n    },\n    {\n      \"msku\": \"WIDGET-RED-S\",\n      \"quantity\": 12,\n      \"labelOwner\": \"SELLER\",\n      \"prepOwner\": \"SELLER\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates/generate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates","generate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 412\n  },\n  \"message\": \"Content update preview generation started\"\n}"}]},{"name":"List Content Update Previews","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]},"description":"Synchronous raw passthrough of Amazon's content update previews for a shipment (SP-API `listShipmentContentUpdatePreviews`, all pages merged — no local mirror tables). Each preview is Amazon's native payload: `contentUpdatePreviewId` (use with **Confirm Content Update Preview**), `expiration`, `requestedUpdates` (the boxes/items you submitted), and `transportationOption` (the re-quoted transportation for the updated contents).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Errors:**\n- 404 — the shipment does not belong to this draft inbound plan\n- 422 — Amazon rejected the request (SP-API client-error messages are parsed and surfaced per field)\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"previews\": [\n      {\n        \"contentUpdatePreviewId\": \"cu-6f7a8b9c-0d1e-2345-f678-901234567890\",\n        \"expiration\": \"2026-06-13T18:00:00Z\",\n        \"requestedUpdates\": {\n          \"boxes\": [\n            {\n              \"boxId\": \"FBA15K7Z9QXM000001\",\n              \"contentInformationSource\": \"BOX_CONTENT_PROVIDED\",\n              \"dimensions\": {\n                \"length\": 18,\n                \"width\": 14,\n                \"height\": 12,\n                \"unitOfMeasurement\": \"IN\"\n              },\n              \"weight\": {\n                \"value\": 28.5,\n                \"unit\": \"LB\"\n              },\n              \"quantity\": 1,\n              \"items\": [\n                {\n                  \"msku\": \"WIDGET-BLUE-L\",\n                  \"quantity\": 36,\n                  \"labelOwner\": \"SELLER\",\n                  \"prepOwner\": \"SELLER\"\n                }\n              ]\n            }\n          ],\n          \"items\": [\n            {\n              \"msku\": \"WIDGET-BLUE-L\",\n              \"quantity\": 36,\n              \"labelOwner\": \"SELLER\",\n              \"prepOwner\": \"SELLER\"\n            }\n          ]\n        },\n        \"transportationOption\": {\n          \"transportationOptionId\": \"to-7a8b9c0d-1e2f-3456-7890-123456789012\",\n          \"program\": \"AMAZON_PARTNERED_CARRIER\",\n          \"shippingMode\": \"GROUND_SMALL_PARCEL\",\n          \"carrier\": {\n            \"alphaCode\": \"UPSN\",\n            \"name\": \"United Parcel Service Inc.\"\n          },\n          \"quote\": {\n            \"cost\": {\n              \"amount\": 9.84,\n              \"code\": \"USD\"\n            },\n            \"expiration\": \"2026-06-13T18:00:00Z\"\n          }\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Confirm Content Update Preview","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates/{contentUpdatePreviewId}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates",":contentUpdatePreviewId","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."},{"key":"contentUpdatePreviewId","value":"cu-6f7a8b9c-0d1e-2345-f678-901234567890","description":"The content update preview ID."}]},"description":"Apply a previously generated content update preview via the async SP-API `confirmShipmentContentUpdatePreview` operation. Dispatches the tracked job **\"Confirm FBA Content Update: {plan name}\"** and returns its `tracked_job_log_id` for the tracked job log endpoints. No request body — the preview id comes from **List Content Update Previews** (`contentUpdatePreviewId`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job only starts the async Amazon operation; the tracked job log is completed (or failed) by the operation poller once Amazon reaches a terminal state. On SUCCESS the shipment items are re-synced from Amazon first, so `quantity_shipped` reflects the accepted deltas, and discrepancy statuses are recomputed.\n\n**Errors:**\n- 404 — the shipment does not belong to this draft inbound plan\n- (async) an invalid/expired preview id fails on the tracked job, not the HTTP response\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/shipments/{plan_shipment}/content-updates/{contentUpdatePreviewId}/confirm","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","shipments",":plan_shipment","content-updates",":contentUpdatePreviewId","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."},{"key":"plan_shipment","value":"15","description":"The plan shipment ID."},{"key":"contentUpdatePreviewId","value":"cu-6f7a8b9c-0d1e-2345-f678-901234567890","description":"The content update preview ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 413\n  },\n  \"message\": \"Content update confirmation started\"\n}"}]},{"name":"List Inbound Discrepancies (Tenant-Level)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba-inbound/discrepancies","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba-inbound","discrepancies"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Tenant-level FBA inbound discrepancies report — note the URL: this endpoint lives at `/api/amazon/{integrationInstance}/fba-inbound/discrepancies`, OUTSIDE the per-plan `draft-inbound-plans/{draft_inbound_plan}` group, because it aggregates across ALL of the instance's inbound plans.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns every `SHORT`/`OVER` shipment item across the instance's plans (unresolved only by default), ordered by `claim_days_remaining` ascending — the most urgent reimbursement claim windows first; shipments without a ship date sort last. `PENDING`/`MATCH` items are never included.\n\n**Query parameters:**\n- `filter[resolved]` (boolean, optional) — `1`/`true` also includes resolved (acknowledged) items. Default: unresolved only\n\n**Row fields:**\n- `plan_id` / `plan_name` — the draft inbound plan\n- `shipment_id` / `shipment_name` / `shipment_confirmation_id` — the shipment (e.g. `FBA15K7Z9QXM`)\n- `claim_deadline` (date|null) — `shipped_at` + 60 days (Amazon reimbursement claim window)\n- `claim_days_remaining` (integer|null) — whole days until the deadline (negative once lapsed); null when the shipment has no ship date\n- `approaching_deadline` (boolean) — true when `claim_days_remaining` is ≤ 14 (time to file a claim)\n- `item` — `msku`, `fnsku`, `quantity_shipped`, `quantity_received`, `discrepancy` (received - shipped), `discrepancy_status` (`SHORT` or `OVER`), `discrepancy_resolved_at`, `resolution_note`\n\n**Authentication:** Bearer token (PAT)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba-inbound/discrepancies","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba-inbound","discrepancies"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"plan_id\": 7,\n      \"plan_name\": \"June Replenishment - East\",\n      \"shipment_id\": 12,\n      \"shipment_name\": \"Shipment 1 of 1\",\n      \"shipment_confirmation_id\": \"FBA15K5T3PWB\",\n      \"claim_deadline\": \"2026-06-20\",\n      \"claim_days_remaining\": 8,\n      \"approaching_deadline\": true,\n      \"item\": {\n        \"msku\": \"GIZMO-BLK-XL\",\n        \"fnsku\": \"X001JKL012\",\n        \"quantity_shipped\": 100,\n        \"quantity_received\": 88,\n        \"discrepancy\": -12,\n        \"discrepancy_status\": \"SHORT\",\n        \"discrepancy_resolved_at\": null,\n        \"resolution_note\": null\n      }\n    },\n    {\n      \"plan_id\": 9,\n      \"plan_name\": \"May Replenishment - West\",\n      \"shipment_id\": 15,\n      \"shipment_name\": \"Shipment 1 of 2\",\n      \"shipment_confirmation_id\": \"FBA15K7Z9QXM\",\n      \"claim_deadline\": \"2026-07-03\",\n      \"claim_days_remaining\": 21,\n      \"approaching_deadline\": false,\n      \"item\": {\n        \"msku\": \"WIDGET-BLUE-L\",\n        \"fnsku\": \"X001ABC123\",\n        \"quantity_shipped\": 40,\n        \"quantity_received\": 36,\n        \"discrepancy\": -4,\n        \"discrepancy_status\": \"SHORT\",\n        \"discrepancy_resolved_at\": null,\n        \"resolution_note\": null\n      }\n    },\n    {\n      \"plan_id\": 9,\n      \"plan_name\": \"May Replenishment - West\",\n      \"shipment_id\": 16,\n      \"shipment_name\": \"Shipment 2 of 2\",\n      \"shipment_confirmation_id\": \"FBA15K8A2RLN\",\n      \"claim_deadline\": \"2026-07-31\",\n      \"claim_days_remaining\": 49,\n      \"approaching_deadline\": false,\n      \"item\": {\n        \"msku\": \"GADGET-GRN-M\",\n        \"fnsku\": \"X001GHI789\",\n        \"quantity_shipped\": 60,\n        \"quantity_received\": 63,\n        \"discrepancy\": 3,\n        \"discrepancy_status\": \"OVER\",\n        \"discrepancy_resolved_at\": null,\n        \"resolution_note\": null\n      }\n    }\n  ]\n}"}]},{"name":"Refresh from Amazon","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/refresh-amazon-plan","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","refresh-amazon-plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Refresh a submitted plan from Amazon. Pulls the latest plan + shipment state from Amazon's Fulfillment Inbound API (`getInboundPlan`, `getShipment`, `listShipmentItems`) and mirrors it onto the linked `AmazonNewFbaInboundPlan` (status, shipments, accepted items). Use this to reconcile the in-app plan with Seller Central after submission.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the updated draft Amazon FBA inbound plan object with the refreshed `amazon_new_fba_inbound_plan` relationship loaded."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/refresh-amazon-plan","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","refresh-amazon-plan"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"portal_access_hash\": \"eyJpdiI6Ii4uLiI...\",\n    \"integration_instance_id\": 1,\n    \"warehouse_id\": 5,\n    \"warehouse_country_code\": \"US\",\n    \"name\": \"Q2 Restock\",\n    \"status\": \"submitted_to_amazon\",\n    \"workflow_step\": 7,\n    \"source_mode\": \"warehouse_transfer\",\n    \"source_warehouse_id\": 8,\n    \"source_warehouse_name\": \"Main Warehouse\",\n    \"source_type\": \"warehouse\",\n    \"source_supplier_name\": null,\n    \"warehouse_type\": \"standard\",\n    \"warehouse_transfer_id\": 17,\n    \"amazon_new_fba_inbound_plan\": {\n      \"id\": 33,\n      \"inboundPlanId\": \"wf52bdb8a9-d197-4d95-9f60-07d2293b587d\",\n      \"status\": \"ACTIVE\",\n      \"items_fetched\": true,\n      \"sent_count\": 2,\n      \"accepted_count\": 2,\n      \"excluded_items\": [],\n      \"shipments\": [\n        {\n          \"id\": 91,\n          \"shipmentConfirmationId\": \"FBA15ABCDEFG\",\n          \"sku_link_type\": \"warehouse_transfer\",\n          \"sku_link_id\": 17\n        }\n      ]\n    },\n    \"items\": [\n      {\n        \"id\": 501,\n        \"product_id\": 42,\n        \"msku\": \"SKU-1\",\n        \"quantity\": 30\n      },\n      {\n        \"id\": 502,\n        \"product_id\": 77,\n        \"msku\": \"SKU-2\",\n        \"quantity\": 20\n      }\n    ],\n    \"inventory_inquiry_last_processed_at\": null,\n    \"created_at\": \"2026-06-10T22:00:00.000000Z\",\n    \"updated_at\": \"2026-06-14T10:05:00.000000Z\"\n  }\n}"}]},{"name":"List Inbound Plans (Tab)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/list","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","list"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Paginated listing for the FBA Inbound \"Inbound Plans\" tab. Mirrors each plan's Amazon status (ACTIVE / SHIPPED / VOIDED / ERRORED) and INCLUDES orphan (\"Unlinked\") plans that have no linked SKU draft.\n\nRequires a Bearer token.\n\nEach row exposes `source_type` (\"warehouse\" | \"supplier\" | null) and `source_id` so the UI can deep-link the source to its detail page, plus `draft_id` for linked plans (deep-link into the in-app workflow). The response also carries `status_counts` (per-Amazon-status totals powering the metric cards) and `unfiltered_total` (the tab's total ignoring filters). Linked rows also expose `created_by_user_id` / `created_by` — the user who created the draft in-app (null for unlinked / Seller Central plans and drafts that predate creator tracking).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/list","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","list"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 412,\n      \"inboundPlanId\": \"wf1a2b3c4d\",\n      \"name\": \"Q1 Restock - West\",\n      \"status\": \"ACTIVE\",\n      \"status_label\": \"Active\",\n      \"sourceName\": \"Main Warehouse\",\n      \"sourceCountry\": \"US\",\n      \"source_type\": \"warehouse\",\n      \"source_id\": 4,\n      \"is_awd\": false,\n      \"shipment_count\": 2,\n      \"is_unlinked\": false,\n      \"draft_id\": 65,\n      \"draft_status\": \"submitted_to_amazon\",\n      \"draft_status_label\": \"Submitted To Amazon\",\n      \"created_by_user_id\": 7,\n      \"created_by\": \"Jane Smith\",\n      \"lastUpdatedAt\": \"2026-06-14T18:22:00Z\",\n      \"createdAt\": \"2026-06-10T12:00:00Z\",\n      \"created_at\": \"2026-06-10T12:00:00.000000Z\",\n      \"updated_at\": \"2026-06-14T18:22:00.000000Z\"\n    },\n    {\n      \"id\": 388,\n      \"inboundPlanId\": \"wf9z8y7x6w\",\n      \"name\": \"Seller Central Plan\",\n      \"status\": \"VOIDED\",\n      \"status_label\": \"Voided\",\n      \"sourceName\": null,\n      \"sourceCountry\": \"US\",\n      \"source_type\": null,\n      \"source_id\": null,\n      \"is_awd\": false,\n      \"shipment_count\": 1,\n      \"is_unlinked\": true,\n      \"draft_id\": null,\n      \"draft_status\": null,\n      \"draft_status_label\": null,\n      \"created_by_user_id\": null,\n      \"created_by\": null,\n      \"lastUpdatedAt\": \"2026-05-30T09:10:00Z\",\n      \"createdAt\": \"2026-05-28T08:00:00Z\",\n      \"created_at\": \"2026-05-28T08:00:00.000000Z\",\n      \"updated_at\": \"2026-05-30T09:10:00.000000Z\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"...\",\n    \"last\": \"...\",\n    \"prev\": null,\n    \"next\": null\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 1,\n    \"per_page\": 15,\n    \"to\": 2,\n    \"total\": 2\n  },\n  \"unfiltered_total\": 96,\n  \"status_counts\": {\n    \"total\": 96,\n    \"ACTIVE\": 64,\n    \"SHIPPED\": 6,\n    \"VOIDED\": 24,\n    \"ERRORED\": 2\n  }\n}"}]},{"name":"Bulk Void Inbound Plans","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/bulk-void","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","bulk-void"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk-void selected inbound plans on Amazon — cleanup of stale plans from the \"Inbound Plans\" tab. Dispatches a tracked background job (follow it via the tracked job log endpoints) and returns its `tracked_job_log_id`.\n\nRequires a Bearer token.\n\nVoiding mirrors Amazon's status to VOIDED. Linked plans also have their in-app draft aborted and any reserved warehouse transfer released back to stock; orphan (unlinked) plans are voided directly. Plans already VOIDED are skipped, and plans Amazon refuses to void (already shipped/closed) are captured as per-plan failures without aborting the batch.\n\nBody: `ids` — array of AmazonNewFbaInboundPlan primary keys (the `id` field from the list endpoint). Required, 1-1000 integers.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    412,\n    388\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/bulk-void","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","bulk-void"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9123\n  },\n  \"message\": \"Voiding 2 plan(s) — track progress in the job tray.\"\n}"}]},{"name":"Refresh Inbound Plans From Amazon","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/refresh-from-amazon","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","refresh-from-amazon"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Refresh the \"Inbound Plans\" tab from Amazon. Dispatches a tracked background job (follow it via the tracked job log endpoints) and returns its tracked_job_log_id.\n\nRequires a Bearer token.\n\nBody (all optional; defaults to a full re-sync):\n- mode: all | since_latest | from_start_date | date_range\n- latest_date: lower bound for since_latest (ISO 8601 / date)\n- date_from: lower bound for from_start_date and date_range (Y-m-d)\n- date_to: upper bound for date_range (Y-m-d)\n\nBounds are applied against each plan's lastUpdatedAt; Amazon's list is paged sorted by LAST_UPDATED_TIME DESC and stops once it passes the lower bound.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-01-01\",\n  \"date_to\": \"2026-02-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/refresh-from-amazon","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","refresh-from-amazon"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9123\n  },\n  \"message\": \"Refresh started — track progress in the job tray.\"\n}"}]},{"name":"Inbound Plan Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/sync-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Sync-info for the Refresh Inbound Plans modal header and \"Fetch Since Latest\" mode: the most recently updated plan already synced locally plus the total count.\n\nRequires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/sync-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latestIdentifier\": \"Q1 Restock - West\",\n    \"latestDate\": \"2026-03-01T00:00:00Z\",\n    \"totalCount\": 96\n  }\n}"}]},{"name":"Search Inbound Plans","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/search?query=wf1a2b3c4d","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","search"],"query":[{"key":"query","value":"wf1a2b3c4d","description":"The Amazon inbound plan id to look up (required)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Search a single inbound plan on Amazon by its inbound plan id (the modal's \"Search Specific Inbound\" tab). Amazon's list API has no id search, so this fetches the plan directly — which also imports/refreshes it — and returns an array with 0 or 1 OrderSearchResult-shaped row.\n\nRequires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/search?query=wf1a2b3c4d","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","search"],"query":[{"key":"query","value":"wf1a2b3c4d","description":"The Amazon inbound plan id to look up (required)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"wf1a2b3c4d\",\n      \"name\": \"Q1 Restock - West\",\n      \"email\": null,\n      \"createdAt\": \"2026-06-10T12:00:00Z\",\n      \"financialStatus\": null,\n      \"fulfillmentStatus\": \"ACTIVE\",\n      \"totalPrice\": null,\n      \"currency\": null,\n      \"existsInDatabase\": true\n    }\n  ]\n}"}]},{"name":"Refresh Single Inbound Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/refresh-single","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","refresh-single"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Download / refresh a single inbound plan from Amazon by its inbound plan id — the per-row action in the modal's search results.\n\nRequires a Bearer token.\n\nBody: uniqueId — the Amazon inbound plan id (required).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"wf1a2b3c4d\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/refresh-single","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","refresh-single"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound plan refreshed.\"\n}"}]},{"name":"Get Portal Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]},"description":"Plan header + line items for the external verification portal. No bearer token — access is granted by the encrypted `hashedDraftInboundPlanId` in the URL (single plan scope). Generated from the plan's `portal_access_hash`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Kit fields per item:** `is_kit` (boolean), `assemble_at_source` (boolean — the recipient builds this line's kits from components before shipping), `components` (the pick list when assemble_at_source: `sku`, `name`, `barcode`, `per_kit`, `total_units` = per_kit × quantity).\n\n`user_name` falls back to the merchant's store name when no inventory inquiry was explicitly sent."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"name\": \"SMO Inbound 2026/07/02\",\n    \"user_name\": \"Jane Operator\",\n    \"source_name\": \"ShipMyOrders Warehouse\",\n    \"created_at\": \"2026-07-02 16:36:09\",\n    \"status\": \"verification_in_progress\",\n    \"items\": [\n      {\n        \"product_id\": 707,\n        \"image_url\": null,\n        \"sku\": \"GSL392+400-939\",\n        \"name\": \"Walbro GSL392 Fuel Pump + 400-939 Installation Kit\",\n        \"barcode\": \"703929123456\",\n        \"quantity\": 30,\n        \"verified_quantity\": null,\n        \"is_kit\": true,\n        \"assemble_at_source\": true,\n        \"components\": [\n          {\n            \"sku\": \"GSL392\",\n            \"name\": \"Walbro GSL392 255 LPH Fuel Pump\",\n            \"barcode\": \"703929787488\",\n            \"per_kit\": 1,\n            \"total_units\": 30\n          },\n          {\n            \"sku\": \"400-939\",\n            \"name\": \"Installation Kit\",\n            \"barcode\": null,\n            \"per_kit\": 1,\n            \"total_units\": 30\n          }\n        ]\n      },\n      {\n        \"product_id\": 15,\n        \"image_url\": null,\n        \"sku\": \"GSL395\",\n        \"name\": \"Walbro GSL395 Fuel Pump\",\n        \"barcode\": \"703929111222\",\n        \"quantity\": 20,\n        \"verified_quantity\": null,\n        \"is_kit\": false,\n        \"assemble_at_source\": false,\n        \"components\": []\n      }\n    ]\n  }\n}"}]},{"name":"Verify Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/verify-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","verify-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]},"description":"Record the quantity the source can provide for one product (spread across the plan's lines for that product in order). For assemble-at-source kit lines the quantity is COMPLETE KITS buildable from component stock. No bearer token — access is granted by the encrypted `hashedDraftInboundPlanId` in the URL (single plan scope). Generated from the plan's `portal_access_hash`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"product_id\": 707,\n  \"verified_quantity\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/verify-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","verify-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Product verified\"\n}"}]},{"name":"Verify All Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/verify-all-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","verify-all-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]},"description":"Mark every line as verified at its requested quantity (the 'can fulfill everything' shortcut). No bearer token — access is granted by the encrypted `hashedDraftInboundPlanId` in the URL (single plan scope). Generated from the plan's `portal_access_hash`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/verify-all-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","verify-all-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"All products successfully verified\"\n}"}]},{"name":"Submit Verification","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/submit-verification","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","submit-verification"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]},"description":"Finalize the verification: plan moves to `verified` (or `verified_with_adjustments` when any line was verified short). Fails with 400 `cant_submit_verification_unless_all_items_verified` while any line is unverified. No bearer token — access is granted by the encrypted `hashedDraftInboundPlanId` in the URL (single plan scope). Generated from the plan's `portal_access_hash`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"Bad Request","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/portal/{hashedDraftInboundPlanId}/submit-verification","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","portal",":hashedDraftInboundPlanId","submit-verification"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"hashedDraftInboundPlanId","value":"","description":"The hashed draft inbound plan ID."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"errors\": {\n    \"cant_submit_verification_unless_all_items_verified\": [\n      {\n        \"message\": \"Cannot submit verification unless all items are verified.\"\n      }\n    ]\n  }\n}"}]},{"name":"Show Fulfillment Packet","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Detect 3PL/supplier fulfillment availability for the plan and return the built packet (or null when not yet built). `available` reflects whether the plan is eligible; `source_type` is `3pl` or `supplier`; `packet` is the FbaInboundFulfillmentPacket resource including `recipient_email`, `recipient_name`, and the editable `email_template`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`email_will_attach_fnsku_labels`** (boolean): whether the 3PL email can carry the FNSKU label PDF (a durable label file is already attached, or labels are generatable at send for seller-labelled items) — drives the compose dialog's attachment checkbox."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"available\": true,\n  \"source_type\": \"3pl\",\n  \"reason\": null,\n  \"packet\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Build Fulfillment Packet","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Build (or rebuild) the 3PL/supplier fulfillment packet for the plan: generates the prep documents, portal token, and default instructions. Body: `channels` (optional array of `api|email|portal`), `build_kits` (boolean, default true), `instruction_override` (optional string to replace the condition-aware default instructions).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`email_will_attach_fnsku_labels`** (boolean): whether the 3PL email can carry the FNSKU label PDF (a durable label file is already attached, or labels are generatable at send for seller-labelled items) — drives the compose dialog's attachment checkbox.","body":{"mode":"raw","raw":"{\n  \"channels\": [\n    \"portal\",\n    \"email\"\n  ],\n  \"build_kits\": true,\n  \"instruction_override\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment packet built.\",\n  \"data\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"email_will_attach_fnsku_labels\": true,\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Update Fulfillment Packet","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Update the fulfillment packet — same payload and behaviour as Build; re-runs the packet build with the supplied channels / kit flag / instruction override.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`email_will_attach_fnsku_labels`** (boolean): whether the 3PL email can carry the FNSKU label PDF (a durable label file is already attached, or labels are generatable at send for seller-labelled items) — drives the compose dialog's attachment checkbox.","body":{"mode":"raw","raw":"{\n  \"channels\": [\n    \"portal\",\n    \"email\"\n  ],\n  \"build_kits\": true,\n  \"instruction_override\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment packet built.\",\n  \"data\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"email_will_attach_fnsku_labels\": true,\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Download Prep & Pack Sheet CSV","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/prep-sheet.csv","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","prep-sheet.csv"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"draft_inbound_plan","value":"1","description":"Draft FBA inbound plan ID"}]},"description":"Download the fulfillment prep & pack sheet as a CSV file, to hand to a 3PL or supplier that won't use the fulfilment portal (e.g. for upload into their own system). The CSV contains a Unit Mix section (SKU, product, MSKU, FNSKU, UPC, quantity, unit weight, unit dimensions, who labels, who preps) and, once box contents have been submitted, a Box Contents section (box number, SKU, quantity) matching the box-import template so it round-trips.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: requires a Bearer token.\n\nReturns 422 if the fulfilment packet has not been built yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/prep-sheet.csv","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","prep-sheet.csv"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"draft_inbound_plan","value":"1","description":"Draft FBA inbound plan ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Unit Mix\nSKU,Product,MSKU,FNSKU,UPC,Qty,Unit weight,Unit dimensions,Who labels,Who preps\nSOAP-01,Shave Soap,1000070-FBA,X00ABCDEF1,850000000017,448,0.5 lb,4 x 4 x 2 in,SELLER,NONE\n\nBox Contents\nBox number,SKU,Qty\n1,SOAP-01,112"}]},{"name":"Send Fulfillment Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/send","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","send"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Dispatch the full fulfillment send as a tracked background job (marks documents + packet Sent and delivers the configured channels). Returns the tracked job log id to poll for progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/send","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","send"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order send started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 9001\n  }\n}"}]},{"name":"Preview 3PL Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/email/preview","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","email","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Preview the \"Email the 3PL\" compose dialog: substitutes the `{{reference}}`, `{{portal_link}}`, and `{{instructions}}` tokens in the supplied subject/body server-side and returns the rendered result (no email is sent). Body: `subject` (required, max 255), `body` (required HTML string), `cc` (optional array of email addresses).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"subject\": \"FBA inbound ready — WF-2026-000123\",\n  \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready.</p><p>{{portal_link}}</p><p>{{instructions}}</p>\",\n  \"cc\": [\n    \"ops@example.com\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/email/preview","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","email","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"subject\": \"FBA inbound ready — WF-2026-000123\",\n    \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>WF-2026-000123</strong>) is ready.</p><p><a href=\\\"https://app.sku.io/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\\\">https://app.sku.io/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1</a></p><p>Pack each MSKU into its own box.<br />Apply the provided FNSKU labels to every unit.</p>\"\n  }\n}"}]},{"name":"Send 3PL Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/email","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","email"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Send the operator-composed \"Email the 3PL\" portal invitation: resolves the 3PL/supplier recipient, substitutes the `{{reference}}`/`{{portal_link}}`/`{{instructions}}` tokens, marks the packet Sent, and dispatches FbaInboundPortalInviteNotification (CC honoured). Returns the updated FbaInboundFulfillmentPacket resource. Same body as the preview endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`attach_fnsku_labels`** (boolean, optional, default `true`): attach the FNSKU item-label PDF to the email. When no durable label file exists yet, labels are generated at send time for every seller-labelled item at its plan quantity (best-effort — a generation failure never blocks the email). Send `false` to omit the attachment.","body":{"mode":"raw","raw":"{\n  \"subject\": \"FBA inbound ready — WF-2026-000123\",\n  \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready.</p><p>{{portal_link}}</p><p>{{instructions}}</p>\",\n  \"cc\": [\n    \"ops@example.com\"\n  ],\n  \"attach_fnsku_labels\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/email","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","email"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Email sent to the 3PL.\",\n  \"data\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"sent\",\n    \"status_label\": \"Sent\",\n    \"sent_at\": \"2026-07-06T12:05:00+00:00\",\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Sync Label Documents","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/documents/sync-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","documents","sync-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Attach any newly-generated FBA label documents (FNSKU / box / pallet labels, BOL) from the plan to the fulfillment portal so the 3PL can download them. Returns the refreshed packet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/documents/sync-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","documents","sync-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Attached 2 label document(s) to the portal.\",\n  \"data\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Rotate Portal Link","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/portal-token/rotate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","portal-token","rotate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Rotate the portal token — invalidates the old portal link and issues a fresh one (and a new `portal_url`). Use when a link may have leaked. Returns the refreshed packet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/fulfillment/portal-token/rotate","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","fulfillment","portal-token","rotate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Portal link rotated.\",\n  \"data\": {\n    \"id\": 42,\n    \"draft_amazon_fba_inbound_plan_id\": 1,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL\",\n    \"channels\": [\n      \"portal\",\n      \"email\"\n    ],\n    \"integration_instance_id\": 1,\n    \"external_order_id\": null,\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/uCJ8x2n1QwErTy?integration=1\",\n    \"portal_token_expires_at\": \"2026-08-05T00:00:00+00:00\",\n    \"portal_revoked_at\": null,\n    \"is_portal_accessible\": true,\n    \"recipient_email\": \"warehouse@3pl.example.com\",\n    \"recipient_name\": \"Acme 3PL Fulfillment\",\n    \"email_template\": {\n      \"subject\": \"FBA inbound ready — {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>An Amazon FBA inbound shipment (<strong>{{reference}}</strong>) is ready for you to prepare and ship.</p><p>Please use the secure portal below to review the order and prep instructions, submit your box contents, and confirm when the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions</strong></p><p>{{instructions}}</p><p>Box/pallet labels and the bill of lading are prepared separately and will follow — the BOL is issued close to the pickup date.</p><p>Thank you.</p>\"\n    },\n    \"instructions\": \"Pack each MSKU into its own box. Apply the provided FNSKU labels to every unit, then the box labels to the outside of each carton.\",\n    \"instruction_override\": null,\n    \"has_custom_instructions\": false,\n    \"build_required\": false,\n    \"manufacturing_order_id\": null,\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"portal_submission\": null,\n    \"documents\": [\n      {\n        \"id\": 501,\n        \"type\": \"instructions\",\n        \"type_label\": \"Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      },\n      {\n        \"id\": 502,\n        \"type\": \"fnsku_labels\",\n        \"type_label\": \"FNSKU Labels\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"is_downloadable\": true,\n        \"ready_at\": \"2026-07-06T12:00:00+00:00\",\n        \"sent_at\": null\n      }\n    ],\n    \"created_at\": \"2026-07-06T12:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T12:00:00+00:00\"\n  }\n}"}]},{"name":"Get Portal Payload (3PL Portal)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]},"description":"Anonymous 3PL/supplier fulfillment portal entry point. Access is granted by the opaque `:token` in the URL (the packet's `portal_token`) — no bearer auth (`tenant.public-portal` middleware). Returns the full portal payload the 3PL sees: shipment reference + FBA id, source, the destination fulfillment center (`destination_fc`) and its **full destination address** (`destination_address`, Amazon SP-API camelCase keys — null until Amazon assigns placement), shipping mode / LTL flags, condition-aware `instructions` (markdown, rendered inline by the portal), downloadable `documents`, the product catalogue for the box-contents packing station (`products`), the tenant's saved carton presets (`carton_templates`), any existing `box_contents_submission` / `pallets_submission`, and the confirm gating (`can_confirm`, `confirm_blocked_reason`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**`products[]` fields:** each item carries `product_id`, `sku`, `name`, `image_url`, `msku`, `fnsku`, `barcode` (UPC — enables barcode scanning in the portal), `quantity` (required units), `label_owner` / `prep_owner` (AMAZON | SELLER | NONE — SELLER label_owner means the 3PL applies FNSKU labels; SELLER prep_owner means the 3PL must prep the item before boxing), and the unit measurements saved on the product record: `weight`, `weight_unit`, `length`, `width`, `height`, `dimension_unit`.\n\n**`documents[]`** lists only genuinely downloadable paperwork (kitting work order, FNSKU/box/pallet labels, BOL once attached). The renderable `instructions` and `box_contents` types are NOT listed — the portal renders instructions inline and collects box contents via its own form.\n\nEvery view is audit-logged (portal events). Returns 404 when the token is expired, rotated, or revoked.\n\n**`prep_details`** (object|null): the operator's last persisted Amazon prep-details fetch — `{details: [{msku, prepCategory, prepTypes[], ...}], fetched_at}` — powering the portal's per-category \"Required Prep Types\" breakdown. Null when prep details were never fetched."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"FBA-2026-000123\",\n    \"fba_shipment_id\": \"FBA15ABCDEF\",\n    \"source_name\": \"Acme 3PL Warehouse\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"ONT8\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com\",\n      \"addressLine1\": \"24208 San Michele Rd\",\n      \"addressLine2\": null,\n      \"city\": \"Moreno Valley\",\n      \"stateOrProvinceCode\": \"CA\",\n      \"postalCode\": \"92551\",\n      \"countryCode\": \"US\"\n    },\n    \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n    \"is_ltl\": false,\n    \"requires_pallets\": false,\n    \"status\": \"in_progress\",\n    \"requested_by\": \"Jane Buyer\",\n    \"build_required\": false,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [],\n    \"instructions\": \"# FBA Inbound Preparation Instructions\\nShipment: FBA15ABCDEF\\nShip to: Amazon ONT8\\n\\nPack each SKU into the boxes exactly as listed, label every box, then confirm ready to ship.\",\n    \"prep_details\": {\n      \"details\": [\n        {\n          \"msku\": \"ACME-SKU-A\",\n          \"prepCategory\": \"FRAGILE\",\n          \"prepTypes\": [\n            \"ITEM_BUBBLEWRAP\",\n            \"ITEM_LABELING\"\n          ],\n          \"labelOwnerConstraint\": null,\n          \"prepOwnerConstraint\": null,\n          \"allOwnersConstraint\": null\n        }\n      ],\n      \"fetched_at\": \"2026-07-07T05:00:00+00:00\"\n    },\n    \"documents\": [\n      {\n        \"id\": 41,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 44,\n        \"type\": \"box_labels\",\n        \"type_label\": \"Box Labels\",\n        \"stage\": \"mid\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"products\": [\n      {\n        \"product_id\": 5567,\n        \"sku\": \"SKU-A\",\n        \"name\": \"Acme Widget - Blue\",\n        \"image_url\": \"https://cdn.example.com/img/sku-a.jpg\",\n        \"msku\": \"ACME-SKU-A\",\n        \"fnsku\": \"X001ABCDEF\",\n        \"barcode\": \"812345678901\",\n        \"quantity\": 24,\n        \"label_owner\": \"SELLER\",\n        \"prep_owner\": \"SELLER\",\n        \"weight\": 1.4,\n        \"weight_unit\": \"lb\",\n        \"length\": 7.3,\n        \"width\": 4.9,\n        \"height\": 2.8,\n        \"dimension_unit\": \"in\"\n      },\n      {\n        \"product_id\": 5568,\n        \"sku\": \"SKU-B\",\n        \"name\": \"Acme Widget - Red\",\n        \"image_url\": null,\n        \"msku\": \"ACME-SKU-B\",\n        \"fnsku\": \"X001GHIJKL\",\n        \"barcode\": null,\n        \"quantity\": 12,\n        \"label_owner\": \"AMAZON\",\n        \"prep_owner\": \"NONE\",\n        \"weight\": null,\n        \"weight_unit\": null,\n        \"length\": null,\n        \"width\": null,\n        \"height\": null,\n        \"dimension_unit\": null\n      }\n    ],\n    \"carton_templates\": [\n      {\n        \"id\": 7,\n        \"name\": \"Standard 12x10x8\",\n        \"length\": 12,\n        \"width\": 10,\n        \"height\": 8,\n        \"dimension_unit\": \"IN\",\n        \"tare_weight\": 0.5,\n        \"weight_unit\": \"LB\",\n        \"is_active\": true\n      },\n      {\n        \"id\": 8,\n        \"name\": \"Large 18x12x10\",\n        \"length\": 18,\n        \"width\": 12,\n        \"height\": 10,\n        \"dimension_unit\": \"IN\",\n        \"tare_weight\": 0.8,\n        \"weight_unit\": \"LB\",\n        \"is_active\": true\n      }\n    ],\n    \"box_contents_submission\": null,\n    \"pallets_submission\": null,\n    \"can_confirm\": false,\n    \"confirm_blocked_reason\": \"Box contents have not been submitted yet.\",\n    \"acknowledged_at\": null\n  }\n}"}]},{"name":"Submit Box Contents (3PL Portal)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/box-contents","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","box-contents"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]},"description":"Anonymous 3PL portal submission of packed box contents. Access is granted by the opaque `:token` in the URL (the packet's `portal_token`) — no bearer auth. The submission is stored verbatim on the packet's `portal_submission.boxes` JSON.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Validation**\n- `boxes` — required array, 1..1000 boxes\n- `boxes.*.box_number` — required integer 1..100000, **distinct** across boxes\n- `boxes.*.length` / `boxes.*.width` / `boxes.*.height` — optional numeric 0..1000000 (per-box carton dimensions)\n- `boxes.*.dimension_unit` — optional string, one of `IN`, `CM`\n- `boxes.*.weight` — optional numeric 0..1000000\n- `boxes.*.weight_unit` — optional string, one of `LB`, `KG`\n- `boxes.*.amazon_fba_carton_template_id` — optional integer, must exist in `amazon_fba_carton_templates` (provenance marker set when the 3PL picks a saved carton preset; kept even after manual dimension edits)\n- `boxes.*.lines` — required array, 1..1000 lines per box\n- `boxes.*.lines.*.sku` — required string, max 255\n- `boxes.*.lines.*.quantity` — required integer 1..1000000\n\nThe dimension/weight fields are optional so a bare SKU+quantity submission still validates, but the portal offers the same full-featured box entry (carton presets + L×W×H + weight) the internal packing station uses. Returns the refreshed portal payload (same shape as `GET .../fulfillment-portal/:token`).","body":{"mode":"raw","raw":"{\n  \"boxes\": [\n    {\n      \"box_number\": 1,\n      \"amazon_fba_carton_template_id\": 7,\n      \"length\": 12,\n      \"width\": 10,\n      \"height\": 8,\n      \"dimension_unit\": \"IN\",\n      \"weight\": 15.5,\n      \"weight_unit\": \"LB\",\n      \"lines\": [\n        {\n          \"sku\": \"SKU-A\",\n          \"quantity\": 3\n        },\n        {\n          \"sku\": \"SKU-B\",\n          \"quantity\": 2\n        }\n      ]\n    },\n    {\n      \"box_number\": 2,\n      \"length\": 18,\n      \"width\": 12,\n      \"height\": 10,\n      \"dimension_unit\": \"IN\",\n      \"weight\": 22,\n      \"weight_unit\": \"LB\",\n      \"lines\": [\n        {\n          \"sku\": \"SKU-C\",\n          \"quantity\": 5\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/box-contents","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","box-contents"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Box contents submitted.\",\n  \"data\": {\n    \"reference\": \"FBA-2026-000123\",\n    \"fba_shipment_id\": \"FBA15ABCDEF\",\n    \"source_name\": \"Acme 3PL Warehouse\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"ONT8\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com\",\n      \"addressLine1\": \"24208 San Michele Rd\",\n      \"addressLine2\": null,\n      \"city\": \"Moreno Valley\",\n      \"stateOrProvinceCode\": \"CA\",\n      \"postalCode\": \"92551\",\n      \"countryCode\": \"US\"\n    },\n    \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n    \"is_ltl\": false,\n    \"requires_pallets\": false,\n    \"status\": \"in_progress\",\n    \"requested_by\": \"Jane Buyer\",\n    \"build_required\": false,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [],\n    \"instructions\": \"# FBA Inbound Preparation Instructions\\nShipment: FBA15ABCDEF\\nShip to: Amazon ONT8\\n\\nPack each SKU into the boxes exactly as listed, label every box, then confirm ready to ship.\",\n    \"documents\": [\n      {\n        \"id\": 41,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"products\": [\n      {\n        \"product_id\": 5567,\n        \"sku\": \"SKU-A\",\n        \"name\": \"Acme Widget - Blue\",\n        \"image_url\": \"https://cdn.example.com/img/sku-a.jpg\",\n        \"msku\": \"ACME-SKU-A\",\n        \"fnsku\": \"X001ABCDEF\",\n        \"quantity\": 24,\n        \"barcode\": null,\n        \"weight\": null,\n        \"weight_unit\": null,\n        \"length\": null,\n        \"width\": null,\n        \"height\": null,\n        \"dimension_unit\": null\n      },\n      {\n        \"product_id\": 5568,\n        \"sku\": \"SKU-B\",\n        \"name\": \"Acme Widget - Red\",\n        \"image_url\": null,\n        \"msku\": \"ACME-SKU-B\",\n        \"fnsku\": \"X001GHIJKL\",\n        \"quantity\": 12,\n        \"barcode\": null,\n        \"weight\": null,\n        \"weight_unit\": null,\n        \"length\": null,\n        \"width\": null,\n        \"height\": null,\n        \"dimension_unit\": null\n      }\n    ],\n    \"carton_templates\": [\n      {\n        \"id\": 7,\n        \"name\": \"Standard 12x10x8\",\n        \"length\": 12,\n        \"width\": 10,\n        \"height\": 8,\n        \"dimension_unit\": \"IN\",\n        \"tare_weight\": 0.5,\n        \"weight_unit\": \"LB\",\n        \"is_active\": true\n      },\n      {\n        \"id\": 8,\n        \"name\": \"Large 18x12x10\",\n        \"length\": 18,\n        \"width\": 12,\n        \"height\": 10,\n        \"dimension_unit\": \"IN\",\n        \"tare_weight\": 0.8,\n        \"weight_unit\": \"LB\",\n        \"is_active\": true\n      }\n    ],\n    \"box_contents_submission\": [\n      {\n        \"box_number\": 1,\n        \"amazon_fba_carton_template_id\": 7,\n        \"length\": 12,\n        \"width\": 10,\n        \"height\": 8,\n        \"dimension_unit\": \"IN\",\n        \"weight\": 15.5,\n        \"weight_unit\": \"LB\",\n        \"lines\": [\n          {\n            \"sku\": \"SKU-A\",\n            \"quantity\": 3\n          },\n          {\n            \"sku\": \"SKU-B\",\n            \"quantity\": 2\n          }\n        ]\n      },\n      {\n        \"box_number\": 2,\n        \"length\": 18,\n        \"width\": 12,\n        \"height\": 10,\n        \"dimension_unit\": \"IN\",\n        \"weight\": 22,\n        \"weight_unit\": \"LB\",\n        \"lines\": [\n          {\n            \"sku\": \"SKU-C\",\n            \"quantity\": 5\n          }\n        ]\n      }\n    ],\n    \"pallets_submission\": null,\n    \"can_confirm\": true,\n    \"confirm_blocked_reason\": null,\n    \"acknowledged_at\": null\n  }\n}"}]},{"name":"Generate FNSKU Labels (3PL Portal)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/fnsku-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","fnsku-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal_token"}]},"description":"Generate FNSKU (MSKU) item labels on demand from the anonymous 3PL/supplier portal. Token-gated — no bearer auth (`tenant.public-portal` middleware); returns 404 when the token is expired, rotated, or revoked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns Amazon's synchronous `createMarketplaceItemLabels` for the requested MSKU quantities and returns the short-lived label document `url` (open/download promptly — Amazon expires it) plus its `expiration`. The print is recorded in the label audit trail with no user (marking a portal print), a `fnsku_labels_generated` portal event is logged, and a durable copy is auto-attached to the packet's FNSKU Labels document.\n\n**Body fields:**\n- `label_type` (required): `STANDARD_FORMAT` (letter/laser sheets) or `THERMAL_PRINTING`\n- `page_type` (required): one of Amazon's createMarketplaceItemLabels page types — `Letter_30`, `A4_21`, `A4_24`, `A4_27`, `A4_44_48x25`, `A4_24_66x35`, `A4_24_64x33`, `A4_40_52x29`, `A4_24_70x36`, `A4_24_70x37`, `A4_24i`\n- `mskus` (required, min 1): array of `{msku, quantity}` — every `msku` must belong to the plan (422 otherwise), `quantity` ≥ 1","body":{"mode":"raw","raw":"{\n  \"label_type\": \"STANDARD_FORMAT\",\n  \"page_type\": \"Letter_30\",\n  \"mskus\": [\n    {\n      \"msku\": \"ACME-SKU-A\",\n      \"quantity\": 24\n    },\n    {\n      \"msku\": \"ACME-SKU-B\",\n      \"quantity\": 12\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/fnsku-labels","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","fnsku-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal_token"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://d1irx6qbteivpz.cloudfront.net/labels/item-labels-abc123.pdf\",\n    \"expiration\": \"2026-07-08T00:15:00Z\",\n    \"label_print_id\": 87\n  }\n}"}]},{"name":"Submit Pallets (3PL Portal)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/pallets","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","pallets"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]},"description":"Anonymous 3PL portal submission of LTL pallet details. Access is granted by the opaque `:token` in the URL (the packet's `portal_token`) — no bearer auth. The submission is stored verbatim on the packet's `portal_submission.pallets` JSON and is required before an LTL packet can be confirmed ready.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Validation**\n- `pallet_count` — required integer 1..1000\n- `pallets` — optional array, max 1000. A count-only submission (no `pallets`) is allowed; when `pallets` is supplied its length **must equal** `pallet_count`\n- `pallets.*.weight` — required numeric, > 0, max 5000\n- `pallets.*.height` — required numeric, > 0, max 200\n\nReturns the refreshed portal payload (same shape as `GET .../fulfillment-portal/:token`).","body":{"mode":"raw","raw":"{\n  \"pallet_count\": 2,\n  \"pallets\": [\n    {\n      \"weight\": 120.5,\n      \"height\": 48\n    },\n    {\n      \"weight\": 98,\n      \"height\": 40\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/pallets","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","pallets"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"token","value":"","description":"The token ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Pallet details submitted.\",\n  \"data\": {\n    \"reference\": \"FBA-2026-000124\",\n    \"fba_shipment_id\": \"FBA15GHIJKL\",\n    \"source_name\": \"Acme 3PL Warehouse\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"LGB8\",\n    \"shipping_mode\": \"FREIGHT_LTL\",\n    \"is_ltl\": true,\n    \"requires_pallets\": true,\n    \"status\": \"in_progress\",\n    \"requested_by\": \"Jane Buyer\",\n    \"build_required\": false,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [],\n    \"instructions\": \"Palletize the boxes, record each pallet's weight and height, then confirm ready to ship.\",\n    \"documents\": [\n      {\n        \"id\": 51,\n        \"type\": \"pallet_labels\",\n        \"type_label\": \"Pallet Labels\",\n        \"stage\": \"shipping\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"box_contents_submission\": [\n      {\n        \"box_number\": 1,\n        \"lines\": [\n          {\n            \"sku\": \"SKU-A\",\n            \"quantity\": 3\n          }\n        ]\n      }\n    ],\n    \"pallets_submission\": {\n      \"pallet_count\": 2,\n      \"pallets\": [\n        {\n          \"weight\": 120.5,\n          \"height\": 48\n        },\n        {\n          \"weight\": 98,\n          \"height\": 40\n        }\n      ]\n    },\n    \"can_confirm\": true,\n    \"confirm_blocked_reason\": null,\n    \"acknowledged_at\": null\n  }\n}"}]},{"name":"Download Portal Document (3PL Portal)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/documents/{document}/download","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","documents",":document","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"},{"key":"document","value":"","description":"Document id from the portal payload's documents[] list"}]},"description":"Downloads one of the fulfillment packet's documents from the anonymous 3PL/supplier portal. Access is granted solely by the opaque `:token` in the URL (the packet's portal token from the emailed link) — no bearer auth. `:document` is a document id from the `documents[]` array of the portal payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is a **file download**: renderable paperwork (prep instructions, box contents, kitting work order) is generated on demand and returned as a `text/plain` attachment; label documents (FNSKU/box/pallet labels), bill of lading, and other attached files are streamed from storage with their stored content type (typically `application/pdf`).\n\nEvery download is audit-logged as a portal event. Errors are plain-text: 404 when the token is expired, rotated, or revoked, or when the document does not belong to this packet; 422 when the document is not yet downloadable or its file has not been attached yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/documents/{document}/download","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","documents",":document","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"},{"key":"document","value":"","description":"Document id from the portal payload's documents[] list"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"KITTING WORK ORDER — FBA15ABCDEF\nKit: ACME-KIT-1 (Acme Widget Kit 2-pack) x 12\n  - SKU-A Acme Widget - Blue x 24\nBuild all kits, then confirm via the portal."}]},{"name":"Acknowledge Fulfillment Order (3PL Portal)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/acknowledge","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"}]},"description":"Confirms, from the anonymous 3PL/supplier portal, that the fulfillment order is packed and ready to ship. Access is granted solely by the opaque `:token` in the URL (the packet's portal token from the emailed link) — no bearer auth. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nGating: box contents must have been submitted first, and pallet details as well when the shipment moves LTL/freight — otherwise a 422 with error key `not_ready_to_confirm` explains what is missing (the same gating is exposed as `can_confirm` / `confirm_blocked_reason` on the portal payload).\n\nSide effects on success: any component-sourced kits not yet explicitly confirmed built are realized (idempotent backstop — confirming ready-to-ship implies the kits were built), the packet status moves to `acknowledged` with an `acknowledged_at` timestamp, and the confirmation is audit-logged as a portal event. Returns the refreshed portal payload.\n\nReturns 404 when the token is expired, rotated, or revoked."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/acknowledge","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Thank you — the shipment has been confirmed as ready.\",\n  \"data\": {\n    \"reference\": \"FBA-2026-000123\",\n    \"fba_shipment_id\": \"FBA15ABCDEF\",\n    \"source_name\": \"Acme 3PL Warehouse\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"ONT8\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com\",\n      \"addressLine1\": \"24208 San Michele Rd\",\n      \"addressLine2\": null,\n      \"city\": \"Moreno Valley\",\n      \"stateOrProvinceCode\": \"CA\",\n      \"postalCode\": \"92551\",\n      \"countryCode\": \"US\"\n    },\n    \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n    \"is_ltl\": false,\n    \"requires_pallets\": false,\n    \"status\": \"acknowledged\",\n    \"requested_by\": \"Jane Buyer\",\n    \"build_required\": false,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [],\n    \"instructions\": \"# FBA Inbound Preparation Instructions\\nShipment: FBA15ABCDEF\\nShip to: Amazon ONT8\\n\\nPack each SKU into the boxes exactly as listed, label every box, then confirm ready to ship.\",\n    \"prep_details\": null,\n    \"documents\": [\n      {\n        \"id\": 41,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 44,\n        \"type\": \"box_labels\",\n        \"type_label\": \"Box Labels\",\n        \"stage\": \"mid\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"products\": [\n      {\n        \"product_id\": 5567,\n        \"sku\": \"SKU-A\",\n        \"name\": \"Acme Widget - Blue\",\n        \"image_url\": \"https://cdn.example.com/img/sku-a.jpg\",\n        \"msku\": \"ACME-SKU-A\",\n        \"fnsku\": \"X001ABCDEF\",\n        \"barcode\": \"812345678901\",\n        \"quantity\": 24,\n        \"label_owner\": \"SELLER\",\n        \"prep_owner\": \"SELLER\",\n        \"weight\": 1.4,\n        \"weight_unit\": \"lb\",\n        \"length\": 7.3,\n        \"width\": 4.9,\n        \"height\": 2.8,\n        \"dimension_unit\": \"in\"\n      }\n    ],\n    \"carton_templates\": [],\n    \"box_contents_submission\": [\n      {\n        \"box_number\": 1,\n        \"lines\": [\n          {\n            \"sku\": \"SKU-A\",\n            \"quantity\": 24\n          }\n        ]\n      }\n    ],\n    \"pallets_submission\": null,\n    \"can_confirm\": true,\n    \"confirm_blocked_reason\": null,\n    \"acknowledged_at\": \"2026-07-07T16:20:00+00:00\"\n  }\n}"}]},{"name":"Confirm Kits Built (3PL Portal)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/kits-built","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","kits-built"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"}]},"description":"Confirms, from the anonymous 3PL/supplier portal, that the kits on the fulfillment order have been physically assembled. Access is granted solely by the opaque `:token` in the URL (the packet's portal token from the emailed link) — no bearer auth. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSide effects: the reserved kit components are converted into finished kit stock and the kits are allocated to their transfer lines; the confirmation is audit-logged as a portal event. The operation is idempotent — lines already built are skipped, and calling it when there is nothing to build is a safe no-op.\n\nReturns the refreshed portal payload (`kits_pending_build` becomes false; `kit_build_manifest` still lists what was built). Returns 404 when the token is expired, rotated, or revoked."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/fulfillment-portal/{token}/kits-built","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","fulfillment-portal",":token","kits-built"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"token","value":"","description":"The packet's opaque portal access token from the emailed fulfillment link"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Thank you — the kits have been marked as built.\",\n  \"data\": {\n    \"reference\": \"FBA-2026-000125\",\n    \"fba_shipment_id\": \"FBA15KITSXY\",\n    \"source_name\": \"Acme 3PL Warehouse\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"ONT8\",\n    \"destination_address\": {\n      \"name\": \"Amazon.com\",\n      \"addressLine1\": \"24208 San Michele Rd\",\n      \"addressLine2\": null,\n      \"city\": \"Moreno Valley\",\n      \"stateOrProvinceCode\": \"CA\",\n      \"postalCode\": \"92551\",\n      \"countryCode\": \"US\"\n    },\n    \"shipping_mode\": \"GROUND_SMALL_PARCEL\",\n    \"is_ltl\": false,\n    \"requires_pallets\": false,\n    \"status\": \"in_progress\",\n    \"requested_by\": \"Jane Buyer\",\n    \"build_required\": true,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [\n      {\n        \"kit_sku\": \"ACME-KIT-1\",\n        \"kit_name\": \"Acme Widget Kit (2-pack)\",\n        \"quantity\": 12,\n        \"components\": [\n          {\n            \"sku\": \"SKU-A\",\n            \"name\": \"Acme Widget - Blue\",\n            \"quantity_per_kit\": 2,\n            \"total_quantity\": 24\n          }\n        ]\n      }\n    ],\n    \"instructions\": \"# FBA Inbound Preparation Instructions\\nShipment: FBA15ABCDEF\\nShip to: Amazon ONT8\\n\\nPack each SKU into the boxes exactly as listed, label every box, then confirm ready to ship.\",\n    \"prep_details\": null,\n    \"documents\": [\n      {\n        \"id\": 41,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 44,\n        \"type\": \"box_labels\",\n        \"type_label\": \"Box Labels\",\n        \"stage\": \"mid\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"products\": [\n      {\n        \"product_id\": 5567,\n        \"sku\": \"SKU-A\",\n        \"name\": \"Acme Widget - Blue\",\n        \"image_url\": \"https://cdn.example.com/img/sku-a.jpg\",\n        \"msku\": \"ACME-SKU-A\",\n        \"fnsku\": \"X001ABCDEF\",\n        \"barcode\": \"812345678901\",\n        \"quantity\": 24,\n        \"label_owner\": \"SELLER\",\n        \"prep_owner\": \"SELLER\",\n        \"weight\": 1.4,\n        \"weight_unit\": \"lb\",\n        \"length\": 7.3,\n        \"width\": 4.9,\n        \"height\": 2.8,\n        \"dimension_unit\": \"in\"\n      }\n    ],\n    \"carton_templates\": [],\n    \"box_contents_submission\": null,\n    \"pallets_submission\": null,\n    \"can_confirm\": false,\n    \"confirm_blocked_reason\": \"Submit your box contents before confirming the shipment is ready.\",\n    \"acknowledged_at\": null\n  }\n}"}]},{"name":"List Prep Details","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/list-prep-details","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","list-prep-details"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance id."},{"key":"draft_inbound_plan","value":"1","description":"Draft inbound plan id."}]},"description":"Fetch Amazon's prep requirements (prep category + prep types) for every MSKU on a draft inbound plan. SKU.io sends all of the plan's MSKUs to Amazon's listPrepDetails operation and returns the per-MSKU results. Backs the plan configuration step's \"Fetch Amazon Prep Requirements\" action.\n\nResilient to invalid MSKUs: Amazon 400-rejects the whole batch if any single MSKU is not recognised for the seller account. When that happens, SKU.io parses the rejected MSKUs, drops them, and retries with the remaining valid SKUs — so one bad SKU no longer dead-ends the whole step. The rejected SKUs are returned in the top-level `invalid_mskus` array (excluded from `data`) so the UI can prompt the user to remove or remap them.\n\nA 400 that is NOT an invalid-MSKU error (or that names SKUs we did not send) surfaces as a 422 ValidationException.\n\nAuthentication: requires Bearer token.\n\nNo request body — the MSKU list is derived from the plan's line items.\n\nResponse: `data` is an array of prep detail items (msku, prepCategory, prepTypes[], labelOwnerConstraint, prepOwnerConstraint, allOwnersConstraint); `invalid_mskus` is an array of the MSKU strings Amazon rejected as \"not valid\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/list-prep-details","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","list-prep-details"],"variable":[{"key":"integrationInstance","value":"2","description":"Amazon integration instance id."},{"key":"draft_inbound_plan","value":"1","description":"Draft inbound plan id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"msku\": \"WIDGET-BLUE-01\",\n      \"prepCategory\": \"NONE\",\n      \"prepTypes\": [],\n      \"labelOwnerConstraint\": \"SELLER\",\n      \"prepOwnerConstraint\": \"SELLER\",\n      \"allOwnersConstraint\": null\n    },\n    {\n      \"msku\": \"GLASS-JAR-8OZ\",\n      \"prepCategory\": \"FRAGILE\",\n      \"prepTypes\": [\n        \"ITEM_BUBBLEWRAP\"\n      ],\n      \"labelOwnerConstraint\": \"SELLER\",\n      \"prepOwnerConstraint\": \"SELLER\",\n      \"allOwnersConstraint\": null\n    }\n  ],\n  \"invalid_mskus\": [\n    \"100830-M\",\n    \"100831-M\"\n  ]\n}"}]},{"name":"Get Draft Plan Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Paginated activity log for a draft FBA inbound plan, rolling up activity recorded on the plan itself and on each of its line items into a single stream ordered newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach entry contains `id`, `description`, `event` (e.g. `created`, `updated`, `deleted`), `subject_type` (short type name of the record the event was recorded on — the plan or one of its line items), `subject_id`, `properties` (the recorded attribute changes, typically `{attributes: {...}, old: {...}}`), `causer_name` (the acting user, null for system events), and `created_at` (UTC datetime).\n\nQuery parameters: `page` (default 1), `per_page` (default 15), and `filter[search]` — a free-text search matched against the acting user's name, the event, the serialized property changes, and the subject type. Standard pagination metadata (`current_page`, `last_page`, `per_page`, `total`, `links`, ...) is included in the response."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9182,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"DraftAmazonFbaInboundPlanItem\",\n      \"subject_id\": 4411,\n      \"properties\": {\n        \"attributes\": {\n          \"quantity\": 24\n        },\n        \"old\": {\n          \"quantity\": 12\n        }\n      },\n      \"causer_name\": \"Jane Buyer\",\n      \"created_at\": \"2026-07-01T18:42:11.000000Z\"\n    },\n    {\n      \"id\": 9169,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"DraftAmazonFbaInboundPlan\",\n      \"subject_id\": 512,\n      \"properties\": {\n        \"attributes\": {\n          \"name\": \"FBA-2026-000123\",\n          \"status\": \"draft\"\n        }\n      },\n      \"causer_name\": \"Jane Buyer\",\n      \"created_at\": \"2026-06-30T15:03:27.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=3\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/1/draft-inbound-plans/512/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 34\n}"}]},{"name":"Download Inventory Inquiry PDF","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/download-inventory-inquiry-pdf","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","download-inventory-inquiry-pdf"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Generates and downloads the inventory inquiry PDF for the draft inbound plan. The document lists every plan item (with product image, SKU, MSKU and requested quantity), the source warehouse/supplier details, and embeds a QR code linking to the shareable verification portal so the supplier can verify quantities on their phone.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response is a binary `application/pdf` attachment (`Content-Disposition: attachment`) named `inventory-inquiry-<plan-name-slug>.pdf`. No request body or query parameters."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/download-inventory-inquiry-pdf","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","download-inventory-inquiry-pdf"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.7\n% Binary PDF content — inventory-inquiry-fba-2026-000123.pdf (truncated example)"}]},{"name":"Get Portal Access Hash","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/portal-access-hash","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","portal-access-hash"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Returns the encrypted plan identifier (`hashed_id`) used to build the shareable, unauthenticated verification portal URL for this draft inbound plan. The portal lets a supplier verify item quantities without logging in.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe hash is an encrypted payload of the plan id; append it to the verification portal path (`/v2/integrations/amazon/fba/draft-inbound-plans/verification-portal/{hashed_id}?integration={integrationInstance}`) and share the resulting link. The same hash is embedded in the inventory inquiry email and the QR code on the inventory inquiry PDF. No request body or query parameters."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/portal-access-hash","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","portal-access-hash"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"hashed_id\": \"eyJpdiI6IlR2bXhOc2JQZk9rZz09IiwidmFsdWUiOiJkR0Z6ZEdWeVpYTjBaWEp1YldWaGJHbHVaUT09IiwibWFjIjoiOWY0YjFjMGEzZTc3NGIxZThhM2Q2YTJiMWM5ZDBlNWYiLCJ0YWciOiIifQ==\"\n  }\n}"}]},{"name":"Send Inventory Inquiry","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/send-inventory-inquiry","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","send-inventory-inquiry"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Sends the inventory inquiry email for the draft inbound plan. **Note: although this is a GET request, it has a side effect — calling it sends an email** and updates the plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe email goes to the plan's source: for a supplier warehouse, the supplier's purchase-order email (falling back to the supplier's main email); otherwise the source warehouse address email. It contains the plan's item list and a link to the unauthenticated verification portal where the recipient confirms available quantities.\n\nSide effects on success: the plan's inventory-inquiry sent timestamp is stamped, the sending user is recorded, and the plan status moves to `verification_in_progress`.\n\nErrors: when no recipient email is on file for the source, the response carries an `inventory_inquiry_missing_email` error instead of sending."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/send-inventory-inquiry","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","send-inventory-inquiry"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory inquiry email sent successfully.\"\n}"}]},{"name":"Set Prep Details","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/set-prep-details","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","set-prep-details"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Sets Amazon SP-API prep details (prep category + prep types) for MSKUs on the draft inbound plan whose prep category is unknown. The request is forwarded to Amazon's `setPrepDetails` operation for the plan's marketplace (derived from the destination warehouse's country); Amazon's raw response (an `operationId` you can use to correlate the asynchronous SP-API operation) is returned under `data`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `mskuPrepDetails` (array, required) — one entry per MSKU\n- `mskuPrepDetails[].msku` (string, required) — the Amazon seller SKU\n- `mskuPrepDetails[].prepCategory` (string, required) — one of `ADULT`, `BABY`, `FC_PROVIDED`, `FRAGILE`, `GRANULAR`, `HANGER`, `LIQUID`, `NONE`, `PERFORATED`, `SET`, `SHARP`, `SMALL`, `TEXTILE`\n- `mskuPrepDetails[].prepTypes` (array of strings, required) — SP-API prep types (e.g. `ITEM_POLYBAGGING`, `ITEM_BUBBLEWRAP`, `ITEM_LABELING`, `ITEM_NO_PREP`)\n\nBusiness rule: when `prepCategory` is `NONE`, `prepTypes` must include `ITEM_NO_PREP` (422 otherwise). A 422 is also returned when Amazon rejects the request.","body":{"mode":"raw","raw":"{\n  \"mskuPrepDetails\": [\n    {\n      \"msku\": \"ACME-WIDGET-BLUE-FBA\",\n      \"prepCategory\": \"FRAGILE\",\n      \"prepTypes\": [\n        \"ITEM_BUBBLEWRAP\",\n        \"ITEM_LABELING\"\n      ]\n    },\n    {\n      \"msku\": \"ACME-WIDGET-RED-FBA\",\n      \"prepCategory\": \"NONE\",\n      \"prepTypes\": [\n        \"ITEM_NO_PREP\"\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/set-prep-details","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","set-prep-details"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"operationId\": \"1f4c3a9e-8f21-4a2c-b0d3-7e5a9c1b2d43\"\n  },\n  \"message\": \"Prep details set successfully.\"\n}"}]},{"name":"Verify All Products (Internal)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/verify-all-products-internal","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","verify-all-products-internal"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]},"description":"Marks every item on the draft inbound plan as verified at its full planned quantity, without going through the supplier verification portal. Use this when the operator already knows the source quantities are correct and wants to skip the emailed inventory inquiry round-trip.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is the authenticated counterpart of the portal's verify-all action: each plan item's verified quantity is set to its planned quantity. No request body or query parameters."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/{draft_inbound_plan}/verify-all-products-internal","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans",":draft_inbound_plan","verify-all-products-internal"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"draft_inbound_plan","value":"","description":"Draft inbound plan id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All products successfully verified\"\n}"}]},{"name":"Search Inbound Products by Country","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound-products/{countryCode}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound-products",":countryCode"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"countryCode","value":"US","description":"Marketplace country code (e.g. US, CA, MX, GB, DE, AU)"}]},"description":"Searches products eligible for FBA inbound shipping on this integration instance, scoped to one marketplace country. Backed by the mapped Amazon listings joined with current FBA inventory, so each row carries the Amazon identifiers plus live FBA quantity buckets.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath parameter `countryCode` is the marketplace country code (e.g. `US`, `CA`). Query parameter `query` (optional) does a partial match against product SKU, MSKU, ASIN, FNSKU, or product name; omit it to list all inbound-eligible products for the country.\n\nEach result includes identifiers (`msku`, `asin`, `fnsku`, `product_id`, `product_sku`, `product_name`, `product_image`, `country_code`), FBA quantity buckets (`warehouse_quantity`, `fulfillable_quantity`, `unsellable_quantity`, `reserved_quantity`, `inbound_quantity`, `inbound_working_quantity`, `inbound_shipped_quantity`, `inbound_receiving_quantity`), inbound ownership defaults (`label_owner`, `prep_owner` — `AMAZON` | `SELLER` | `NONE`), case-pack settings (`case_pack_qty`, `case_pack_rounding`), and unit measurements with derived metrics (`weight`, `weight_unit`, `weight_estimated`, `length`, `width`, `height`, `dimension_unit`, `dims_estimated`, `unit_weight_lb`, `unit_volume_cuft`, `unit_cost`, `size_tier`). `source_quantity` is null here — it is only populated by the plan-scoped product search, which computes availability at the plan's source warehouse. Returns the full (non-paginated) matching list.\n\nEach product includes an eligibility object { shippable: bool, reason: string|null } — false with a reason when the SKU can't be inbounded (no FNSKU, removed from Amazon, or an inactive listing)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/inbound-products/{countryCode}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","inbound-products",":countryCode"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"},{"key":"countryCode","value":"US","description":"Marketplace country code (e.g. US, CA, MX, GB, DE, AU)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"msku\": \"ACME-WIDGET-BLUE-FBA\",\n      \"asin\": \"B0EXAMPLE1\",\n      \"fnsku\": \"X002ABCDE1\",\n      \"product_id\": 1979,\n      \"product_sku\": \"80707522\",\n      \"product_name\": \"Acme Widget - Blue\",\n      \"product_image\": \"https://cdn.example.com/img/80707522.jpg\",\n      \"country_code\": \"US\",\n      \"warehouse_quantity\": 71,\n      \"fulfillable_quantity\": 65,\n      \"unsellable_quantity\": 0,\n      \"reserved_quantity\": 6,\n      \"inbound_quantity\": 12,\n      \"inbound_working_quantity\": 12,\n      \"inbound_shipped_quantity\": 0,\n      \"inbound_receiving_quantity\": 0,\n      \"label_owner\": \"SELLER\",\n      \"prep_owner\": \"SELLER\",\n      \"source_quantity\": null,\n      \"case_pack_qty\": 12,\n      \"case_pack_rounding\": \"always_round_down\",\n      \"weight\": 1.4,\n      \"weight_unit\": \"lb\",\n      \"weight_estimated\": false,\n      \"length\": 7.3,\n      \"width\": 4.9,\n      \"height\": 2.8,\n      \"dimension_unit\": \"in\",\n      \"dims_estimated\": false,\n      \"unit_weight_lb\": 1.4,\n      \"unit_volume_cuft\": 0.0579,\n      \"unit_cost\": 6.85,\n      \"size_tier\": \"standard\"\n    }\n  ]\n}"}]},{"name":"Refresh Inbound Plans","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"}]},"description":"Refreshes the integration's FBA inbound plans from Amazon. The request synchronously pulls inbound plan summaries from the SP-API — first plans in `SHIPPED` status, then `ACTIVE` (some active plans already have shipments) — and upserts them, along with the ship-from address mappings found on those plans.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIt then queues background jobs that download each plan's full details, line items, and shipments, so plan data keeps loading after the response returns; there is no job id to poll — re-query the inbound plan list to see updated data. No request body or query parameters.\n\nBecause the summary fetch calls Amazon synchronously, the response can take several seconds on accounts with many plans."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-inbound/plans/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-inbound","plans","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound plans downloading...\"\n}"}]},{"name":"Add Item to Draft Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan}/add-item","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan","add-item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Add an item to a draft FBA inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Fields:**\n- `product_id` (integer, required) — SKU product id\n- `msku` (string, required) — Amazon merchant SKU\n- `quantity` (integer, required) — units to send\n- `kit_fulfillment_mode` (string, optional) — for kit products only: `kit_stock` (ship pre-built kit stock) or `components` (the source assembles the kit from component stock; components are allocated at verify and convert to the kit when the source confirms the build).\n- `case_pack_qty` (integer, optional, nullable) — case pack size to snapshot onto this line. Defaults to the product's current case pack size when omitted.\n- `case_pack_rounding` (string, optional, nullable) — rounding strategy snapshot for this line: `always_round_up`, `always_round_down`, or `round_nearest`. Defaults to the product's current case pack rounding setting when omitted.\n\n**Smart default:** when `kit_fulfillment_mode` is omitted and the product is a kit sourced from a non-supplier warehouse, the mode defaults to `components` if pre-built kit stock cannot cover the quantity but component stock can assemble it. Pass the field explicitly to override.\n\nThe response includes `is_kit`, `kit_fulfillment_mode`, `kit_availability` (kit stock on hand, max buildable from components, bottleneck component), and the snapshotted `case_pack_qty` / `case_pack_rounding`.","body":{"mode":"raw","raw":"{\n  \"product_id\": 42,\n  \"msku\": \"GSL392-KIT\",\n  \"quantity\": 30,\n  \"kit_fulfillment_mode\": \"components\",\n  \"case_pack_qty\": 12,\n  \"case_pack_rounding\": \"always_round_up\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan}/add-item","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan","add-item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"product_id\": 42,\n    \"quantity\": 100,\n    \"case_pack_qty\": 12,\n    \"case_pack_rounding\": \"always_round_up\"\n  }\n}"}]},{"name":"Bulk Add Items to Draft Plan","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan}/bulk-add","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan","bulk-add"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]},"description":"Bulk add items to a draft FBA inbound plan. Items already on the plan (matched by MSKU) are skipped unless `replace_existing` is true, in which case their quantity is updated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach item accepts the same fields as **Add Item to Draft Plan** (`product_id`, `msku`, `quantity`, `kit_fulfillment_mode`, `case_pack_qty`, `case_pack_rounding`) — `case_pack_qty`/`case_pack_rounding` are optional per-item overrides; when omitted they default to the product's current case pack settings.\n\n**Kit smart default:** each added kit product sourced from a non-supplier warehouse defaults `kit_fulfillment_mode` to `components` when pre-built kit stock cannot cover the requested quantity but component stock can assemble it (the source builds the kits; components are allocated at verify). Other lines default to shipping stock as-is.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"product_id\": 42,\n      \"quantity\": 100,\n      \"case_pack_qty\": 12,\n      \"case_pack_rounding\": \"always_round_up\"\n    },\n    {\n      \"product_id\": 43,\n      \"quantity\": 50\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan}/bulk-add","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan","bulk-add"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan","value":"1","description":"The draft inbound plan ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 items added\",\n  \"data\": [\n    {\n      \"id\": 5,\n      \"product_id\": 42,\n      \"case_pack_qty\": 12,\n      \"case_pack_rounding\": \"always_round_up\"\n    },\n    {\n      \"id\": 6,\n      \"product_id\": 43,\n      \"case_pack_qty\": null,\n      \"case_pack_rounding\": null\n    }\n  ]\n}"}]},{"name":"Update Item","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan_item}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan_item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan_item","value":"5","description":"The draft inbound plan item ID."}]},"description":"Update a single draft plan item.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuth: Requires Bearer token.\n\nBody fields (all optional — only provided fields are updated):\n- product_id (int)\n- msku (string)\n- quantity (int)\n- label_owner (string|null)\n- prep_owner (string|null)\n- expiration (date|null)\n- manufacturing_lot_code (string|null)\n- kit_fulfillment_mode (string|null): how a KIT line is fulfilled from the source warehouse — `kit_stock` (ship existing pre-built kit stock as-is) or `components` (assemble the kit from component stock at the source warehouse when the plan is verified/allocated). Only meaningful for kit products with a non-supplier (3PL/direct) source; ignored otherwise.\n- case_pack_qty (int|null): case pack size snapshot for this line.\n- case_pack_rounding (string|null): rounding strategy snapshot for this line — `always_round_up`, `always_round_down`, or `round_nearest`.\n\nReturns the updated item, including `product_id`, `is_kit`, `kit_fulfillment_mode`, `kit_availability` (live kit-on-hand vs buildable-from-components, with the bottleneck component), and `case_pack_qty` / `case_pack_rounding` for kit lines.","body":{"mode":"raw","raw":"{\n  \"quantity\": 150,\n  \"kit_fulfillment_mode\": \"components\",\n  \"case_pack_qty\": 12,\n  \"case_pack_rounding\": \"always_round_up\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan_item}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan_item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan_item","value":"5","description":"The draft inbound plan item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"product_id\": 42,\n    \"is_kit\": true,\n    \"kit_fulfillment_mode\": \"components\",\n    \"kit_availability\": {\n      \"is_kit\": true,\n      \"kit_on_hand\": 0,\n      \"buildable_from_components\": 12,\n      \"bottleneck_component\": {\n        \"product_id\": 88,\n        \"sku\": \"COMP-A\",\n        \"name\": \"Component A\",\n        \"available\": 24,\n        \"required_per_kit\": 2,\n        \"buildable\": 12\n      },\n      \"components\": [\n        {\n          \"product_id\": 88,\n          \"sku\": \"COMP-A\",\n          \"name\": \"Component A\",\n          \"available\": 24,\n          \"required_per_kit\": 2,\n          \"buildable\": 12\n        },\n        {\n          \"product_id\": 89,\n          \"sku\": \"COMP-B\",\n          \"name\": \"Component B\",\n          \"available\": 60,\n          \"required_per_kit\": 1,\n          \"buildable\": 60\n        }\n      ]\n    },\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"KIT-001\",\n      \"name\": \"Starter Kit\",\n      \"image_url\": null\n    },\n    \"amazon_product_id\": 17,\n    \"quantity\": 150,\n    \"msku\": \"KIT-001-FBA\",\n    \"fnsku\": \"X00ABCDEF\",\n    \"label_owner\": \"SELLER\",\n    \"prep_owner\": \"SELLER\",\n    \"expiration\": null,\n    \"manufacturing_lot_code\": null,\n    \"created_at\": \"2026-06-18T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-21T12:05:00.000000Z\",\n    \"verified_quantity\": null,\n    \"source_quantity\": \"120\",\n    \"warehouse_quantity\": 120,\n    \"fulfillable_quantity\": 100,\n    \"unsellable_quantity\": 0,\n    \"reserved_quantity\": 5,\n    \"inbound_quantity\": 30,\n    \"inbound_working_quantity\": 10,\n    \"inbound_shipped_quantity\": 15,\n    \"inbound_receiving_quantity\": 5,\n    \"case_pack_qty\": 12,\n    \"case_pack_rounding\": \"always_round_up\"\n  }\n}"}]},{"name":"Remove Item from Draft Plan","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan_item}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan_item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan_item","value":"5","description":"The draft inbound plan item ID."}]},"description":"Remove an item from a draft FBA inbound plan.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/{draft_inbound_plan_item}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items",":draft_inbound_plan_item"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"draft_inbound_plan_item","value":"5","description":"The draft inbound plan item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Item removed\"\n}"}]},{"name":"Bulk Update Items","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk update draft plan items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"id\": 5,\n      \"quantity\": 150\n    },\n    {\n      \"id\": 6,\n      \"quantity\": 75\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/draft-inbound-plans/items/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","draft-inbound-plans","items","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 items updated\"\n}"}]},{"name":"Show Initial Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]},"description":"Get a specific initial inventory record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"fnsku\": \"X001ABC123\",\n    \"quantity\": 500,\n    \"unit_cost\": 12.5\n  }\n}"}]},{"name":"Reconcile Initial Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]},"description":"Reconcile a specific initial inventory record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventory reconciled\"\n}"}]},{"name":"Unreconcile Initial Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]},"description":"Unreconcile a specific initial inventory record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/{initialInventory}/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory",":initialInventory","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"initialInventory","value":"1","description":"The initial inventory ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventory unreconciled\"\n}"}]},{"name":"Reconcile All Initial Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reconcile all initial inventory records.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All initial inventory reconciled\"\n}"}]},{"name":"Reconcile Initial Inventories (Batch)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reconcile specific initial inventory records.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventories reconciled\"\n}"}]},{"name":"Unreconcile All Initial Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unreconcile all initial inventory records.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All initial inventory unreconciled\"\n}"}]},{"name":"Reconcile Initial Inventories for FNSKUs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile-for-fnskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile-for-fnskus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reconcile initial inventories for specific FNSKU products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/reconcile-for-fnskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","reconcile-for-fnskus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventories reconciled for FNSKUs\"\n}"}]},{"name":"Unreconcile Initial Inventories (Batch)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unreconcile specific initial inventory records.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Initial inventories unreconciled\"\n}"}]},{"name":"List Initial Inventory (Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/initial-inventory","host":["{{baseUrl}}"],"path":["api","amazon","unified","initial-inventory"]},"description":"Returns paginated FBA initial inventory rows across all Amazon integration instances. Initial inventory is the FBA warehouse balance snapshot captured at the account's inventory tracking start date, used to seed FIFO cost layers and reconcile early ledger activity.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis route accepts both GET and POST with identical behavior - send the same parameters as a JSON body via POST when the filter payload is too long for a query string (e.g. a large `filter_groups` tree). Only this GET request is documented; do not treat POST as a separate operation.\n\nQuery parameters:\n- `page` (default 1), `per_page` (default 10).\n- `sort` - allowed fields: `id`, `fnsku`, `asin`, `msku`, `disposition`, `ending_warehouse_balance`, `location`, `created_at` (prefix `-` for descending).\n- `filter[integration_instance_ids]` - comma-separated instance IDs.\n- `filter[search]` - matches fnsku, asin, msku, title, or integration instance name.\n- Operator filters using `filter[column.operator]=value` syntax:\n  - Text columns `fnsku`, `asin`, `msku`, `title`, `disposition`, `location`, `integration_instance_name`: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\n  - Numeric columns `id`, `ending_warehouse_balance`: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\n  - Date column `created_at`: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year.\n  - A bare `filter[column]=value` acts as an implicit `is`.\n- `filter_groups` - base64-encoded JSON tree (`{\"conjunction\": \"and\", \"children\": [...]}`) for nested and/or filter groups; via POST it may be sent as a plain JSON object.\n\nEach row includes the linked FNSKU product and its SKU.io product (when mapped), the initial unit cost, reconciliation state, and the FIFO layer ID created from the row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/initial-inventory","host":["{{baseUrl}}"],"path":["api","amazon","unified","initial-inventory"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 101,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"fnsku\": \"X002QK7F5T\",\n      \"asin\": \"B08XYZL4M2\",\n      \"msku\": \"WIDGET-BLK-12\",\n      \"title\": \"Widget Pro 12-Pack, Black\",\n      \"location\": \"ONT8\",\n      \"disposition\": \"SELLABLE\",\n      \"ending_warehouse_balance\": 148,\n      \"fnsku_product\": {\n        \"id\": 55,\n        \"initial_unit_cost\": 4.25,\n        \"reconciled_quantity\": 148,\n        \"product\": {\n          \"id\": 918,\n          \"sku\": \"WIDGET-BLK-12\",\n          \"name\": \"Widget Pro 12-Pack, Black\"\n        }\n      },\n      \"is_reconciled\": true,\n      \"amazon_fifo_layer_id\": 7742,\n      \"created_at\": \"2026-04-18T09:12:44.000000Z\"\n    },\n    {\n      \"id\": 102,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"fnsku\": \"X001ZR8V2K\",\n      \"asin\": \"B07QRS9T1P\",\n      \"msku\": \"GADGET-RED-01\",\n      \"title\": \"Gadget Mini, Red\",\n      \"location\": \"TEB4\",\n      \"disposition\": \"UNSELLABLE\",\n      \"ending_warehouse_balance\": 6,\n      \"fnsku_product\": null,\n      \"is_reconciled\": null,\n      \"amazon_fifo_layer_id\": null,\n      \"created_at\": \"2026-04-18T09:12:44.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 9,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=9\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/unified/initial-inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 84\n}"}]},{"name":"Unreconcile Initial Inventories for FNSKUs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile-for-fnskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile-for-fnskus"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Unreconcile the FBA initial inventory records linked to the given FNSKU products. Runs synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (array of integers, required) — FNSKU product IDs; each must exist.\n\nFor every initial inventory row belonging to one of the FNSKU products that currently has an initial-inventory FIFO layer, the reconciliation is reversed in a transaction: the record's initialization timestamp and FIFO layer link are cleared, the FIFO layer created during reconciliation is deleted, and the FNSKU product's reconciled quantity is reset to 0. Rows without a FIFO layer are skipped. The request fails when a targeted FNSKU product still has reconciled ledger entries — unreconcile those ledgers first.\n\nReturns the updated initial inventory records (with amazon_fifo_layer_id and sku_product_initialized_at cleared). Returns 422 when an ID does not exist.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    412,\n    431\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/initial-inventory/unreconcile-for-fnskus","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","initial-inventory","unreconcile-for-fnskus"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7719,\n      \"fnskuProduct\": {\n        \"id\": 412,\n        \"reconciled_quantity\": 0\n      },\n      \"checksum\": \"9c2e6f5a1b7d4c3e8f90a1b2c3d4e5f6\",\n      \"integration_instance_id\": 1,\n      \"amazon_report_id\": 388,\n      \"amazon_product_id\": 1502,\n      \"fifo_layer_id\": null,\n      \"amazon_fifo_layer_id\": null,\n      \"sku_product_initialized_at\": null,\n      \"date\": \"2026-01-31T00:00:00.000000Z\",\n      \"fnsku\": \"X002ABCDE1\",\n      \"asin\": \"B08K4F9TXQ\",\n      \"msku\": \"LS-RAZOR-BLK\",\n      \"title\": \"Leaf Razor, Black\",\n      \"disposition\": \"SELLABLE\",\n      \"starting_warehouse_balance\": 120,\n      \"in_transit_between_warehouses\": 6,\n      \"receipts\": 0,\n      \"customer_shipments\": -14,\n      \"customer_returns\": 1,\n      \"vendor_returns\": 0,\n      \"warehouse_transfer_in_out\": -6,\n      \"found\": 0,\n      \"lost\": -1,\n      \"damaged\": 0,\n      \"disposed\": 0,\n      \"other_events\": 0,\n      \"adjustments\": -1,\n      \"ending_warehouse_balance\": 100,\n      \"total_inventory_quantity\": 106,\n      \"unknown_events\": 0,\n      \"location\": \"US\",\n      \"json_object\": {\n        \"date\": \"1/31/2026\",\n        \"fnsku\": \"X002ABCDE1\",\n        \"asin\": \"B08K4F9TXQ\",\n        \"msku\": \"LS-RAZOR-BLK\",\n        \"title\": \"Leaf Razor, Black\",\n        \"disposition\": \"SELLABLE\",\n        \"starting_warehouse_balance\": \"120\",\n        \"ending_warehouse_balance\": \"100\",\n        \"location\": \"US\"\n      },\n      \"created_at\": \"2026-02-01T04:10:22.000000Z\",\n      \"updated_at\": \"2026-07-06T18:31:07.000000Z\"\n    },\n    {\n      \"id\": 7742,\n      \"fnskuProduct\": {\n        \"id\": 431,\n        \"reconciled_quantity\": 0\n      },\n      \"checksum\": \"1f83ac7d9e2b4a5c6d7e8f9012a3b4c5\",\n      \"integration_instance_id\": 1,\n      \"amazon_report_id\": 388,\n      \"amazon_product_id\": 1518,\n      \"fifo_layer_id\": null,\n      \"amazon_fifo_layer_id\": null,\n      \"sku_product_initialized_at\": null,\n      \"date\": \"2026-01-31T00:00:00.000000Z\",\n      \"fnsku\": \"X003QWERT7\",\n      \"asin\": \"B09PLMN3RZ\",\n      \"msku\": \"LS-SOAP-3PK\",\n      \"title\": \"Shave Soap Refill 3-Pack\",\n      \"disposition\": \"SELLABLE\",\n      \"starting_warehouse_balance\": 40,\n      \"in_transit_between_warehouses\": 0,\n      \"receipts\": 12,\n      \"customer_shipments\": -9,\n      \"customer_returns\": 0,\n      \"vendor_returns\": 0,\n      \"warehouse_transfer_in_out\": 0,\n      \"found\": 0,\n      \"lost\": 0,\n      \"damaged\": 0,\n      \"disposed\": 0,\n      \"other_events\": 0,\n      \"adjustments\": 0,\n      \"ending_warehouse_balance\": 43,\n      \"total_inventory_quantity\": 43,\n      \"unknown_events\": 0,\n      \"location\": \"US\",\n      \"json_object\": {\n        \"date\": \"1/31/2026\",\n        \"fnsku\": \"X003QWERT7\",\n        \"asin\": \"B09PLMN3RZ\",\n        \"msku\": \"LS-SOAP-3PK\",\n        \"title\": \"Shave Soap Refill 3-Pack\",\n        \"disposition\": \"SELLABLE\",\n        \"starting_warehouse_balance\": \"40\",\n        \"ending_warehouse_balance\": \"43\",\n        \"location\": \"US\"\n      },\n      \"created_at\": \"2026-02-01T04:10:22.000000Z\",\n      \"updated_at\": \"2026-07-06T18:31:07.000000Z\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List Outbound Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List Amazon outbound fulfillment orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"fulfillment_order_id\": \"MFN-12345\",\n      \"status\": \"COMPLETE\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 30\n}"}]},{"name":"Delete Outbound Fulfillment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]},"description":"Delete an outbound fulfillment order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Outbound fulfillment deleted\"\n}"}]},{"name":"Get Unlinked Outbound Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get unlinked outbound fulfillment orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/unlinked","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","unlinked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"fulfillment_order_id\": \"MFN-99999\"\n    }\n  ]\n}"}]},{"name":"Refresh Outbound Fulfillments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Refresh outbound fulfillment orders from Amazon.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Refresh started\"\n}"}]},{"name":"Create Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/create-fulfillment/{amazonFulfillmentOrder}/{salesOrder}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","create-fulfillment",":amazonFulfillmentOrder",":salesOrder"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"amazonFulfillmentOrder","value":"1","description":"The amazon fulfillment order ID."},{"key":"salesOrder","value":"55","description":"The sales order ID."}]},"description":"Links an Amazon MCF (outbound) order to its SKU sales order's FulfillmentOrder.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\ndeferred-shipment model: this no longer creates a SalesOrderFulfillment up front. The AmazonFulfillmentOrder is linked to its FulfillmentOrder, and the shipment SOF is minted by the canonical ship-time recorder when Amazon reports a shipment. If Amazon has already shipped, the endpoint returns the resulting fulfilled SalesOrderFulfillment; otherwise it returns a confirmation message that the order was linked and is awaiting Amazon's ship signal.\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/outbound/create-fulfillment/{amazonFulfillmentOrder}/{salesOrder}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","outbound","create-fulfillment",":amazonFulfillmentOrder",":salesOrder"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"amazonFulfillmentOrder","value":"1","description":"The amazon fulfillment order ID."},{"key":"salesOrder","value":"55","description":"The sales order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"sales_order_id\": 55,\n    \"fulfillment_type\": \"fba\",\n    \"status\": \"fulfilled\",\n    \"tracking_number\": \"TBA313166722760\",\n    \"fulfilled_at\": \"2026-06-21 14:02:11\"\n  }\n}"}]},{"name":"Create Shortage from Pending Inbound","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-pending-inbounds/{pendingInbound}/create-shortage","host":["{{baseUrl}}"],"path":["api","amazon-pending-inbounds",":pendingInbound","create-shortage"],"variable":[{"key":"pendingInbound","value":"1","description":"The pending inbound ID."}]},"description":"Create an inbound shortage record from a pending inbound.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon-pending-inbounds/{pendingInbound}/create-shortage","host":["{{baseUrl}}"],"path":["api","amazon-pending-inbounds",":pendingInbound","create-shortage"],"variable":[{"key":"pendingInbound","value":"1","description":"The pending inbound ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"pending_inbound_id\": 1,\n    \"shortage_quantity\": 10\n  }\n}"}]},{"name":"Update Inbound Shortage","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]},"description":"Update an Amazon inbound shortage record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"notes\": \"Shortage confirmed — carrier damaged 10 units\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"notes\": \"Shortage confirmed — carrier damaged 10 units\"\n  }\n}"}]},{"name":"Delete Inbound Shortage","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]},"description":"Delete an Amazon inbound shortage record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shortage deleted\"\n}"}]},{"name":"Generate Accounting Transaction for Shortage","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage","generate-accounting-transaction"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]},"description":"Generate an accounting transaction for an Amazon inbound shortage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon-inbound-shortages/{amazonInboundShortage}/generate-accounting-transaction","host":["{{baseUrl}}"],"path":["api","amazon-inbound-shortages",":amazonInboundShortage","generate-accounting-transaction"],"variable":[{"key":"amazonInboundShortage","value":"3","description":"The amazon inbound shortage ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Accounting transaction generated\",\n  \"data\": {\n    \"transaction_id\": 99\n  }\n}"}]},{"name":"List Reimbursement Cases","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases"]},"description":"Paginated list of SKU.io-tracked FBA reimbursement claim cases, unified across all Amazon integration instances. Cases are flagged by automated detectors (lost or damaged warehouse inventory, customer returns never received back, inbound shortages, fee overcharges, etc.) and move through a claim lifecycle: potential, under_review, ready_to_submit, submitted, partially_reimbursed, reimbursed, denied, dismissed, expired.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: `page` and `per_page` (default 10).\nSorting: `sort=<field>` ascending or `sort=-<field>` descending. Sortable fields: id, category, status, amazon_case_id, flagged_at, submitted_at, reconciled_at, claim_window_expires_at, sku, fnsku, asin, quantity, unit_cost, potential_amount, reimbursed_amount, currency, created_at, updated_at.\n\nSimple filters:\n- `filter[search]` — fuzzy search across amazon_case_id, sku, asin, fnsku and the integration instance name. Restrict with `search_columns` and force exact matching per column with `search_strict_columns`.\n- `filter[integration_instance_ids]` — comma-separated Amazon integration instance IDs.\n- `filter[statuses]` — comma-separated list of statuses (potential, under_review, ready_to_submit, submitted, partially_reimbursed, reimbursed, denied, dismissed, expired).\n- `filter[categories]` — comma-separated list of categories (warehouse_lost, warehouse_damaged, customer_return_not_received, customer_return_damaged, customer_return_refund_mismatch, inbound_shortage, removal_order_discrepancy, fba_fee_overcharge, chargeback_reversal, destroyed_without_authorization).\n- `filter[expiring_within_days]` — only cases whose claim window expires within the next N days (and has not already expired).\n\nAdvanced operator filters use the syntax `filter[column.operator]=value`; a bare `filter[column]=value` is treated as the `is` operator.\n- Text columns (amazon_case_id, sku, fnsku, asin, category, status, currency, unit_cost_source) support: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\n- Numeric columns (quantity, unit_cost, potential_amount, reimbursed_amount) support: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\n- Date columns (flagged_at, submitted_at, reconciled_at, claim_window_expires_at, created_at, updated_at) support: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days. Date values use ISO 8601 / Y-m-d; `between` takes two comma-separated values.\n\nComplex AND/OR filter trees can be sent via `filter_groups` (base64-encoded JSON tree of conditions and nested groups)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"category\": \"warehouse_lost\",\n      \"category_label\": \"Warehouse Lost\",\n      \"status\": \"potential\",\n      \"amazon_case_id\": null,\n      \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n      \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n      \"submitted_at\": null,\n      \"reconciled_at\": null,\n      \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n      \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n      \"days_until_expiry\": 37,\n      \"is_expired\": false,\n      \"can_submit_now\": true,\n      \"sku\": \"BCK-CANISTER-16OZ\",\n      \"fnsku\": \"X002QDR3V7\",\n      \"asin\": \"B08XYZ4Q2M\",\n      \"product_id\": 918,\n      \"amazon_fnsku_product_id\": 2451,\n      \"quantity\": 3,\n      \"unit_cost\": 14.25,\n      \"unit_cost_source\": \"fifo\",\n      \"potential_amount\": 42.75,\n      \"currency\": \"USD\",\n      \"reimbursed_amount\": null,\n      \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n      \"source_reference_type\": \"ledger_event\",\n      \"source_reference_id\": 88213,\n      \"evidence\": {\n        \"ledger_event_ids\": [\n          88213\n        ],\n        \"lost_on\": \"2026-05-14\"\n      },\n      \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n      \"dismissed_reason\": null,\n      \"assigned_user_id\": 7,\n      \"assigned_user\": {\n        \"id\": 7,\n        \"name\": \"Dana Whitfield\"\n      },\n      \"created_at\": \"2026-06-14T02:15:33+00:00\",\n      \"updated_at\": \"2026-06-19T08:12:44+00:00\"\n    },\n    {\n      \"id\": 38,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"category\": \"customer_return_not_received\",\n      \"category_label\": \"Customer Return Not Received\",\n      \"status\": \"reimbursed\",\n      \"amazon_case_id\": \"17389245671\",\n      \"flagged_at\": \"2026-04-22T06:40:12+00:00\",\n      \"detected_at\": \"2026-04-22T06:40:12+00:00\",\n      \"submitted_at\": \"2026-05-02T15:21:07+00:00\",\n      \"reconciled_at\": \"2026-06-03T09:02:51+00:00\",\n      \"claim_window_opens_at\": \"2026-04-22T00:00:00+00:00\",\n      \"claim_window_expires_at\": \"2026-10-19T23:59:59+00:00\",\n      \"days_until_expiry\": 104,\n      \"is_expired\": false,\n      \"can_submit_now\": false,\n      \"sku\": \"LEAF-RAZOR-STD\",\n      \"fnsku\": \"X001M8KQZ3\",\n      \"asin\": \"B0B7H2JKLM\",\n      \"product_id\": 655,\n      \"amazon_fnsku_product_id\": 1994,\n      \"quantity\": 1,\n      \"unit_cost\": 18.9,\n      \"unit_cost_source\": \"fifo\",\n      \"potential_amount\": 18.9,\n      \"currency\": \"USD\",\n      \"reimbursed_amount\": 18.9,\n      \"idempotency_key\": \"customer_return_not_received:3:113-4092817-5544312:X001M8KQZ3\",\n      \"source_reference_type\": \"customer_return\",\n      \"source_reference_id\": 30412,\n      \"evidence\": {\n        \"amazon_order_id\": \"113-4092817-5544312\",\n        \"refund_date\": \"2026-03-08\"\n      },\n      \"claim_text\": \"Refund issued on order 113-4092817-5544312 on 2026-03-08 but the returned unit was never received back into FBA inventory within 45 days.\",\n      \"dismissed_reason\": null,\n      \"assigned_user_id\": 7,\n      \"assigned_user\": {\n        \"id\": 7,\n        \"name\": \"Dana Whitfield\"\n      },\n      \"created_at\": \"2026-04-22T06:40:12+00:00\",\n      \"updated_at\": \"2026-06-03T09:02:51+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 47\n}"}]},{"name":"Create Reimbursement Case","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases"]},"description":"Creates a reimbursement case manually. Creation is idempotent on `idempotency_key` — if a case with the same key already exists, that case is returned instead of creating a duplicate.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `integration_instance_id` (required, integer) — Amazon integration instance the case belongs to.\n- `category` (required) — one of: warehouse_lost, warehouse_damaged, customer_return_not_received, customer_return_damaged, customer_return_refund_mismatch, inbound_shortage, removal_order_discrepancy, fba_fee_overcharge, chargeback_reversal, destroyed_without_authorization.\n- `status` (optional) — one of: potential, under_review, ready_to_submit, submitted, partially_reimbursed, reimbursed, denied, dismissed, expired. Defaults to `potential`.\n- `flagged_at` (optional, date) — when the discrepancy was flagged.\n- `claim_window_expires_at` (required, date, must be in the future) — last day a claim can be filed with Amazon.\n- `sku` (optional, string, max 64) / `fnsku` (optional, string, max 32) / `asin` (optional, string, max 32).\n- `product_id` (optional, integer) — SKU.io product ID.\n- `amazon_fnsku_product_id` (optional, integer) — Amazon FNSKU product ID.\n- `quantity` (required, integer >= 0) — affected units.\n- `unit_cost` (required, numeric >= 0) and `unit_cost_source` (optional, string, max 32, e.g. fifo, manual).\n- `potential_amount` (required, numeric >= 0) — expected recovery amount.\n- `currency` (required, 3-letter ISO code).\n- `idempotency_key` (required, string, max 191) — unique key for deduplication.\n- `source_reference_type` (optional, string, max 64) and `source_reference_id` (optional, integer) — pointer to the record that evidences the discrepancy.\n- `evidence` (optional, object) — free-form supporting data.\n- `claim_text` (optional, string) — pre-drafted text for the Seller Central case.\n- `assigned_user_id` (optional, integer) — user responsible for the case.\n\nReturns the created (or pre-existing) case with HTTP 201.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 3,\n  \"category\": \"warehouse_lost\",\n  \"status\": \"potential\",\n  \"flagged_at\": \"2026-06-14\",\n  \"claim_window_expires_at\": \"2026-08-12\",\n  \"sku\": \"BCK-CANISTER-16OZ\",\n  \"fnsku\": \"X002QDR3V7\",\n  \"asin\": \"B08XYZ4Q2M\",\n  \"product_id\": 918,\n  \"amazon_fnsku_product_id\": 2451,\n  \"quantity\": 3,\n  \"unit_cost\": 14.25,\n  \"unit_cost_source\": \"fifo\",\n  \"potential_amount\": 42.75,\n  \"currency\": \"USD\",\n  \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n  \"source_reference_type\": \"ledger_event\",\n  \"source_reference_id\": 88213,\n  \"evidence\": {\n    \"ledger_event_ids\": [\n      88213\n    ],\n    \"lost_on\": \"2026-05-14\"\n  },\n  \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n  \"assigned_user_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"category\": \"warehouse_lost\",\n    \"category_label\": \"Warehouse Lost\",\n    \"status\": \"potential\",\n    \"amazon_case_id\": null,\n    \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n    \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n    \"submitted_at\": null,\n    \"reconciled_at\": null,\n    \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n    \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n    \"days_until_expiry\": 37,\n    \"is_expired\": false,\n    \"can_submit_now\": true,\n    \"sku\": \"BCK-CANISTER-16OZ\",\n    \"fnsku\": \"X002QDR3V7\",\n    \"asin\": \"B08XYZ4Q2M\",\n    \"product_id\": 918,\n    \"amazon_fnsku_product_id\": 2451,\n    \"quantity\": 3,\n    \"unit_cost\": 14.25,\n    \"unit_cost_source\": \"fifo\",\n    \"potential_amount\": 42.75,\n    \"currency\": \"USD\",\n    \"reimbursed_amount\": null,\n    \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n    \"source_reference_type\": \"ledger_event\",\n    \"source_reference_id\": 88213,\n    \"evidence\": {\n      \"ledger_event_ids\": [\n        88213\n      ],\n      \"lost_on\": \"2026-05-14\"\n    },\n    \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n    \"dismissed_reason\": null,\n    \"assigned_user_id\": 7,\n    \"created_at\": \"2026-06-14T02:15:33+00:00\",\n    \"updated_at\": \"2026-06-19T08:12:44+00:00\"\n  }\n}"}]},{"name":"Get Reimbursement Case Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/summary","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases","summary"]},"description":"Headline reimbursement-case totals across Amazon integration instances, for dashboard-style summaries:\n- `potential_recovery` / `potential_recovery_count` — sum of potential_amount and count for open cases (potential, under_review, ready_to_submit).\n- `in_flight_amount` / `in_flight_count` — outstanding amount (potential minus already reimbursed, floored at zero) and count for submitted and partially_reimbursed cases.\n- `recovered_ytd_amount` / `recovered_ytd_count` — reimbursed amounts reconciled in the current calendar year (reimbursed and partially_reimbursed cases).\n- `lifetime_amount` / `lifetime_count` — all-time reimbursed totals.\n- `currency` — the currency code the totals are reported in (defaults to USD when no cases have a currency).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptionally scope to specific instances with `integration_instance_ids` (comma-separated)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/summary","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"potential_recovery\": 1284.5,\n    \"potential_recovery_count\": 18,\n    \"in_flight_amount\": 342.1,\n    \"in_flight_count\": 5,\n    \"recovered_ytd_amount\": 897.44,\n    \"recovered_ytd_count\": 12,\n    \"lifetime_amount\": 2145.09,\n    \"lifetime_count\": 31,\n    \"currency\": \"USD\"\n  }\n}"}]},{"name":"Detect Reimbursement Cases","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/detect","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases","detect"]},"description":"Re-runs the reimbursement discrepancy detectors and the case reconciler across all Amazon integration instances (or the subset given in `integration_instance_ids`). Works entirely from data already synced into SKU.io (inventory ledger events, customer returns, ingested reimbursement rows, etc.) — it does not call Amazon. Newly detected discrepancies create cases in `potential` status; existing open cases are matched against reimbursements Amazon has already paid.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQueues a background job; returns a job id (`tracked_job_log_id`) for polling progress.\n\n`integration_instance_ids` accepts an array of integers or a comma-separated string; omit it (or send an empty value) to scan every Amazon instance.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    3,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/detect","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases","detect"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Case re-scan started\",\n  \"data\": {\n    \"tracked_job_log_id\": 15234\n  }\n}"}]},{"name":"Get Reimbursement Case","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Returns a single reimbursement case by ID, including the integration instance name, the assigned user, and linked product identifiers. `days_until_expiry`, `is_expired` and `can_submit_now` are computed from the claim window dates at request time.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"integration_instance_name\": \"Amazon US\",\n    \"category\": \"warehouse_lost\",\n    \"category_label\": \"Warehouse Lost\",\n    \"status\": \"potential\",\n    \"amazon_case_id\": null,\n    \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n    \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n    \"submitted_at\": null,\n    \"reconciled_at\": null,\n    \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n    \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n    \"days_until_expiry\": 37,\n    \"is_expired\": false,\n    \"can_submit_now\": true,\n    \"sku\": \"BCK-CANISTER-16OZ\",\n    \"fnsku\": \"X002QDR3V7\",\n    \"asin\": \"B08XYZ4Q2M\",\n    \"product_id\": 918,\n    \"amazon_fnsku_product_id\": 2451,\n    \"quantity\": 3,\n    \"unit_cost\": 14.25,\n    \"unit_cost_source\": \"fifo\",\n    \"potential_amount\": 42.75,\n    \"currency\": \"USD\",\n    \"reimbursed_amount\": null,\n    \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n    \"source_reference_type\": \"ledger_event\",\n    \"source_reference_id\": 88213,\n    \"evidence\": {\n      \"ledger_event_ids\": [\n        88213\n      ],\n      \"lost_on\": \"2026-05-14\"\n    },\n    \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n    \"dismissed_reason\": null,\n    \"assigned_user_id\": 7,\n    \"assigned_user\": {\n      \"id\": 7,\n      \"name\": \"Dana Whitfield\"\n    },\n    \"created_at\": \"2026-06-14T02:15:33+00:00\",\n    \"updated_at\": \"2026-06-19T08:12:44+00:00\"\n  }\n}"}]},{"name":"Update Reimbursement Case","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Updates a reimbursement case. All fields are optional; only supplied fields are changed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `category` — one of: warehouse_lost, warehouse_damaged, customer_return_not_received, customer_return_damaged, customer_return_refund_mismatch, inbound_shortage, removal_order_discrepancy, fba_fee_overcharge, chargeback_reversal, destroyed_without_authorization.\n- `status` — one of: potential, under_review, ready_to_submit, submitted, partially_reimbursed, reimbursed, denied, dismissed, expired. Note: setting the status here does NOT enforce the lifecycle transition rules and does not record a case note — prefer the transition endpoint for status changes.\n- `amazon_case_id` (string, max 64) — Seller Central case ID.\n- `claim_window_expires_at` (date).\n- `quantity` (integer >= 0), `unit_cost` (numeric >= 0), `unit_cost_source` (string, max 32), `potential_amount` (numeric >= 0), `currency` (3-letter ISO code).\n- `evidence` (object), `claim_text` (string), `dismissed_reason` (string, max 255).\n- `assigned_user_id` (integer, nullable) — user responsible for the case.","body":{"mode":"raw","raw":"{\n  \"quantity\": 4,\n  \"potential_amount\": 57,\n  \"claim_text\": \"4 units of FNSKU X002QDR3V7 lost in the FBA ledger on 2026-05-14; ledger export attached.\",\n  \"assigned_user_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"category\": \"warehouse_lost\",\n    \"category_label\": \"Warehouse Lost\",\n    \"status\": \"potential\",\n    \"amazon_case_id\": null,\n    \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n    \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n    \"submitted_at\": null,\n    \"reconciled_at\": null,\n    \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n    \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n    \"days_until_expiry\": 37,\n    \"is_expired\": false,\n    \"can_submit_now\": true,\n    \"sku\": \"BCK-CANISTER-16OZ\",\n    \"fnsku\": \"X002QDR3V7\",\n    \"asin\": \"B08XYZ4Q2M\",\n    \"product_id\": 918,\n    \"amazon_fnsku_product_id\": 2451,\n    \"quantity\": 4,\n    \"unit_cost\": 14.25,\n    \"unit_cost_source\": \"fifo\",\n    \"potential_amount\": 57,\n    \"currency\": \"USD\",\n    \"reimbursed_amount\": null,\n    \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n    \"source_reference_type\": \"ledger_event\",\n    \"source_reference_id\": 88213,\n    \"evidence\": {\n      \"ledger_event_ids\": [\n        88213\n      ],\n      \"lost_on\": \"2026-05-14\"\n    },\n    \"claim_text\": \"4 units of FNSKU X002QDR3V7 lost in the FBA ledger on 2026-05-14; ledger export attached.\",\n    \"dismissed_reason\": null,\n    \"assigned_user_id\": 7,\n    \"created_at\": \"2026-06-14T02:15:33+00:00\",\n    \"updated_at\": \"2026-07-06T11:42:18+00:00\"\n  }\n}"}]},{"name":"Delete Reimbursement Case","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Permanently deletes a reimbursement case. Returns HTTP 204 with no body on success.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Transition Reimbursement Case Status","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/transition","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","transition"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Moves a reimbursement case to a new lifecycle status, enforcing the allowed transitions and recording a case note describing the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `status` (required) — target status, one of: potential, under_review, ready_to_submit, submitted, partially_reimbursed, reimbursed, denied, dismissed, expired.\n- `reason` (optional, string, max 255) — stored as the dismissal/denial reason when moving to `dismissed` or `denied`, and appended to the transition note.\n- `amazon_case_id` (optional, string, max 64) — when provided together with `status=submitted`, the case is marked as submitted to Amazon with this Seller Central case ID and `submitted_at` is stamped (the case must currently be in potential, under_review or ready_to_submit).\n\nAllowed transitions:\n- potential -> under_review, ready_to_submit, submitted, dismissed, expired\n- under_review -> potential, ready_to_submit, submitted, dismissed, expired\n- ready_to_submit -> under_review, submitted, dismissed, expired\n- submitted -> partially_reimbursed, reimbursed, denied\n- partially_reimbursed -> reimbursed, denied\n- reimbursed, denied, dismissed and expired are terminal (no outgoing transitions). Transitioning to the current status is a no-op.\n\nAn invalid transition returns HTTP 422 with an `error` message.","body":{"mode":"raw","raw":"{\n  \"status\": \"under_review\",\n  \"reason\": null,\n  \"amazon_case_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/transition","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","transition"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"category\": \"warehouse_lost\",\n    \"category_label\": \"Warehouse Lost\",\n    \"status\": \"under_review\",\n    \"amazon_case_id\": null,\n    \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n    \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n    \"submitted_at\": null,\n    \"reconciled_at\": null,\n    \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n    \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n    \"days_until_expiry\": 37,\n    \"is_expired\": false,\n    \"can_submit_now\": true,\n    \"sku\": \"BCK-CANISTER-16OZ\",\n    \"fnsku\": \"X002QDR3V7\",\n    \"asin\": \"B08XYZ4Q2M\",\n    \"product_id\": 918,\n    \"amazon_fnsku_product_id\": 2451,\n    \"quantity\": 3,\n    \"unit_cost\": 14.25,\n    \"unit_cost_source\": \"fifo\",\n    \"potential_amount\": 42.75,\n    \"currency\": \"USD\",\n    \"reimbursed_amount\": null,\n    \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n    \"source_reference_type\": \"ledger_event\",\n    \"source_reference_id\": 88213,\n    \"evidence\": {\n      \"ledger_event_ids\": [\n        88213\n      ],\n      \"lost_on\": \"2026-05-14\"\n    },\n    \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n    \"dismissed_reason\": null,\n    \"assigned_user_id\": 7,\n    \"created_at\": \"2026-06-14T02:15:33+00:00\",\n    \"updated_at\": \"2026-07-06T11:42:18+00:00\"\n  }\n}"}]},{"name":"Assign Reimbursement Case","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/assign","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","assign"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Assigns a reimbursement case to a user, or unassigns it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `assigned_user_id` (optional, integer, nullable) — ID of the user to assign the case to. Send `null` (or omit) to unassign.\n\nReturns the updated case.","body":{"mode":"raw","raw":"{\n  \"assigned_user_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/assign","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","assign"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"category\": \"warehouse_lost\",\n    \"category_label\": \"Warehouse Lost\",\n    \"status\": \"potential\",\n    \"amazon_case_id\": null,\n    \"flagged_at\": \"2026-06-14T02:15:33+00:00\",\n    \"detected_at\": \"2026-06-14T02:15:33+00:00\",\n    \"submitted_at\": null,\n    \"reconciled_at\": null,\n    \"claim_window_opens_at\": \"2026-06-14T00:00:00+00:00\",\n    \"claim_window_expires_at\": \"2026-08-12T23:59:59+00:00\",\n    \"days_until_expiry\": 37,\n    \"is_expired\": false,\n    \"can_submit_now\": true,\n    \"sku\": \"BCK-CANISTER-16OZ\",\n    \"fnsku\": \"X002QDR3V7\",\n    \"asin\": \"B08XYZ4Q2M\",\n    \"product_id\": 918,\n    \"amazon_fnsku_product_id\": 2451,\n    \"quantity\": 3,\n    \"unit_cost\": 14.25,\n    \"unit_cost_source\": \"fifo\",\n    \"potential_amount\": 42.75,\n    \"currency\": \"USD\",\n    \"reimbursed_amount\": null,\n    \"idempotency_key\": \"warehouse_lost:3:X002QDR3V7:2026-05-14\",\n    \"source_reference_type\": \"ledger_event\",\n    \"source_reference_id\": 88213,\n    \"evidence\": {\n      \"ledger_event_ids\": [\n        88213\n      ],\n      \"lost_on\": \"2026-05-14\"\n    },\n    \"claim_text\": \"3 units of FNSKU X002QDR3V7 were recorded as lost in the FBA ledger on 2026-05-14 and have not been reimbursed or found.\",\n    \"dismissed_reason\": null,\n    \"assigned_user_id\": 7,\n    \"created_at\": \"2026-06-14T02:15:33+00:00\",\n    \"updated_at\": \"2026-07-06T11:42:18+00:00\"\n  }\n}"}]},{"name":"List Reimbursement Case Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","notes"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Returns all notes on a reimbursement case, newest first. Notes have a `note_type` of `user` (written by a person) or `system` (recorded automatically for status transitions, submissions and reconciliation matches; `user_id` and `user_name` are null for system notes). Not paginated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","notes"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 311,\n      \"amazon_reimbursement_case_id\": 42,\n      \"user_id\": 7,\n      \"user_name\": \"Dana Whitfield\",\n      \"body\": \"Called Seller Support — they asked for the ledger export before opening the case.\",\n      \"note_type\": \"user\",\n      \"created_at\": \"2026-06-19T08:14:02+00:00\",\n      \"updated_at\": \"2026-06-19T08:14:02+00:00\"\n    },\n    {\n      \"id\": 309,\n      \"amazon_reimbursement_case_id\": 42,\n      \"user_id\": null,\n      \"user_name\": null,\n      \"body\": \"Status changed from potential to under_review by Dana Whitfield\",\n      \"note_type\": \"system\",\n      \"created_at\": \"2026-06-19T08:12:44+00:00\",\n      \"updated_at\": \"2026-06-19T08:12:44+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Reimbursement Case Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","notes"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Adds a user note to a reimbursement case. The note is attributed to the authenticated user and stored with `note_type` of `user`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- `body` (required, string, min 1 character) — the note text.","body":{"mode":"raw","raw":"{\n  \"body\": \"Ledger export uploaded to the Seller Central case as supporting evidence.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","notes"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 312,\n    \"amazon_reimbursement_case_id\": 42,\n    \"user_id\": 7,\n    \"body\": \"Ledger export uploaded to the Seller Central case as supporting evidence.\",\n    \"note_type\": \"user\",\n    \"created_at\": \"2026-07-06T11:45:31+00:00\",\n    \"updated_at\": \"2026-07-06T11:45:31+00:00\"\n  }\n}"}]},{"name":"List Reimbursement Case Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","activity-log"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]},"description":"Paginated audit trail for a reimbursement case, newest first. Includes create/update events on the case itself and on its notes. Each entry exposes the event name, the changed attributes (with old values where applicable) in `properties`, and the name of the user who caused the change (`causer_name`, null for system changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: `page` and `per_page` (default 15).\nFiltering: `filter[search]` matches the causer name, the event name, the change properties and the subject type."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reimbursement-cases/{reimbursementCase}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","reimbursement-cases",":reimbursementCase","activity-log"],"variable":[{"key":"reimbursementCase","value":"","description":"Reimbursement case ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5121,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"AmazonReimbursementCase\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"under_review\"\n        },\n        \"old\": {\n          \"status\": \"potential\"\n        }\n      },\n      \"causer_name\": \"Dana Whitfield\",\n      \"created_at\": \"2026-06-19T08:12:44.000000Z\"\n    },\n    {\n      \"id\": 5119,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"AmazonReimbursementCaseNote\",\n      \"subject_id\": 311,\n      \"properties\": {\n        \"attributes\": {\n          \"body\": \"Called Seller Support — they asked for the ledger export before opening the case.\",\n          \"note_type\": \"user\"\n        }\n      },\n      \"causer_name\": \"Dana Whitfield\",\n      \"created_at\": \"2026-06-19T08:14:02.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases/42/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases/42/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases/42/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/unified/reimbursement-cases/42/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Dashboard Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/dashboard?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","dashboard"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Optional: comma-separated integration instance IDs to filter","disabled":true}]},"description":"Get the Amazon inventory and valuation dashboard data, aggregated across integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params:\n- integration_instance_ids: comma-separated IDs to filter (optional)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/dashboard?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","dashboard"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Optional: comma-separated integration instance IDs to filter","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_inventory_value\": 850000,\n    \"total_units\": 12500,\n    \"by_integration\": [\n      {\n        \"id\": 1,\n        \"name\": \"US Store\",\n        \"value\": 650000,\n        \"units\": 9500\n      }\n    ],\n    \"cost_confidence\": {\n      \"high\": 8200,\n      \"medium\": 2300,\n      \"low\": 2000\n    }\n  }\n}"}]},{"name":"Refresh Reports","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/dashboard/refresh-reports","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","dashboard","refresh-reports"]},"description":"Dispatch a background job to refresh inventory reports for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- integration_instance_id: int (required)\n\nReturns a tracked_job_log_id to monitor progress.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/dashboard/refresh-reports","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","dashboard","refresh-reports"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Report refresh started for US Store\",\n  \"data\": {\n    \"tracked_job_log_id\": 42\n  }\n}"}]},{"name":"Cost Source Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-breakdown?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-breakdown"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"Get cost confidence breakdown by cogs_source.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-breakdown?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-breakdown"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"cogs_source\": \"purchase_order\",\n      \"count\": 5200,\n      \"total_value\": 650000\n    },\n    {\n      \"cogs_source\": \"manual\",\n      \"count\": 3000,\n      \"total_value\": 200000\n    }\n  ]\n}"}]},{"name":"Cost Source Event Breakdown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-event-breakdown?cogs_source=purchase_order&integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-event-breakdown"],"query":[{"key":"cogs_source","value":"purchase_order","description":"Required: COGS source to break down by event type","disabled":true},{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"Get event type breakdown for a specific cost source.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired params:\n- cogs_source: string"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-event-breakdown?cogs_source=purchase_order&integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-event-breakdown"],"query":[{"key":"cogs_source","value":"purchase_order","description":"Required: COGS source to break down by event type","disabled":true},{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"event_type\": \"RECEIPT\",\n      \"count\": 3000,\n      \"total_value\": 400000\n    },\n    {\n      \"event_type\": \"TRANSFER\",\n      \"count\": 2200,\n      \"total_value\": 250000\n    }\n  ]\n}"}]},{"name":"Cost Source Layer Drilldown","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-layer-drilldown?cogs_source=purchase_order&source_type=ledger&event_type=RECEIPT&page=1&per_page=15&search=","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-layer-drilldown"],"query":[{"key":"cogs_source","value":"purchase_order","description":"Required: COGS source","disabled":true},{"key":"source_type","value":"ledger","description":"Optional: source type filter","disabled":true},{"key":"event_type","value":"RECEIPT","description":"Optional: event type filter","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true}]},"description":"Get paginated individual FIFO layers for a cost source drilldown.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired:\n- cogs_source: string\n\nOptional:\n- source_type: string\n- event_type: string\n- integration_instance_ids: comma-separated\n- search: string\n- page, per_page"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/cost-source-layer-drilldown?cogs_source=purchase_order&source_type=ledger&event_type=RECEIPT&page=1&per_page=15&search=","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","cost-source-layer-drilldown"],"query":[{"key":"cogs_source","value":"purchase_order","description":"Required: COGS source","disabled":true},{"key":"source_type","value":"ledger","description":"Optional: source type filter","disabled":true},{"key":"event_type","value":"RECEIPT","description":"Optional: event type filter","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"fnsku\": \"X001ABC123\",\n      \"date\": \"2024-03-01\",\n      \"cogs\": 12.5,\n      \"quantity\": 100\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 3000\n}"}]},{"name":"Check FIFO Layer Revert Eligibility","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/{layerId}/revert-eligibility","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers",":layerId","revert-eligibility"],"variable":[{"key":"layerId","value":"101","description":"The layer ID."}]},"description":"Check if a FIFO layer's manual override can be reverted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/{layerId}/revert-eligibility","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers",":layerId","revert-eligibility"],"variable":[{"key":"layerId","value":"101","description":"The layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"eligible\": true,\n    \"reason\": null,\n    \"original_cogs\": 11.25\n  }\n}"}]},{"name":"Revert FIFO Layer Override","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/{layerId}/revert","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers",":layerId","revert"],"variable":[{"key":"layerId","value":"101","description":"The layer ID."}]},"description":"Revert a manual cost override on a FIFO layer back to its automatically calculated value.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/{layerId}/revert","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers",":layerId","revert"],"variable":[{"key":"layerId","value":"101","description":"The layer ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"cogs\": 11.25,\n    \"cogs_source\": \"purchase_order\"\n  }\n}"}]},{"name":"Batch Check Revert Eligibility","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/batch-revert-eligibility","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers","batch-revert-eligibility"]},"description":"Check revert eligibility for multiple FIFO layers at once (max 100).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequired fields:\n- layer_ids: array of integers (max 100)","body":{"mode":"raw","raw":"{\n  \"layer_ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/batch-revert-eligibility","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers","batch-revert-eligibility"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"layer_id\": 101,\n      \"eligible\": true\n    },\n    {\n      \"layer_id\": 102,\n      \"eligible\": false,\n      \"reason\": \"Already at original cost\"\n    }\n  ]\n}"}]},{"name":"Bulk Revert Manual Overrides","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/bulk-revert","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers","bulk-revert"]},"description":"Bulk revert all eligible manual COGS overrides matching the given filters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptional fields:\n- source_type: string filter\n- event_type: string filter\n- integration_instance_ids: comma-separated string","body":{"mode":"raw","raw":"{\n  \"source_type\": \"ledger\",\n  \"event_type\": \"RECEIPT\",\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/inventory-valuation/fifo-layers/bulk-revert","host":["{{baseUrl}}"],"path":["api","amazon","inventory-valuation","fifo-layers","bulk-revert"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reverted\": 48,\n    \"skipped\": 12\n  }\n}"}]},{"name":"List FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List FIFO Layers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Show FIFO Layer detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns detail for a single Amazon FIFO layer, including source links, parent/child layers, cost breakdown, and manual override tracking. 404 if not found.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12345,\n    \"fifo_layer_date\": \"2026-05-20\",\n    \"source_type\": \"ledger\",\n    \"source_type_label\": \"Inventory Ledger\",\n    \"fnsku\": \"X001ABC123\",\n    \"location\": \"AMZ\",\n    \"disposition\": \"SELLABLE\",\n    \"cost_locked\": false,\n    \"cost_editable\": true,\n    \"cogs_source\": \"oldest_active_fifo\",\n    \"quantity\": 100,\n    \"consumed_quantity\": 25,\n    \"available_quantity\": 75,\n    \"cogs\": 9.99,\n    \"extended_cogs\": 999,\n    \"cost_breakdown\": {\n      \"landed_unit_cost\": 9.99,\n      \"freight\": 0,\n      \"duty\": 0\n    },\n    \"reference_id\": \"FBA15ABCDEFG\",\n    \"source_reference_id\": \"FBA15ABCDEFG\",\n    \"amazon_ledger_id\": 90001,\n    \"amazon_awd_ledger_id\": null,\n    \"amazon_ledger_summary_discrepancy_id\": null,\n    \"ledger\": {\n      \"id\": 90001,\n      \"event_type\": \"Receipts\",\n      \"reference_id\": \"FBA15ABCDEFG\",\n      \"reference_link\": {\n        \"route\": \"/integrations/amazon/fba/inbound-shipments/new?filter[search]=FBA15ABCDEFG&search_columns=shipmentConfirmationId&search_strict_columns=shipmentConfirmationId\",\n        \"label\": \"Inbound Shipment\"\n      }\n    },\n    \"awd_ledger\": null,\n    \"discrepancy\": null,\n    \"product\": {\n      \"id\": 555,\n      \"sku\": \"SKU-001\",\n      \"name\": \"Widget Pro\"\n    },\n    \"fnsku_product\": {\n      \"id\": 4321,\n      \"fnsku\": \"X001ABC123\",\n      \"asin\": \"B07XYZ1234\",\n      \"msku\": \"MSKU-001\",\n      \"product_id\": 555\n    },\n    \"warehouse\": {\n      \"id\": 7,\n      \"name\": \"Amazon FBA US\"\n    },\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"Amazon US\"\n    },\n    \"parent_fifo_layer\": null,\n    \"child_fifo_layers\": [],\n    \"previous_cogs\": 8.5,\n    \"previous_cogs_source\": \"unit_cost\",\n    \"cogs_overridden_by\": 12,\n    \"cogs_overridden_by_name\": \"Jane Doe\",\n    \"cogs_overridden_at\": \"2026-05-21T14:30:00+00:00\",\n    \"created_at\": \"2026-05-20T10:00:00+00:00\",\n    \"updated_at\": \"2026-05-21T14:30:00+00:00\"\n  }\n}"}]},{"name":"List Consumptions across all FIFO Layers (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/consumptions","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","consumptions"]},"description":"Cross-layer paginated consumption listing. Each item is transformed via Amazon fifo consumption object; the fifo_layer relation is included for cross-layer context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/consumptions","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","consumptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 778899,\n      \"effective_at\": \"2026-05-22\",\n      \"quantity\": 5,\n      \"cogs\": 9.99,\n      \"extended_cogs\": 49.95,\n      \"cost_locked\": false,\n      \"cost_editable\": true,\n      \"fnsku\": \"X001ABC123\",\n      \"location\": \"AMZ\",\n      \"disposition\": \"SELLABLE\",\n      \"amazon_ledger_id\": 90002,\n      \"amazon_awd_ledger_id\": null,\n      \"product\": {\n        \"id\": 555,\n        \"sku\": \"SKU-001\",\n        \"name\": \"Widget Pro\"\n      },\n      \"ledger\": {\n        \"id\": 90002,\n        \"date\": \"2026-05-22\",\n        \"event_type\": \"CustomerReturns\",\n        \"reference_id\": \"112-1234567-1234567\"\n      },\n      \"awd_ledger\": null,\n      \"fifo_layer\": {\n        \"id\": 12345,\n        \"fifo_layer_date\": \"2026-05-20\",\n        \"source_type\": \"ledger\",\n        \"source_type_label\": \"Inventory Ledger\",\n        \"quantity\": 100,\n        \"cogs\": 9.99,\n        \"integration_instance_name\": \"Amazon US\"\n      },\n      \"created_at\": \"2026-05-22T09:00:00+00:00\",\n      \"updated_at\": \"2026-05-22T09:00:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/consumptions?page=1\",\n  \"from\": 1,\n  \"last_page\": 10,\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/consumptions?page=10\",\n  \"links\": [],\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/consumptions?page=2\",\n  \"path\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/consumptions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 150\n}"}]},{"name":"List Consumptions for a Specific FIFO Layer (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}/consumptions","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id","consumptions"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated consumption records for one FIFO layer. 404 if the layer doesn't exist.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}/consumptions","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id","consumptions"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 778899,\n      \"effective_at\": \"2026-05-22\",\n      \"quantity\": 5,\n      \"cogs\": 9.99,\n      \"extended_cogs\": 49.95,\n      \"cost_locked\": false,\n      \"cost_editable\": true,\n      \"fnsku\": \"X001ABC123\",\n      \"location\": \"AMZ\",\n      \"disposition\": \"SELLABLE\",\n      \"amazon_ledger_id\": 90002,\n      \"amazon_awd_ledger_id\": null,\n      \"product\": {\n        \"id\": 555,\n        \"sku\": \"SKU-001\",\n        \"name\": \"Widget Pro\"\n      },\n      \"ledger\": {\n        \"id\": 90002,\n        \"date\": \"2026-05-22\",\n        \"event_type\": \"CustomerReturns\",\n        \"reference_id\": \"112-1234567-1234567\"\n      },\n      \"awd_ledger\": null,\n      \"created_at\": \"2026-05-22T09:00:00+00:00\",\n      \"updated_at\": \"2026-05-22T09:00:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/consumptions?page=1\",\n  \"from\": 1,\n  \"last_page\": 2,\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/consumptions?page=2\",\n  \"links\": [],\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/consumptions?page=2\",\n  \"path\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/consumptions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 25\n}"}]},{"name":"Activity Log for a FIFO Layer (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns paginated Spatie activity-log entries for the given FIFO layer, newest first. Uses the AppliesActivityLogFilters trait for filter[event], filter[source], filter[batch_uuid]. 404 if the layer doesn't exist (findOrFail).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1002,\n      \"description\": \"COGS updated from 8.50 to 9.99\",\n      \"event\": \"updated\",\n      \"properties\": {\n        \"source\": \"manual\",\n        \"attributes\": {\n          \"cogs\": 9.99,\n          \"cogs_source\": \"manual\"\n        },\n        \"old\": {\n          \"cogs\": 8.5,\n          \"cogs_source\": \"unit_cost\"\n        }\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2026-05-21T14:30:00.000000Z\"\n    },\n    {\n      \"id\": 1001,\n      \"description\": \"FIFO layer created from ledger event\",\n      \"event\": \"created\",\n      \"properties\": {\n        \"source\": \"amazon_sync\",\n        \"attributes\": {\n          \"cogs\": 8.5,\n          \"quantity\": 100\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-05-20T10:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/activity-log?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/fifo-layers/cogs/12345/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Bulk Update COGS","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","bulk-update"]},"description":"Bulk-set the same COGS value on multiple FIFO layers. Validation (BulkUpdateFifoLayerCogsData): layer_ids required array min:1; layer_ids.* required integer exists:amazon_fifo_layers,id; cogs required numeric min:0. Additionally, all selected layers MUST belong to the same product or a 422 is returned. Returns the updated_count and a success message.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"layer_ids\": [\n    12345,\n    12346,\n    12347\n  ],\n  \"cogs\": 9.99\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","bulk-update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"COGS updated successfully\",\n  \"updated_count\": 3\n}"}]},{"name":"Export FIFO Layers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","export"]},"description":"Export FIFO Layers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Download COGS Import Template (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import/template","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import","template"]},"description":"Streams a CSV template (fifo-layer-cogs-import-template.csv) with headers: layer_id, cogs. Includes one sample row (12345, 9.99).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import/template","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import","template"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"layer_id,cogs\n12345,9.99\n"}]},{"name":"Validate COGS Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import/validate","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import","validate"]},"description":"Validates a parsed CSV import payload BEFORE committing. Validation rules: rows required array min:1; rows.*.layer_id present; rows.*.cogs present. Per-row business validation checks layer existence and cogs >= 0. Returns valid_rows, error_rows, and summary counts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"layer_id\": 12345,\n      \"cogs\": 9.99\n    },\n    {\n      \"layer_id\": 12346,\n      \"cogs\": 0\n    },\n    {\n      \"layer_id\": \"\",\n      \"cogs\": \"abc\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import/validate","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"valid_rows\": [\n    {\n      \"row_number\": 1,\n      \"layer_id\": 12345,\n      \"cogs\": 9.99,\n      \"errors\": [],\n      \"layer\": {\n        \"id\": 12345,\n        \"fnsku\": \"X001ABC123\",\n        \"product_sku\": \"SKU-001\",\n        \"current_cogs\": 8.5,\n        \"qty\": 100\n      }\n    },\n    {\n      \"row_number\": 2,\n      \"layer_id\": 12346,\n      \"cogs\": 0,\n      \"errors\": [],\n      \"layer\": {\n        \"id\": 12346,\n        \"fnsku\": \"X001DEF456\",\n        \"product_sku\": \"SKU-002\",\n        \"current_cogs\": 0,\n        \"qty\": 50\n      }\n    }\n  ],\n  \"error_rows\": [\n    {\n      \"row_number\": 3,\n      \"layer_id\": null,\n      \"cogs\": null,\n      \"errors\": [\n        \"Layer ID is required.\",\n        \"COGS must be a numeric value.\"\n      ]\n    }\n  ],\n  \"summary\": {\n    \"total\": 3,\n    \"valid\": 2,\n    \"errors\": 1\n  }\n}"}]},{"name":"Execute COGS Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import"]},"description":"Executes a validated COGS import. Validation rules: rows required array min:1; rows.*.layer_id required integer; rows.*.cogs required numeric min:0. Each row updates the layer's cogs and propagates the change to consumptions, discrepancies, provisional layers, and pending inbounds. Wrapped in a DB transaction.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"layer_id\": 12345,\n      \"cogs\": 9.99\n    },\n    {\n      \"layer_id\": 12346,\n      \"cogs\": 4.5\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-layers/cogs/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-layers","cogs","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"updated_count\": 2,\n  \"errors\": []\n}"}]},{"name":"Get FIFO Inventory Valuation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-inventory-valuation?integration_instance_ids=&date=","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-inventory-valuation"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true},{"key":"date","value":"","disabled":true}]},"description":"Get FIFO Inventory Valuation\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Max Report Date","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fifo-inventory-valuation/max-date","host":["{{baseUrl}}"],"path":["api","amazon","unified","fifo-inventory-valuation","max-date"]},"description":"Get Max Report Date\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List Valuation Snapshots","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/valuation-snapshots?page=1&per_page=10&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","valuation-snapshots"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Valuation Snapshots\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Valuation Totals","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/valuation-snapshots/totals?integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","valuation-snapshots","totals"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"Get Valuation Totals\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List Amazon Products for Integration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products?per_page=10&page=1&sort=-id&filter[archived]=0","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products"],"query":[{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"page","value":"1","description":"Page number (1-indexed)","disabled":true},{"key":"sort","value":"-id","description":"Allowed: id, seller_sku, asin1, item_name, price, quantity, status, fulfillment_channel, brand, product_type, created_at, updated_at. Prefix with `-` for descending. Default: -id.","disabled":true},{"key":"filter[archived]","value":"0","description":"0 = active (default), 1 (or `true`) = archived only, `only` = archived only, `all` = include both.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Paginated list of `AmazonProduct` rows for one Amazon integration instance. Powers the application UI **Amazon → Products** listing page (`AmazonProductsPage`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUses Spatie QueryBuilder with `GroupedFilterSupport`, eager-loading `productListing.product.defaultFinancialLineType` so the SKU.io mapping is rendered inline.\n\n**Default behavior:** archived products are hidden (`archived=0`) unless `filter[archived]` is supplied. Default sort is `-id`. Default page size is `10`.\n\n**legacy mode:** when the request carries `table_specifications`, the controller falls back to the legacy `abstractIndexForIntegration` list view response shape used by the Vue 2 page.\n\n**Allowed sorts:** `id`, `seller_sku`, `asin1`, `item_name`, `price`, `quantity`, `status`, `fulfillment_channel`, `brand`, `product_type`, `created_at`, `updated_at`.\n\n**Advanced filter operators** are also supported on `seller_sku`, `asin1`, `item_name`, `brand`, `product_type` (text), `price` (numeric), `created_at`, `updated_at` (datetime) via `filter[<column>][<operator>]=<value>`.\n\n**Response shape:** standard Laravel paginator wrapping Amazon product object. Each row includes catalog attributes, FBA flags, dimensions/weight, and a `sku_product` block populated from the linked SKU.io product (when mapped)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products?per_page=10&page=1&sort=-id&filter[archived]=0","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products"],"query":[{"key":"per_page","value":"10","description":"Items per page (default 10)","disabled":true},{"key":"page","value":"1","description":"Page number (1-indexed)","disabled":true},{"key":"sort","value":"-id","description":"Allowed: id, seller_sku, asin1, item_name, price, quantity, status, fulfillment_channel, brand, product_type, created_at, updated_at. Prefix with `-` for descending. Default: -id.","disabled":true},{"key":"filter[archived]","value":"0","description":"0 = active (default), 1 (or `true`) = archived only, `only` = archived only, `all` = include both.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41201,\n      \"integration_instance_id\": 1,\n      \"seller_sku\": \"ABC-001-RED\",\n      \"asin1\": \"B0CXYZ1234\",\n      \"item_name\": \"Acme Widget — Red, 8oz\",\n      \"price\": 24.99,\n      \"quantity\": 152,\n      \"status\": \"Active\",\n      \"fulfillment_channel\": \"AMAZON_NA\",\n      \"is_fba\": true,\n      \"label_owner\": \"AMAZON\",\n      \"prep_owner\": \"AMAZON\",\n      \"country_code\": \"US\",\n      \"brand\": \"Acme\",\n      \"manufacturer\": \"Acme Mfg.\",\n      \"model\": \"WID-8\",\n      \"part_number\": \"WID-8-RED\",\n      \"product_type\": \"BEAUTY\",\n      \"sales_rank\": 4821,\n      \"color\": \"Red\",\n      \"size\": \"8oz\",\n      \"style\": \"Classic\",\n      \"department\": \"unisex-adult\",\n      \"material\": \"Plastic\",\n      \"package_length\": 6.5,\n      \"package_width\": 4,\n      \"package_height\": 3,\n      \"package_dimensions_unit\": \"inches\",\n      \"package_weight\": 0.45,\n      \"package_weight_unit\": \"pounds\",\n      \"item_length\": 5.5,\n      \"item_width\": 3.5,\n      \"item_height\": 2.5,\n      \"item_dimensions_unit\": \"inches\",\n      \"item_weight\": 0.4,\n      \"item_weight_unit\": \"pounds\",\n      \"item_description\": \"Premium red widget.\",\n      \"merchant_shipping_group\": \"Migrated Template\",\n      \"image_url\": \"https://m.media-amazon.com/images/I/abc.jpg\",\n      \"main_image\": \"https://m.media-amazon.com/images/I/abc.jpg\",\n      \"listing_id\": \"0501XXXX1234\",\n      \"open_date\": \"2024-09-12T17:32:00+00:00\",\n      \"removed_from_amazon\": false,\n      \"was_catalog_data_sync_attempted\": true,\n      \"catalog_data_last_sync\": \"2026-05-28T14:01:33+00:00\",\n      \"catalog_data\": {\n        \"attributes\": {}\n      },\n      \"listing_url\": \"https://www.amazon.com/dp/B0CXYZ1234\",\n      \"is_listing_suppressed\": false,\n      \"has_listing_issues\": false,\n      \"realtime_listing_issues\": [],\n      \"realtime_listing_status\": null,\n      \"archived_at\": null,\n      \"created_at\": \"2024-09-12T17:32:00+00:00\",\n      \"updated_at\": \"2026-05-28T14:01:33+00:00\",\n      \"sku_product\": {\n        \"id\": 33421,\n        \"sku\": \"ABC-001-RED\",\n        \"name\": \"Acme Widget Red 8oz\",\n        \"barcode\": 12345678905,\n        \"price\": 24.99,\n        \"type\": \"standard\",\n        \"default_financial_line_type_id\": null,\n        \"default_financial_line_type\": null\n      }\n    },\n    {\n      \"id\": 41205,\n      \"integration_instance_id\": 1,\n      \"seller_sku\": \"ABC-002-BLU\",\n      \"asin1\": \"B0CXYZ5678\",\n      \"item_name\": \"Acme Widget — Blue, 8oz\",\n      \"price\": 24.99,\n      \"quantity\": 0,\n      \"status\": \"Inactive\",\n      \"fulfillment_channel\": null,\n      \"is_fba\": false,\n      \"sku_product\": null,\n      \"is_listing_suppressed\": false,\n      \"has_listing_issues\": false,\n      \"realtime_listing_issues\": [],\n      \"realtime_listing_status\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.com/api/amazon/1/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 84,\n  \"last_page_url\": \"https://example.com/api/amazon/1/products?page=84\",\n  \"links\": [],\n  \"next_page_url\": \"https://example.com/api/amazon/1/products?page=2\",\n  \"path\": \"https://example.com/api/amazon/1/products\",\n  \"per_page\": 2,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 168\n}"}]},{"name":"Show Amazon Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Returns a single `AmazonProduct` wrapped in the SKU.io response envelope. Delegates to the abstract sales-channel show — the response body contains the full Amazon product object payload (same fields as the list endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis endpoint is registered automatically by the `Route::salesChannel` macro as an `apiResource` (`except index`), so the standard show / store / update / destroy routes exist for `/api/amazon/:integrationInstance/products`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"integration_instance_id\": 1,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"item_name\": \"Acme Widget — Red, 8oz\",\n    \"price\": 24.99,\n    \"quantity\": 152,\n    \"status\": \"Active\",\n    \"is_fba\": true,\n    \"listing_url\": \"https://www.amazon.com/dp/B0CXYZ1234\",\n    \"is_listing_suppressed\": false,\n    \"has_listing_issues\": false,\n    \"realtime_listing_issues\": [],\n    \"realtime_listing_status\": null,\n    \"sku_product\": null\n  }\n}"}]},{"name":"Update Single Product Metadata (Label / Prep Owner)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/product/{product}/update-metadata","host":["{{baseUrl}}"],"path":["api","amazon","product",":product","update-metadata"],"variable":[{"key":"product","value":"9871","description":"ProductListing ID (NOT AmazonProduct ID). The bound model is `ProductListing`; the controller updates the related `amazonListing` (`amazon_products`) row's `metadata` JSON column."}]},"description":"Patches the `metadata.label_owner` / `metadata.prep_owner` fields on the Amazon product associated with a SKU.io `ProductListing`. Used by the FBA prep configuration UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (both optional, but at least one should be supplied — `nullable|string` validation):**\n- `label_owner` (string|null) — typically `AMAZON` or `SELLER`.\n- `prep_owner` (string|null) — typically `AMAZON` or `SELLER`.\n\n**Note:** the route binds `ProductListing` (not `AmazonProduct`) — the controller resolves the Amazon listing via `$product->amazonListing` and merges the fields into its existing `metadata` array before saving.\n\nNamed route: `amazon.product.update-metadata` (note the singular `product` — distinct from the bulk `amazon.products.*` namespace).","body":{"mode":"raw","raw":"{\n  \"label_owner\": \"AMAZON\",\n  \"prep_owner\": \"SELLER\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/product/{product}/update-metadata","host":["{{baseUrl}}"],"path":["api","amazon","product",":product","update-metadata"],"variable":[{"key":"product","value":"9871","description":"ProductListing ID (NOT AmazonProduct ID). The bound model is `ProductListing`; the controller updates the related `amazonListing` (`amazon_products`) row's `metadata` JSON column."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Metadata updated successfully.\"\n}"}]},{"name":"Archive Single Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Archives a single Amazon product. The product is reloaded with `productListing.product.defaultFinancialLineType` + `productListing.subscriptionOffering` and returned as an Amazon product object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.archive` (single — distinct from the bulk PUT `/archive` endpoint above).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"item_name\": \"Acme Widget — Red, 8oz\",\n    \"status\": \"Active\",\n    \"archived_at\": \"2026-05-29T10:14:22+00:00\"\n  },\n  \"message\": \"Product archived successfully.\"\n}"}]},{"name":"Unarchive Single Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Unarchives a single Amazon product. Returns the refreshed product as an Amazon product object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.unarchive` (single).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"archived_at\": null\n  },\n  \"message\": \"Product unarchived successfully.\"\n}"}]},{"name":"Refresh Single Product (Catalog Lookup)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Refreshes a single product's catalog data directly from Amazon's SP-API catalog endpoint. Updates `catalog_data`, `catalog_data_last_sync`, `was_catalog_data_sync_attempted`, and `removed_from_amazon` in place, then returns the refreshed Amazon product object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns HTTP 403 when the product does not belong to the given integration instance, HTTP 500 on Amazon API failure (with error message in `error`).\n\nNamed route: `amazon.products.refresh` (single).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"was_catalog_data_sync_attempted\": true,\n    \"catalog_data_last_sync\": \"2026-05-29T10:14:22+00:00\",\n    \"removed_from_amazon\": false\n  },\n  \"message\": \"Product refreshed successfully.\"\n}"}]},{"name":"Get Raw Catalog Data from Amazon","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Forces a live catalog lookup against Amazon for a single product and then returns the *raw* sync output: ASIN, `catalog_data`, `catalog_data_last_sync`, `was_catalog_data_sync_attempted`, `removed_from_amazon`, and the underlying `json_object` for the row.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed by the **Debug Raw** drawer on the products page.\n\n**Errors:**\n- `403` — the product does not belong to the given integration instance.\n- `422` — the product has no `asin1` to look up.\n- `500` — Amazon API call failed (error message returned in `message`).\n\nNamed route: `amazon.products.raw`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"asin\": \"B0CXYZ1234\",\n    \"catalog_data\": {\n      \"summaries\": [\n        {\n          \"marketplaceId\": \"ATVPDKIKX0DER\",\n          \"itemName\": \"Acme Widget — Red, 8oz\",\n          \"brandName\": \"Acme\"\n        }\n      ]\n    },\n    \"catalog_data_last_sync\": \"2026-05-29T10:14:22+00:00\",\n    \"was_catalog_data_sync_attempted\": true,\n    \"removed_from_amazon\": false,\n    \"json_object\": {\n      \"seller-sku\": \"ABC-001-RED\",\n      \"asin1\": \"B0CXYZ1234\"\n    }\n  }\n}"}]},{"name":"Create SKU.io Product from Amazon Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Single-row variant of the bulk Create-SKU-Products endpoint. Used by the per-row **Create SKU.io Product** button in the unified mapping modal (Amazon parity with Faire/Shopify).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBehavior:\n- If the Amazon product already has a mapping (`productListing`), returns HTTP 422.\n- If a SKU.io `products.sku` row already exists matching the Amazon `seller_sku`, the existing product is linked (no duplicate is created) — `linked_existing: true` in the response.\n- Otherwise, a new SKU.io product is created and mapped.\n\nReturns HTTP 201 in both link and create cases, with the refreshed Amazon product object.\n\nNamed route: `amazon.products.create-sku-product`.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"item_name\": \"Acme Widget — Red, 8oz\",\n    \"sku_product\": {\n      \"id\": 33425,\n      \"sku\": \"ABC-001-RED\",\n      \"name\": \"Acme Widget — Red, 8oz\",\n      \"type\": \"standard\"\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Map Single Product to SKU.io Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Per-row mapping endpoint used by the unified products mapping modal (Faire/Shopify parity). Maps a single Amazon product to either an existing SKU.io product (`product_id`) or a subscription offering (`subscription_offering_id`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (one of, required):**\n- `product_id` (int, required_without:subscription_offering_id, must exist in `products`) — link to a SKU.io product.\n- `subscription_offering_id` (int, required_without:product_id, must exist in `subscription_offerings`) — link to a subscription offering.\n\nBehavior:\n- If the Amazon product is already mapped (`productListing` exists), the existing row is updated in place — supports the Remap flow.\n- Otherwise a new `ProductListing` row is created with `sales_channel_id` = the instance's sales channel, `listing_sku` = `seller_sku`, `document_type` = `AmazonProduct::class`.\n- After mapping, any unmapped `SalesOrderLine` rows matching this listing are dispatched to a background job so back-fill happens automatically.\n\nReturns HTTP 201 with the refreshed Amazon product object.\n\nNamed route: `amazon.products.map` (single).","body":{"mode":"raw","raw":"{\n  \"product_id\": 33421\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"item_name\": \"Acme Widget — Red, 8oz\",\n    \"sku_product\": {\n      \"id\": 33421,\n      \"sku\": \"ABC-001-RED\",\n      \"name\": \"Acme Widget Red 8oz\",\n      \"type\": \"standard\"\n    }\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Single Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Removes the existing `ProductListing` link between an Amazon product and its SKU.io product. Returns HTTP 422 with `Product is not mapped.` when no mapping exists.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the refreshed Amazon product object (with `sku_product: null`).\n\nNamed route: `amazon.products.unmap`."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41201,\n    \"seller_sku\": \"ABC-001-RED\",\n    \"asin1\": \"B0CXYZ1234\",\n    \"sku_product\": null\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Get Orders for Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/orders?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","orders"],"query":[{"key":"per_page","value":"10","description":"Items per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]},"description":"Paginated list of Amazon orders (`AmazonOrder`) that include a line item with this product's `seller_sku`. Orders are returned sorted by `PurchaseDate` (newest first) and wrapped in Amazon order object. Used by the **Recent Orders** lazy-loading tab on the product detail/mapping modal.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns HTTP 403 when the product does not belong to the given integration instance.\n\n**Note:** the response shape is hand-built (not a Laravel paginator dump) — it includes `current_page`, `last_page`, `per_page`, `total`, `from`, `to` alongside the `data` array.\n\nNamed route: `amazon.products.orders`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/{product}/orders?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products",":product","orders"],"query":[{"key":"per_page","value":"10","description":"Items per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."},{"key":"product","value":"41201","description":"AmazonProduct ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 990125,\n      \"AmazonOrderId\": \"114-1234567-1234567\",\n      \"PurchaseDate\": \"2026-05-25T18:42:11+00:00\",\n      \"OrderStatus\": \"Shipped\",\n      \"OrderTotal\": {\n        \"Amount\": \"24.99\",\n        \"CurrencyCode\": \"USD\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 22,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Sync summary card data for the **Amazon → Products** page header chip — last sync timestamp, total/ mapped/unmapped product counts, and the title/date of the most recently updated product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.latest-sync-info`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Acme Widget — Red, 8oz\",\n    \"latest_product_date\": \"2026-05-28T14:01:33+00:00\",\n    \"total_products\": 168,\n    \"mapped_products\": 142,\n    \"unmapped_products\": 26,\n    \"last_synced_at\": \"2026-05-28T14:01:33\"\n  }\n}"}]},{"name":"Refresh All Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Triggers an asynchronous Amazon report request to refresh the catalog. Returns immediately with a queued-message; progress is surfaced via the tracked job log endpoints (a background job).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.refresh`.\n\nReturns **409 Conflict** when an Amazon `GET_MERCHANT_LISTINGS_ALL_DATA` report is already in progress for this integration instance (Amazon SP-API permits only one report of a given type at a time). The response includes a `conflicting_report` object with the in-progress report's id, type, processing status, and creation time.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be refreshed shortly.\"\n}"}]},{"name":"Export Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","export"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Streams an export of the integration instance's Amazon products (CSV/XLSX) using the abstract sales-channel exporter. Returns a `BinaryFileResponse`, a `RedirectResponse` (when async export is dispatched), or the SKU.io response envelope on failure.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThrows `ExportingEmptyDataException` (handled by the global error handler) if the result set is empty.\n\nNamed route: `amazon.products.export`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","export"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,seller_sku,asin1,item_name,price,quantity,status,fulfillment_channel\n41201,ABC-001-RED,B0CXYZ1234,\"Acme Widget — Red, 8oz\",24.99,152,Active,AMAZON_NA\n"}]},{"name":"Create SKU.io Products (Bulk)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Bulk-creates SKU.io products from a selection of Amazon products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (`CreateSkuProductsFromSalesChannelData`):**\n- `create_all_products` (bool, required) — when true, all products for this integration instance are queued.\n- `ids` (`array<int>`, required unless `create_all_products` or `filters` is supplied) — explicit AmazonProduct IDs.\n- `mappings` (`array<DataImportMappingData>`, optional) — `{ original_name, stored_name }` entries persisted.\n- `filters` (string|null, optional) — when present, IDs are resolved from the filter set instead of from `ids`.\n- `initial_mapping` (bool, default false) — internal flag used by the import wizard.\n\nReturns immediately with a queued message; the manager job actually creates the SKU.io products and the corresponding `ProductListing` mappings.\n\nNamed route: `amazon.products.create-sku-products`.\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"create_all_products\": false,\n  \"ids\": [\n    41201,\n    41205\n  ],\n  \"mappings\": [],\n  \"initial_mapping\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be created shortly.\"\n}"}]},{"name":"Map Products to SKU.io Products (Bulk)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Bulk-maps Amazon products to existing SKU.io products (or `subscription_offering_id`) in a single call. Used by the legacy import wizard.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (`SalesChannelProductToSkuProductMappingCollectionData`):**\n- `mapping` (array, min 1) — each item is a `SalesChannelProductToSkuProductMappingData`:\n  - `sales_channel_listing_id` (string, required) — usually the Amazon `seller_sku`.\n  - `mapped_sku` (string|null) — SKU.io `products.sku` to map to. Empty string is coerced to null (i.e. an unmap).\n  - `product_listing_id` (int|null, optional) — existing `product_listings` row to update.\n  - `subscription_offering_id` (int|null, optional) — map to a subscription offering instead of a product.\n\n**Validation:** `salesChannelProductMappingsValidation()` enforces that FBA listings can only be mapped to `standard`, `kit`, or `blemished` product types, and that non-FBA listings additionally accept `bundle`. Returns HTTP 402 with an error message on violation.\n\nThrows `SalesChannelProductMappingException` → HTTP 400 with the exception message.\n\nNamed route: `amazon.products.map`.","body":{"mode":"raw","raw":"{\n  \"mapping\": [\n    {\n      \"sales_channel_listing_id\": \"ABC-001-RED\",\n      \"mapped_sku\": \"ABC-001-RED\"\n    },\n    {\n      \"sales_channel_listing_id\": \"ABC-002-BLU\",\n      \"mapped_sku\": \"WID-BLU-8\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\"\n}"}]},{"name":"Import Mappings (CSV/XLSX)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Queues a background job on the `serial` queue to apply Amazon → SKU.io product mappings from a previously uploaded file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (`SalesChannelProductImportMappingData`):**\n- `original_name` (string, required) — original filename as uploaded.\n- `stored_name` (string, required) — server-side filename (returned by the file upload endpoint).\n\nNamed route: `amazon.products.import-mappings`.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"amazon-mappings-2026-05.csv\",\n  \"stored_name\": \"uploads/imports/amazon-mappings-2026-05-xyz123.csv\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, mappings will be imported shortly.\"\n}"}]},{"name":"Archive Products (Bulk)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Bulk-archives Amazon products. Body accepts either an explicit ID list, or `mode: \"all\"` to archive every product for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:**\n- `ids` (`array<int>`, required unless `mode = all`) — validated against existing IDs for this integration instance.\n- `mode` (string, optional) — set to `\"all\"` to bypass `ids` and operate on every product.\n\nNamed route: `amazon.products.archive`.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    41201,\n    41205\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Unarchive Products (Bulk)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Bulk-unarchives previously archived Amazon products. Same body shape as the bulk Archive endpoint (`ids` or `mode = \"all\"`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.unarchive`.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    41201,\n    41205\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products unarchived successfully.\"\n}"}]},{"name":"Check Archiveable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Pre-flight check that returns per-product status (`can_archive` / reason if not) for the supplied selection. Used by the UI to disable Archive in bulk-action menus when some rows can't be archived (e.g. they have open orders).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:** same as the bulk Archive endpoint — `ids` (array) or `mode: \"all\"`.\n\nNamed route: `amazon.products.archiveable`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    41201,\n    41205\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41201,\n      \"can_archive\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 41205,\n      \"can_archive\": false,\n      \"reason\": \"Product has linked orders.\"\n    }\n  ]\n}"}]},{"name":"Delete Products (Bulk)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Bulk-deletes Amazon product records (and their `ProductListing` rows). Body accepts `ids` (array) or `mode: \"all\"`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `amazon.products.delete`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    41201,\n    41205\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products deleted successfully.\"\n}"}]},{"name":"Check Deleteable","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Pre-flight check for the bulk-delete action. Returns per-product `can_delete` / `reason` so the UI can disable Delete in the bulk-action menu when some rows can't be removed (typically because they have linked orders or inventory movements).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:** `ids` (array) or `mode: \"all\"`.\n\nNamed route: `amazon.products.deleteable`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    41201,\n    41205\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41201,\n      \"can_delete\": true,\n      \"reason\": null\n    },\n    {\n      \"id\": 41205,\n      \"can_delete\": false,\n      \"reason\": \"Product has linked orders.\"\n    }\n  ]\n}"}]},{"name":"Sync Inventory to Amazon","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]},"description":"Submits the supplied SKU.io `product_listings` IDs to Amazon as an inventory feed. The controller groups listings by Amazon marketplace country code and dispatches one sync per group so that each marketplace gets its own feed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:**\n- `ids` (`array<int>`, optional) — `product_listings.id` values to sync. When omitted, the underlying manager defaults are used.\n\nNamed route: `amazon.products.sync-inventory`.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    9871,\n    9872\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"Show FNSKU Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/{fnskuProduct}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products",":fnskuProduct"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fnskuProduct","value":"1","description":"The fnsku product ID."}]},"description":"Get details of a specific FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/{fnskuProduct}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products",":fnskuProduct"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fnskuProduct","value":"1","description":"The fnsku product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"fnsku\": \"X001ABC123\",\n    \"location\": \"US\",\n    \"disposition\": \"SELLABLE\",\n    \"initial_unit_cost\": 12.5,\n    \"product\": {\n      \"id\": 42,\n      \"sku\": \"WIDGET-RED\"\n    }\n  }\n}"}]},{"name":"Generate FNSKU Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/create","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","create"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Generate FNSKU product records from inventory data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/create","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","create"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FNSKU products generated successfully\",\n  \"data\": {\n    \"created\": 15,\n    \"skipped\": 5\n  }\n}"}]},{"name":"Link FNSKU to Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/link-to-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","link-to-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Link a FNSKU product to an internal product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_id\": 1,\n  \"product_id\": 42\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/link-to-product","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","link-to-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FNSKU product linked to product successfully\"\n}"}]},{"name":"Bulk Map by ASIN","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/bulk-map-by-asin","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","bulk-map-by-asin"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk map FNSKU products by ASIN to internal products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"asin\": \"B08XYZ1234\",\n      \"product_id\": 42\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/bulk-map-by-asin","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","bulk-map-by-asin"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk ASIN mapping completed\",\n  \"data\": {\n    \"mapped\": 10\n  }\n}"}]},{"name":"Get Auto-Mapping Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","auto-mapping-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get FNSKU auto-mapping settings for an integration instance. Returns whether new FNSKUs are automatically mapped to a product when a matching ASIN mapping already exists. Email and in-app alerts for unmapped FNSKUs are configured separately via alert notification preferences.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","auto-mapping-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"is_fnsku_auto_mapping_enabled\": true\n  }\n}"}]},{"name":"Update Auto-Mapping Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","auto-mapping-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Update FNSKU auto-mapping settings for an integration instance. Accepts `is_fnsku_auto_mapping_enabled` (boolean) to control whether new FNSKUs are automatically mapped when a matching ASIN mapping exists. Email and in-app alerts for unmapped FNSKUs are configured separately via alert notification preferences.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"is_fnsku_auto_mapping_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","auto-mapping-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Auto-mapping settings updated successfully\"\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/activity-log?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get FNSKU product mapping activity log for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fnsku-products/activity-log?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fnsku-products","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"event\": \"mapped\",\n      \"fnsku\": \"X001ABC123\",\n      \"product_sku\": \"WIDGET-RED\",\n      \"created_at\": \"2024-06-01T10:00:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 50\n}"}]},{"name":"Show FBA Inventory Record","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba-inventory/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba-inventory",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a specific FBA inventory report record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/fba-inventory/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","fba-inventory",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"fnsku\": \"X001ABC123\",\n    \"asin\": \"B08XYZ1234\",\n    \"sellable_quantity\": 250,\n    \"unsellable_quantity\": 5\n  }\n}"}]},{"name":"Show Ledger Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledger-summaries/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledger-summaries",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a specific ledger summary record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledger-summaries/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledger-summaries",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"date\": \"2024-06-01\",\n    \"fnsku\": \"X001ABC123\",\n    \"starting_warehouse_balance\": 200,\n    \"ending_warehouse_balance\": 250,\n    \"receipts\": 60,\n    \"customer_shipments\": 10\n  }\n}"}]},{"name":"Get Customer Return (Per Instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledgers/customer-returns/{customer_return}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledgers","customer-returns",":customer_return"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"customer_return","value":"5121","description":"Customer return record ID"}]},"description":"Get a single FBA customer return report row by ID. Rows are imported from the Amazon FBA customer returns report and describe one returned unit event: order_id, sku, asin, fnsku, product_name, quantity, fulfillment_center_id, detailed_disposition (e.g. SELLABLE, CUSTOMER_DAMAGED), reason, status, license_plate_number, customer_comments, plus review metadata (reviewed_at) and the return timestamps (return_date, event_datetime) in UTC ISO 8601 format.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nlinked_sales_order is populated on the list endpoints (where matching sales orders are resolved in bulk) and is null on this detail endpoint. Returns 404 for an unknown ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledgers/customer-returns/{customer_return}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledgers","customer-returns",":customer_return"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"customer_return","value":"5121","description":"Customer return record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5121,\n    \"event_datetime\": \"2026-05-14T10:22:00.000000Z\",\n    \"order_id\": \"113-9184620-7712345\",\n    \"sku\": \"LS-RAZOR-BLK\",\n    \"asin\": \"B08K4F9TXQ\",\n    \"fnsku\": \"X002ABCDE1\",\n    \"product_name\": \"Leaf Razor, Black\",\n    \"quantity\": 1,\n    \"fulfillment_center_id\": \"PHX7\",\n    \"detailed_disposition\": \"SELLABLE\",\n    \"reason\": \"NO_REASON_GIVEN\",\n    \"status\": \"Unit returned to inventory\",\n    \"license_plate_number\": \"LPNRR902184713\",\n    \"customer_comments\": null,\n    \"reviewed_at\": null,\n    \"linked_sales_order\": null,\n    \"integration_instance_id\": 1,\n    \"return_date\": \"2026-05-14T10:22:00.000000Z\",\n    \"created_at\": \"2026-05-15T02:10:11.000000Z\",\n    \"updated_at\": \"2026-05-15T02:10:11.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get FBA Shipment Record (Per Instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledgers/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledgers","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"shipment","value":"90233","description":"FBA shipment report record ID"}]},"description":"Get a single Amazon-fulfilled shipment report row by ID. Rows are imported from the Amazon fulfilled shipments report and describe one shipped order item: Amazon order/item identifiers, purchase, payment, shipment and reporting timestamps (UTC ISO 8601), buyer and recipient details, ship-to and bill-to addresses, item/shipping/gift-wrap prices and taxes, promotion discounts, carrier and tracking number, fulfillment center, fulfillment channel and sales channel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 404 for an unknown ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/ledgers/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","ledgers","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"shipment","value":"90233","description":"FBA shipment report record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 90233,\n    \"amazon_order_id\": \"249-1234567-1234567\",\n    \"merchant_order_id\": null,\n    \"shipment_id\": \"DkNqXvmZN\",\n    \"shipment_item_id\": \"DwLnkWvZR\",\n    \"amazon_order_item_id\": \"68812291234567\",\n    \"merchant_order_item_id\": null,\n    \"purchase_date\": \"2026-05-12T18:03:41.000000Z\",\n    \"payments_date\": \"2026-05-12T18:03:41.000000Z\",\n    \"shipment_date\": \"2026-05-13T09:44:02.000000Z\",\n    \"reporting_date\": \"2026-05-13T11:02:55.000000Z\",\n    \"event_datetime\": \"2026-05-13T09:44:02.000000Z\",\n    \"buyer_name\": \"John Carter\",\n    \"buyer_phone_number\": null,\n    \"sku\": \"LS-RAZOR-BLK\",\n    \"product_name\": \"Leaf Razor, Black\",\n    \"quantity_shipped\": 1,\n    \"currency\": \"USD\",\n    \"item_price\": 84,\n    \"item_tax\": 6.93,\n    \"shipping_price\": 0,\n    \"shipping_tax\": 0,\n    \"gift_wrap_price\": 0,\n    \"gift_wrap_tax\": 0,\n    \"ship_service_level\": \"Expedited\",\n    \"recipient_name\": \"John Carter\",\n    \"ship_address_1\": \"410 Terry Ave N\",\n    \"ship_address_2\": null,\n    \"ship_address_3\": null,\n    \"ship_city\": \"Seattle\",\n    \"ship_state\": \"WA\",\n    \"ship_postal_code\": \"98109-5210\",\n    \"ship_country\": \"US\",\n    \"ship_phone_number\": null,\n    \"bill_address_1\": \"410 Terry Ave N\",\n    \"bill_address_2\": null,\n    \"bill_address_3\": null,\n    \"bill_city\": \"Seattle\",\n    \"bill_state\": \"WA\",\n    \"bill_postal_code\": \"98109-5210\",\n    \"bill_country\": \"US\",\n    \"item_promotion_discount\": 0,\n    \"ship_promotion_discount\": 0,\n    \"carrier\": \"AMZN_US\",\n    \"tracking_number\": \"TBA312845067201\",\n    \"estimated_arrival_date\": \"2026-05-16T03:00:00.000000Z\",\n    \"fulfillment_center_id\": \"SMF3\",\n    \"fulfillment_channel\": \"AFN\",\n    \"sales_channel\": \"Amazon.com\",\n    \"created_at\": \"2026-05-14T02:31:44.000000Z\",\n    \"updated_at\": \"2026-05-14T02:31:44.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Restock Report Row (Per Instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/restock-report/{restock_report}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","restock-report",":restock_report"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"restock_report","value":"3311","description":"Restock report row ID"}]},"description":"Get a single row of the Amazon restock inventory recommendations report by ID. Each row is one FNSKU/marketplace combination with Amazon's replenishment guidance: identification (fnsku, merchant_sku, asin, product_name, condition, country), pricing and sales velocity (price, sales_last_30_days, units_sold_last_30_days), current inventory position (total_units, inbound, available, fc_transfer, fc_processing, customer_order, unfulfillable, working, shipped, receiving), days of supply, alerts, and Amazon's recommended_replenishment_qty and recommended_ship_date (Y-m-d).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\namazon_product is a cross-link to the matching Amazon product; it is resolved on the list endpoint and null here when no product matches the row's merchant SKU. json_object holds the raw report row as imported. Returns 404 for an unknown ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/restock-report/{restock_report}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","restock-report",":restock_report"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"restock_report","value":"3311","description":"Restock report row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3311,\n    \"integration_instance_id\": 1,\n    \"amazon_product\": null,\n    \"checksum\": \"b1946ac92492d2347c6235b4d2611184\",\n    \"amazon_report_id\": 512,\n    \"country\": \"US\",\n    \"product_name\": \"Leaf Razor, Black\",\n    \"fnsku\": \"X002ABCDE1\",\n    \"merchant_sku\": \"LS-RAZOR-BLK\",\n    \"asin\": \"B08K4F9TXQ\",\n    \"condition\": \"New\",\n    \"supplier\": null,\n    \"supplier_part_no\": null,\n    \"currency_code\": \"USD\",\n    \"fulfilled_by\": null,\n    \"total_days_of_supply\": \"45\",\n    \"days_of_supply_at_amazon_fulfillment_network\": \"38\",\n    \"alert\": null,\n    \"json_object\": {\n      \"country\": \"US\",\n      \"product_name\": \"Leaf Razor, Black\",\n      \"fnsku\": \"X002ABCDE1\",\n      \"merchant_sku\": \"LS-RAZOR-BLK\",\n      \"asin\": \"B08K4F9TXQ\",\n      \"condition\": \"New\",\n      \"price\": \"84.00\",\n      \"available\": \"119\",\n      \"recommended_replenishment_qty\": \"150\",\n      \"recommended_ship_date\": \"2026-07-21\"\n    },\n    \"created_at\": \"2026-07-01T06:12:30.000000Z\",\n    \"updated_at\": \"2026-07-01T06:12:30.000000Z\",\n    \"working\": 0,\n    \"shipped\": 24,\n    \"receiving\": 0,\n    \"recommended_replenishment_qty\": 150,\n    \"recommended_ship_date\": \"2026-07-21\",\n    \"price\": 84,\n    \"sales_last_30_days\": 2520,\n    \"units_sold_last_30_days\": 30,\n    \"total_units\": 143,\n    \"inbound\": 24,\n    \"available\": 119,\n    \"fc_transfer\": 0,\n    \"fc_processing\": 0,\n    \"customer_order\": 0,\n    \"unfulfillable\": 0\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Show Settlement Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a specific settlement data record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"settlement_id\": \"12345678\",\n    \"total_amount\": 5432.1,\n    \"currency\": \"USD\"\n  }\n}"}]},{"name":"Get Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get settlement type mappings for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings?page=1&per_page=20","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"transaction_type\": \"Order\",\n      \"amount_type\": \"Principal\",\n      \"financial_code\": \"revenue\",\n      \"nominal_code_id\": 10\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 85\n}"}]},{"name":"Map Settlement Types","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Update settlement type mappings (maps transaction types to nominal codes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"id\": 1,\n      \"nominal_code_id\": 10,\n      \"amazon_settlement_mapping_group_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Settlement type mappings updated successfully\"\n}"}]},{"name":"Get Type Mapping Lookups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/lookups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","lookups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get lookup data (nominal codes, mapping groups) for the settlement type mapping form.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/lookups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","lookups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"nominal_codes\": [\n    {\n      \"id\": 10,\n      \"code\": \"4000\",\n      \"name\": \"Sales Revenue\"\n    }\n  ],\n  \"mapping_groups\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard Group\"\n    }\n  ]\n}"}]},{"name":"Bulk Assign Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk assign a nominal code or mapping group to multiple settlement type mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"nominal_code_id\": 10,\n  \"amazon_settlement_mapping_group_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3\n  },\n  \"message\": \"3 type mapping(s) updated successfully.\"\n}"}]},{"name":"Import Settlement Types","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Import settlement type mappings from a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import completed\",\n  \"data\": {\n    \"imported\": 42\n  }\n}"}]},{"name":"Export Settlement Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","export"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Export settlement type mappings as CSV/Excel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-data/type-mappings/export","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-data","type-mappings","export"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary file content)"}]},{"name":"Get Fallback Settings (Per Instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-finance-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get fallback finance settings (default nominal codes) for an Amazon integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-finance-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fallback_revenue_nominal_code_id\": 10,\n  \"fallback_expense_nominal_code_id\": 20,\n  \"landed_cost_bill_mode\": \"auto_create\",\n  \"landed_cost_proration_strategy\": \"cost_based\"\n}"}]},{"name":"Update Fallback Settings (Per Instance)","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-finance-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Update fallback finance settings for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nfields:\n- fallback_revenue_nominal_code_id: nullable int\n- fallback_expense_nominal_code_id: nullable int\n- landed_cost_bill_mode: auto_create | manual\n- landed_cost_proration_strategy: cost_based | equal","body":{"mode":"raw","raw":"{\n  \"fallback_revenue_nominal_code_id\": 10,\n  \"fallback_expense_nominal_code_id\": 20,\n  \"landed_cost_bill_mode\": \"auto_create\",\n  \"landed_cost_proration_strategy\": \"cost_based\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-finance-settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fallback settings updated successfully.\"\n}"}]},{"name":"List Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List settlement mapping groups for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"FBA Fees\",\n      \"position\": 1,\n      \"nominal_code_id\": 20\n    }\n  ]\n}"}]},{"name":"Create Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Create a new settlement mapping group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"FBA Fees\",\n  \"nominal_code_id\": 20\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"FBA Fees\",\n    \"position\": 3,\n    \"nominal_code_id\": 20\n  }\n}"}]},{"name":"Update Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"settlementMappingGroup","value":"1","description":"The settlement mapping group ID."}]},"description":"Update a settlement mapping group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Group Name\",\n  \"nominal_code_id\": 21\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"settlementMappingGroup","value":"1","description":"The settlement mapping group ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Group Name\"\n  }\n}"}]},{"name":"Delete Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"settlementMappingGroup","value":"1","description":"The settlement mapping group ID."}]},"description":"Delete a settlement mapping group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"settlementMappingGroup","value":"1","description":"The settlement mapping group ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping group deleted successfully\"\n}"}]},{"name":"Reorder Mapping Groups","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reorder settlement mapping groups by providing an ordered list of IDs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/settlement-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","settlement-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping groups reordered successfully\"\n}"}]},{"name":"Show AWD Ledger","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Get a specific AWD ledger entry.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"date\": \"2024-03-01\",\n    \"event_type\": \"RECEIPT\",\n    \"quantity\": 100,\n    \"sku\": \"WIDGET-RED\"\n  }\n}"}]},{"name":"Import AWD Ledger","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Import AWD ledger data from a CSV file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/import","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD ledger imported successfully\",\n  \"data\": {\n    \"imported\": 250\n  }\n}"}]},{"name":"Reconcile All AWD Ledgers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","reconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reconcile all unreconciled AWD ledger entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","reconcile-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All AWD ledgers reconciled\",\n  \"data\": {\n    \"reconciled\": 48\n  }\n}"}]},{"name":"Reconcile AWD Ledgers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Reconcile specific AWD ledger entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/reconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Ledgers reconciled\",\n  \"data\": {\n    \"reconciled\": 3\n  }\n}"}]},{"name":"Unreconcile AWD Ledgers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unreconcile specific AWD ledger entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","unreconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Ledgers unreconciled\",\n  \"data\": {\n    \"unreconciled\": 3\n  }\n}"}]},{"name":"Delete AWD Ledgers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Delete specific AWD ledger entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD ledgers deleted\"\n}"}]},{"name":"Get Linkable Sales Order Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/linkable-sales-order-lines","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","linkable-sales-order-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Get sales order lines that can be linked to an AWD ledger entry.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/linkable-sales-order-lines","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","linkable-sales-order-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"sales_order_number\": \"SO-2024-001\",\n      \"sku\": \"WIDGET-RED\",\n      \"quantity\": 100\n    }\n  ]\n}"}]},{"name":"Link to Sales Order Line","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/link-sales-order-line","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","link-sales-order-line"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Link an AWD ledger entry to a sales order line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"sales_order_line_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/link-sales-order-line","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","link-sales-order-line"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Linked to sales order line successfully\"\n}"}]},{"name":"Unlink from Sales Order Line","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/unlink-sales-order-line","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","unlink-sales-order-line"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Unlink an AWD ledger entry from its sales order line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/unlink-sales-order-line","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","unlink-sales-order-line"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unlinked from sales order line successfully\"\n}"}]},{"name":"Get Linkable Ledgers for Sales Order Line","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/linkable-for-sales-order-line/{salesOrderLineId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","linkable-for-sales-order-line",":salesOrderLineId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderLineId","value":"5","description":"The sales order line ID."}]},"description":"Get AWD ledger entries that can be linked to a specific sales order line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/linkable-for-sales-order-line/{salesOrderLineId}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers","linkable-for-sales-order-line",":salesOrderLineId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderLineId","value":"5","description":"The sales order line ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"date\": \"2024-03-01\",\n      \"event_type\": \"RECEIPT\",\n      \"quantity\": 100\n    }\n  ]\n}"}]},{"name":"Get Linkable Destination Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/linkable-destination-warehouses","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","linkable-destination-warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Get warehouses that can serve as transfer destinations for an AWD ledger entry.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/linkable-destination-warehouses","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","linkable-destination-warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Main Warehouse\",\n      \"code\": \"WH-MAIN\"\n    }\n  ]\n}"}]},{"name":"Link to Warehouse Transfer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/link-warehouse-transfer","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","link-warehouse-transfer"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Link an AWD ledger entry to a warehouse transfer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/link-warehouse-transfer","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","link-warehouse-transfer"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Linked to warehouse transfer successfully\"\n}"}]},{"name":"Unlink from Warehouse Transfer","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/unlink-warehouse-transfer","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","unlink-warehouse-transfer"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]},"description":"Unlink an AWD ledger entry from its warehouse transfer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/awd/ledgers/{awdLedger}/unlink-warehouse-transfer","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","awd","ledgers",":awdLedger","unlink-warehouse-transfer"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"awdLedger","value":"1","description":"The awd ledger ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unlinked from warehouse transfer\"\n}"}]},{"name":"List Nominal Code Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","nominal-code-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List financial event type to nominal code mappings for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","nominal-code-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"financial_event_type\": \"Order\",\n      \"nominal_code_id\": 10,\n      \"nominal_code\": \"4000\"\n    }\n  ]\n}"}]},{"name":"Create Nominal Code Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","nominal-code-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Create a new financial event type to nominal code mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"financial_event_type\": \"Order\",\n  \"nominal_code_id\": 10\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","nominal-code-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"financial_event_type\": \"Order\",\n    \"nominal_code_id\": 10\n  }\n}"}]},{"name":"Get Report Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/get-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports","get-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get report configuration and status information for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/get-info","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports","get-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reports\": [\n      {\n        \"type\": \"GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA\",\n        \"status\": \"enabled\",\n        \"last_synced_at\": \"2024-06-01T10:00:00.000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Sync Report","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/{report}/sync","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports",":report","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"report","value":"1","description":"The report ID."}]},"description":"Trigger a sync for a specific Amazon report.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/{report}/sync","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports",":report","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"report","value":"1","description":"The report ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Report sync started\"\n}"}]},{"name":"Create Report","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/create","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports","create"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Request a new Amazon report.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"report_type\": \"GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA\",\n  \"data_start_time\": \"2024-01-01\",\n  \"data_end_time\": \"2024-01-31\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/reports/create","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","reports","create"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Report creation started\",\n  \"data\": {\n    \"report_id\": \"RPT-12345\"\n  }\n}"}]},{"name":"Get Finance Dashboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/finance-dashboard?integration_instance_ids=&date_from=&date_to=","host":["{{baseUrl}}"],"path":["api","amazon","unified","finance-dashboard"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true},{"key":"date_from","value":"","description":"Start of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"date_to","value":"","description":"End of the date range (see the Dates & Timezones guide for formats).","disabled":true}]},"description":"Get Finance Dashboard\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"New Ledger Bulk COGS Suggestions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-ledgers/bulk-cogs-suggestions","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-ledgers","bulk-cogs-suggestions"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get COGS suggestions for multiple new ledger entries in bulk.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ledger_ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/new-ledgers/bulk-cogs-suggestions","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","new-ledgers","bulk-cogs-suggestions"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"ledger_id\": 1,\n      \"suggested_cogs\": 12.5\n    },\n    {\n      \"ledger_id\": 2,\n      \"suggested_cogs\": 8.75\n    }\n  ]\n}"}]},{"name":"Create Next Report Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/report-requests/create-next","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","report-requests","create-next"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]},"description":"Create the next pending report request for a report type on this integration instance. Computes the next data window — from the last synced data point up to the newest safe end time (Amazon report data is delayed by up to 72 hours depending on report type) — and stores a report request row without calling Amazon yet. Submit it with the Create Report from Request endpoint. If an identical pending request already exists it is returned instead of creating a duplicate. Report types with long windows are split into multiple requests; the first created request is returned.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- reportType (string, required) — one of: GET_MERCHANT_LISTINGS_ALL_DATA, GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA, GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL, GET_FBA_FULFILLMENT_REMOVAL_SHIPMENT_DETAIL_DATA, GET_FBA_FULFILLMENT_REMOVAL_ORDER_DETAIL_DATA, GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA, GET_LEDGER_SUMMARY_VIEW_DATA, GET_LEDGER_DETAIL_VIEW_DATA, GET_RESTOCK_INVENTORY_RECOMMENDATIONS_REPORT, GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2, GET_SELLER_FEEDBACK_DATA, GET_FBA_ESTIMATED_FBA_FEES_TXT_DATA, GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE, GET_FBA_REIMBURSEMENTS_DATA, GET_FBA_STORAGE_FEE_CHARGES_DATA, GET_FBA_FULFILLMENT_LONGTERM_STORAGE_FEE_CHARGES_DATA.\n\nReturns the stored report request (dataStartTime/dataEndTime in UTC ISO 8601; options and marketplaceIds are derived from the report type and instance). Fails when another report of the same type is still being processed (settlement and shipment reports excepted; stuck reports older than 4 hours are automatically failed so the request can proceed). Returns 422 for an unknown report type.","body":{"mode":"raw","raw":"{\n  \"reportType\": \"GET_LEDGER_SUMMARY_VIEW_DATA\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/report-requests/create-next","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","report-requests","create-next"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"reportType\": \"GET_LEDGER_SUMMARY_VIEW_DATA\",\n    \"dataStartTime\": \"2026-06-01T00:00:00.000000Z\",\n    \"dataEndTime\": \"2026-07-05T14:02:11.000000Z\",\n    \"options\": {\n      \"aggregatedByTimePeriod\": \"DAILY\"\n    },\n    \"marketplaceIds\": [\n      \"ATVPDKIKX0DER\"\n    ],\n    \"disallow_duplicates\": false,\n    \"updated_at\": \"2026-07-06T14:02:11.000000Z\",\n    \"created_at\": \"2026-07-06T14:02:11.000000Z\",\n    \"id\": 291\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Create Report from Request","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/report-requests/{reportRequest}/create-report","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","report-requests",":reportRequest","create-report"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"reportRequest","value":"291","description":"Report request ID (from Create Next Report Request)"}]},"description":"Submit a stored report request to Amazon, creating the actual report. Calls the Amazon Selling Partner API to create a report for the request's type, data window, options and marketplaces, stores the resulting report record with its Amazon report id, and deletes the report request. The report's processing status is subsequently updated by the scheduled report sync, and its rows are imported once Amazon finishes generating it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Fails when an existing non-failed report already overlaps the requested data range, unless the request was created with overlapping pulls permitted (in which case row-level checksum de-duplication applies on import). Returns 404 for an unknown report request ID."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/report-requests/{reportRequest}/create-report","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","report-requests",":reportRequest","create-report"],"variable":[{"key":"integrationInstance","value":"1","description":"Amazon integration instance ID"},{"key":"reportRequest","value":"291","description":"Report request ID (from Create Next Report Request)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reportId\": \"1468239482093\",\n    \"integration_instance_id\": 1,\n    \"reportType\": \"GET_LEDGER_SUMMARY_VIEW_DATA\",\n    \"dataStartTime\": \"2026-06-01T00:00:00.000000Z\",\n    \"dataEndTime\": \"2026-07-05T14:02:11.000000Z\",\n    \"options\": {\n      \"aggregatedByTimePeriod\": \"DAILY\"\n    },\n    \"marketplaceIds\": [\n      \"ATVPDKIKX0DER\"\n    ],\n    \"disallow_duplicates\": false,\n    \"updated_at\": \"2026-07-06T14:05:40.000000Z\",\n    \"created_at\": \"2026-07-06T14:05:40.000000Z\",\n    \"id\": 6021\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Show Financial Event Group","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/event-groups/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","event-groups",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a specific financial event group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/finances/event-groups/{id}","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","finances","event-groups",":id"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"financial_event_group_id\": \"FEG-123\",\n    \"processing_status\": \"Closed\"\n  }\n}"}]},{"name":"List FNSKU Products (paginated, with reconciliation data)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products"]},"description":"Returns a paginated list of FNSKU products across all integration instances, enriched with per-record reconciliation_data (total_ledgers, reconciled_ledgers, reconciliation_percentage, initial_inventory_reconciled, unreconciled_discrepancies_count, reconciliation_status).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fnskuProduct\": {\n        \"id\": 101,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"US\",\n        \"disposition\": \"SELLABLE\",\n        \"initial_unit_cost\": 4.25\n      },\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US (Production)\"\n      },\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"SKU-123\",\n        \"name\": \"Widget\"\n      },\n      \"reconciliation_data\": {\n        \"total_ledgers\": 120,\n        \"reconciled_ledgers\": 118,\n        \"reconciliation_percentage\": 98,\n        \"initial_inventory_reconciled\": true,\n        \"unreconciled_discrepancies_count\": 0,\n        \"reconciliation_status\": \"fully_reconciled\"\n      },\n      \"initial_inventory_fifo_layer_id\": 5512,\n      \"created_at\": \"2026-01-15T10:24:00.000000Z\",\n      \"updated_at\": \"2026-05-01T08:15:00.000000Z\",\n      \"last_reconciled\": \"2026-05-01T08:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 7,\n  \"per_page\": 15,\n  \"total\": 102,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fnsku-products?page=1\",\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fnsku-products?page=7\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fnsku-products?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products\",\n  \"links\": []\n}"}]},{"name":"Show FNSKU Product Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId"],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]},"description":"Returns detail payload for a single FNSKU product (including reconciliation_data, initial_fba_inventory, inventory_summary, related_counts).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId"],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fnskuProduct\": {\n      \"id\": 101,\n      \"fnsku\": \"X001ABCDEF\",\n      \"location\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"created_at\": \"2026-01-15T10:24:00.000000Z\",\n      \"updated_at\": \"2026-05-01T08:15:00.000000Z\"\n    },\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"Amazon US (Production)\"\n    },\n    \"product\": {\n      \"id\": 9001,\n      \"sku\": \"SKU-123\",\n      \"name\": \"Widget\"\n    },\n    \"reconciliation_data\": {\n      \"total_ledgers\": 120,\n      \"reconciled_ledgers\": 118,\n      \"reconciliation_percentage\": 98,\n      \"initial_inventory_reconciled\": true,\n      \"unreconciled_discrepancies_count\": 0,\n      \"reconciliation_status\": \"fully_reconciled\"\n    },\n    \"initial_fba_inventory\": {\n      \"id\": 555,\n      \"date\": \"2026-01-01\",\n      \"ending_inventory\": 250,\n      \"total_inventory\": 260,\n      \"in_transit_between_warehouses\": 10,\n      \"disposition\": \"SELLABLE\",\n      \"location\": \"US\",\n      \"reconciled_at\": \"2026-05-01T08:15:00.000000Z\",\n      \"fifo_layer\": {\n        \"id\": 5512,\n        \"cogs\": 4.25,\n        \"cogs_source\": \"product_unit_cost\"\n      }\n    },\n    \"inventory_summary\": {\n      \"last_reconciled_date\": \"2026-05-01T08:15:00.000000Z\",\n      \"pending_ledgers_count\": 2\n    },\n    \"default_as_of_date\": \"2026-05-15\",\n    \"related_counts\": {\n      \"discrepancies\": 1,\n      \"ledgers\": 120,\n      \"summary_ledgers\": 30,\n      \"removal_orders\": 2,\n      \"removal_shipments\": 2\n    }\n  },\n  \"message\": \"Success\"\n}"}]},{"name":"Get ASIN mapping statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","stats"]},"description":"Returns aggregate counts of mapped vs unmapped FNSKUs and ASIN groups.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_fnsku_count\": 320,\n    \"unmapped_fnsku_count\": 47,\n    \"total_fnsku_count\": 367,\n    \"mapped_asin_count\": 210,\n    \"unmapped_asin_count\": 22,\n    \"total_asin_count\": 232\n  },\n  \"message\": \"Success\"\n}"}]},{"name":"Search FNSKU products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/search?fnsku=X001","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","search"],"query":[{"key":"fnsku","value":"X001","description":"Required. Partial FNSKU string to search by (min 1 char)","disabled":true}]},"description":"Lightweight FNSKU search (up to 50 results), used for manual discrepancy creation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/search?fnsku=X001","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","search"],"query":[{"key":"fnsku","value":"X001","description":"Required. Partial FNSKU string to search by (min 1 char)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"results\": [\n      {\n        \"id\": 101,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"US\",\n        \"disposition\": \"SELLABLE\",\n        \"integration_instance\": {\n          \"id\": 1,\n          \"name\": \"Amazon US (Production)\"\n        },\n        \"product\": {\n          \"id\": 9001,\n          \"sku\": \"SKU-123\",\n          \"name\": \"Widget\"\n        },\n        \"initial_unit_cost\": 4.25\n      }\n    ],\n    \"total\": 1\n  }\n}"}]},{"name":"List Unmapped FNSKU Products (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unmapped","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unmapped"]},"description":"Paginated list of FNSKU products that are not yet mapped to a product. Uses unified Amazon FNSKU product mapper object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unmapped","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unmapped"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 542,\n      \"fnsku\": \"X001UNMAPPED\",\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US (Production)\",\n      \"location\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"product\": null,\n      \"matches\": [\n        {\n          \"asin\": \"B0123ABCDE\",\n          \"msku\": null,\n          \"title\": null\n        }\n      ],\n      \"created_at\": \"2026-03-01T10:00:00.000000Z\",\n      \"updated_at\": \"2026-03-01T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/unmapped?page=1\",\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/unmapped?page=4\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/unmapped?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products/unmapped\",\n  \"links\": []\n}"}]},{"name":"List Mapped FNSKU Products (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/mapped","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","mapped"]},"description":"Paginated list of FNSKU products already mapped to a product. Uses unified Amazon FNSKU product mapper object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/mapped","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","mapped"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"fnsku\": \"X001ABCDEF\",\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US (Production)\",\n      \"location\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"SKU-123\",\n        \"name\": \"Widget\"\n      },\n      \"matches\": [\n        {\n          \"asin\": \"B0123ABCDE\",\n          \"msku\": null,\n          \"title\": null\n        }\n      ],\n      \"created_at\": \"2026-01-15T10:24:00.000000Z\",\n      \"updated_at\": \"2026-05-01T08:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 22,\n  \"per_page\": 15,\n  \"total\": 320,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/mapped?page=1\",\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/mapped?page=22\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fnsku-products/mapped?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products/mapped\",\n  \"links\": []\n}"}]},{"name":"List Unmapped FNSKUs Grouped by ASIN","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unmapped-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unmapped-by-asin"]},"description":"FNSKUs grouped by ASIN where at least one FNSKU is unmapped. Includes FNSKUs without ASINs grouped as 'No ASIN'.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unmapped-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unmapped-by-asin"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"asin\": \"B0123ABCDE\",\n      \"msku\": \"SELLER-SKU-A\",\n      \"title\": \"Widget Black\",\n      \"total_fnskus\": 3,\n      \"total_instances\": 2,\n      \"mapped_product\": null,\n      \"mapping_status\": \"unmapped\",\n      \"fnsku_records\": [\n        {\n          \"id\": 542,\n          \"fnsku\": \"X001UNMAPPED\",\n          \"integration_instance_id\": 1,\n          \"integration_instance_name\": \"Amazon US (Production)\",\n          \"product_id\": null,\n          \"product\": null,\n          \"location\": \"US\",\n          \"disposition\": \"SELLABLE\"\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 22,\n  \"from\": 1,\n  \"to\": 15,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products/unmapped-by-asin\",\n  \"links\": []\n}"}]},{"name":"List Mapped FNSKUs Grouped by ASIN","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/mapped-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","mapped-by-asin"]},"description":"FNSKUs grouped by ASIN where at least one FNSKU is mapped. mapping_status is 'mapped' or 'partially_mapped'.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/mapped-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","mapped-by-asin"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"asin\": \"B0987FGHIJ\",\n      \"msku\": \"SELLER-SKU-B\",\n      \"title\": \"Widget Red\",\n      \"total_fnskus\": 4,\n      \"total_instances\": 2,\n      \"mapped_product\": {\n        \"id\": 9001,\n        \"sku\": \"SKU-123\",\n        \"name\": \"Widget\"\n      },\n      \"mapping_status\": \"mapped\",\n      \"fnsku_records\": [\n        {\n          \"id\": 101,\n          \"fnsku\": \"X001ABCDEF\",\n          \"integration_instance_id\": 1,\n          \"integration_instance_name\": \"Amazon US (Production)\",\n          \"product_id\": 9001,\n          \"product\": {\n            \"id\": 9001,\n            \"sku\": \"SKU-123\",\n            \"name\": \"Widget\"\n          },\n          \"location\": \"US\",\n          \"disposition\": \"SELLABLE\"\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 14,\n  \"per_page\": 15,\n  \"total\": 210,\n  \"from\": 1,\n  \"to\": 15,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products/mapped-by-asin\",\n  \"links\": []\n}"}]},{"name":"Export FNSKU Products (unpaginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","export"]},"description":"Returns ALL FNSKU products with reconciliation data (forces per_page=10000). Same filters as the paginated index.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fnskuProduct\": {\n        \"id\": 101,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"US\",\n        \"disposition\": \"SELLABLE\",\n        \"initial_unit_cost\": 4.25\n      },\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US (Production)\"\n      },\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"SKU-123\",\n        \"name\": \"Widget\"\n      },\n      \"reconciliation_data\": {\n        \"total_ledgers\": 120,\n        \"reconciled_ledgers\": 118,\n        \"reconciliation_percentage\": 98,\n        \"initial_inventory_reconciled\": true,\n        \"unreconciled_discrepancies_count\": 0,\n        \"reconciliation_status\": \"fully_reconciled\"\n      },\n      \"initial_inventory_fifo_layer_id\": 5512,\n      \"created_at\": \"2026-01-15T10:24:00.000000Z\",\n      \"updated_at\": \"2026-05-01T08:15:00.000000Z\",\n      \"last_reconciled\": \"2026-05-01T08:15:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Auto-Mapping Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","activity-log"]},"description":"Paginated activity log of FNSKU auto-mapping events across all integrations.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","activity-log"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8821,\n      \"integration_instance_id\": 1,\n      \"amazon_fnsku_product_id\": 101,\n      \"product_id\": 9001,\n      \"matched_from_fnsku_id\": 99,\n      \"asin\": \"B0123ABCDE\",\n      \"mapping_type\": \"auto\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US (Production)\"\n      },\n      \"amazon_fnsku_product\": {\n        \"id\": 101,\n        \"fnsku\": \"X001ABCDEF\"\n      },\n      \"product\": {\n        \"id\": 9001,\n        \"sku\": \"SKU-123\",\n        \"name\": \"Widget\"\n      },\n      \"matched_from_fnsku\": {\n        \"id\": 99,\n        \"fnsku\": \"X001ORIGREF\"\n      },\n      \"created_at\": \"2026-05-12T13:45:00.000000Z\",\n      \"updated_at\": \"2026-05-12T13:45:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10,\n  \"path\": \"https://example.test/api/amazon/unified/fnsku-products/activity-log\",\n  \"links\": []\n}"}]},{"name":"FNSKU Discrepancies (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProduct}/discrepancies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProduct","discrepancies"],"variable":[{"key":"fnskuProduct","value":"","description":"The fnskuProduct identifier"}]},"description":"Paginated discrepancies for an FNSKU product (route-model-bound by id). Adds computed `status` field (reconciled|unreconciled).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProduct}/discrepancies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProduct","discrepancies"],"variable":[{"key":"fnskuProduct","value":"","description":"The fnskuProduct identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9111,\n      \"amazon_fnsku_product_id\": 101,\n      \"reason_type\": \"ledger_summary_mismatch\",\n      \"discrepancy_date\": \"2026-04-10\",\n      \"quantity\": 5,\n      \"reconciled_at\": null,\n      \"status\": \"unreconciled\",\n      \"created_at\": \"2026-04-10T12:00:00.000000Z\",\n      \"updated_at\": \"2026-04-10T12:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"FNSKU Ledgers (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProduct}/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProduct","ledgers"],"variable":[{"key":"fnskuProduct","value":"","description":"The fnskuProduct identifier"}]},"description":"Paginated FBA ledger entries for an FNSKU product, formatted via unified Amazon FNSKU product ledger object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProduct}/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProduct","ledgers"],"variable":[{"key":"fnskuProduct","value":"","description":"The fnskuProduct identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 70011,\n      \"amazon_fnsku_product_id\": 101,\n      \"event_type\": \"Receipts\",\n      \"event_datetime\": \"2026-02-01T10:00:00.000000Z\",\n      \"quantity\": 100,\n      \"asin\": \"B0123ABCDE\",\n      \"msku\": \"SELLER-SKU-A\",\n      \"title\": \"Widget Black\",\n      \"reconciled_at\": \"2026-02-02T08:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 8,\n  \"per_page\": 15,\n  \"total\": 120\n}"}]},{"name":"Inventory Tally Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}/inventory-tally-summary?as_of_date=2026-05-01","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId","inventory-tally-summary"],"query":[{"key":"as_of_date","value":"2026-05-01","description":"Required. Y-m-d format. Must not exceed the latest summary report date.","disabled":true}],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]},"description":"Computes ledger vs summary inventory variance for a specific as-of date, with event-type and discrepancy reason breakdowns.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}/inventory-tally-summary?as_of_date=2026-05-01","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId","inventory-tally-summary"],"query":[{"key":"as_of_date","value":"2026-05-01","description":"Required. Y-m-d format. Must not exceed the latest summary report date.","disabled":true}],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"as_of_date\": \"2026-05-01\",\n    \"initial_inventory\": {\n      \"date\": \"2026-01-01\",\n      \"quantity\": 250\n    },\n    \"summary_warehouse_inventory\": 245,\n    \"summary_in_transit\": 10,\n    \"ledger_current\": 250,\n    \"discrepancies_reconciled\": 0,\n    \"discrepancies_unreconciled\": 1,\n    \"variance\": {\n      \"quantity\": 5,\n      \"percentage\": 2\n    },\n    \"reconciliation_status\": {\n      \"percentage\": 98,\n      \"last_reconciled\": \"2026-05-01T08:15:00.000000Z\",\n      \"unreconciled_ledgers\": 2\n    },\n    \"event_types_summary\": {\n      \"Receipts\": 100,\n      \"Customer Shipments\": -90,\n      \"Customer Returns\": 5,\n      \"Vendor Returns\": 0,\n      \"Warehouse Transfer In Out\": 0,\n      \"Adjustments\": {\n        \"Found\": 0,\n        \"Lost\": 0,\n        \"Damaged\": 0,\n        \"Disposed\": 0,\n        \"Other Events\": 0\n      },\n      \"Unknown Events\": 0\n    },\n    \"event_types_ledger\": {\n      \"Receipts\": 100,\n      \"Shipments\": -90,\n      \"Customer Returns\": 5\n    },\n    \"discrepancy_reasons\": {\n      \"Ledger Summary Mismatch\": 0\n    }\n  },\n  \"message\": \"Success\"\n}"}]},{"name":"Map Single FNSKU to a Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/map-single-fnsku","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","map-single-fnsku"]},"description":"Map a single FNSKU product to a product. Pass product_id=null to unmap (also triggers unreconciliation). When linking, dispatches a tracked reconciliation job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_id\": 101,\n  \"product_id\": 9001\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/map-single-fnsku","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","map-single-fnsku"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fnsku_product_id\": 101,\n    \"product_id\": 9001,\n    \"tracked_job_log_id\": 4521\n  },\n  \"message\": \"Mapped FNSKU product 101 to product ID 9001\"\n}"}]},{"name":"Map all FNSKUs for an ASIN to a Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/map-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","map-by-asin"]},"description":"Map every FNSKU with the given ASIN to a product. Pass product_id=null to unmap.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"asin\": \"B0123ABCDE\",\n  \"product_id\": 9001,\n  \"integration_instance_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/map-by-asin","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","map-by-asin"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_count\": 3\n  },\n  \"message\": \"Mapped 3 FNSKU products with ASIN B0123ABCDE to product ID 9001\"\n}"}]},{"name":"Bulk Reconcile","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-reconcile"]},"description":"Dispatch bulk reconciliation for the given FNSKU product IDs, or for all IDs matching `filters` when `apply_to_all=true`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\",\n    \"reconciliation_status\": \"needs_attention\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-reconcile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 3,\n    \"dispatched\": 3\n  },\n  \"message\": \"Bulk reconciliation dispatched: 3 FNSKU products\"\n}"}]},{"name":"Bulk Unreconcile","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-unreconcile"]},"description":"Dispatch bulk unreconciliation for the given FNSKU product IDs, or for all IDs matching `filters` when `apply_to_all=true`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-unreconcile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 3,\n    \"dispatched\": 3\n  },\n  \"message\": \"Bulk unreconciliation dispatched: 3 FNSKU products\"\n}"}]},{"name":"Reconcile All (tracked job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","reconcile-all"]},"description":"Dispatches a tracked a background job. Returns the tracked_job_log_id so the frontend can monitor progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/reconcile-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","reconcile-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4523\n  },\n  \"message\": \"Reconciliation job started\"\n}"}]},{"name":"Bulk Link (to single product)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-link","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-link"]},"description":"Link the given FNSKU products to a single product (or all filtered IDs when apply_to_all=true). Dispatches a tracked reconciliation job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\"\n  },\n  \"product_id\": 9001\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-link","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-link"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"linked\": 3,\n    \"tracked_job_log_id\": 4522\n  },\n  \"message\": \"Linked 3 FNSKU product(s) to product ID 9001\"\n}"}]},{"name":"Update Initial Unit Cost (single)","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}/initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId","initial-unit-cost"],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]},"description":"Update the initial unit cost for a single FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"initial_unit_cost\": 4.25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{fnskuProductId}/initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":fnskuProductId","initial-unit-cost"],"variable":[{"key":"fnskuProductId","value":"","description":"The fnskuProductId identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fnsku_product_id\": 101,\n    \"initial_unit_cost\": 4.25\n  },\n  \"message\": \"Initial unit cost updated successfully\"\n}"}]},{"name":"Update Auto-Mapping Settings (Bulk)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","auto-mapping-settings"]},"description":"Bulk update FNSKU auto-mapping settings across multiple integration instances. Provide `ids` (array of integration instance IDs) and `is_fnsku_auto_mapping_enabled` (boolean). Email and in-app alerts for unmapped FNSKUs are configured separately via alert notification preferences.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"is_fnsku_auto_mapping_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/auto-mapping-settings","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","auto-mapping-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"message\": \"Successfully updated auto-mapping settings for 3 integration instances\",\n  \"data\": {\n    \"updated_count\": 3\n  }\n}"}]},{"name":"Complete Partial Mapping (by ASIN)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/complete-partial-mapping","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","complete-partial-mapping"]},"description":"For an ASIN that has some FNSKUs mapped and some unmapped, link the unmapped ones to the most-common existing product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"asin\": \"B0987FGHIJ\",\n  \"integration_instance_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/complete-partial-mapping","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","complete-partial-mapping"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_count\": 2,\n    \"product_id\": 9001\n  },\n  \"message\": \"Completed partial mapping: mapped 2 FNSKU products with ASIN B0987FGHIJ to product ID 9001\"\n}"}]},{"name":"FNSKU Summary Ledgers (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/summary-ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","summary-ledgers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated FBA inventory ledger summary rows for an FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/summary-ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","summary-ledgers"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 31001,\n      \"date\": \"2026-05-01\",\n      \"fnsku\": \"X001ABCDEF\",\n      \"asin\": \"B0123ABCDE\",\n      \"msku\": \"SELLER-SKU-A\",\n      \"location\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"ending_warehouse_balance\": 245,\n      \"in_transit_between_warehouses\": 10,\n      \"receipts\": 50,\n      \"customer_shipments\": -45,\n      \"customer_returns\": 5,\n      \"vendor_returns\": 0,\n      \"warehouse_transfer_in_out\": 0,\n      \"found\": 0,\n      \"lost\": 0,\n      \"damaged\": 0,\n      \"disposed\": 0,\n      \"other_events\": 0,\n      \"unknown_events\": 0\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 15,\n  \"total\": 30\n}"}]},{"name":"FNSKU Removal Orders (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/removal-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","removal-orders"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated removal orders associated with an FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/removal-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","removal-orders"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4001,\n      \"order_id\": \"REM-2026-0001\",\n      \"order_status\": \"Completed\",\n      \"order_type\": \"Return\",\n      \"requested_quantity\": 25,\n      \"cancelled_quantity\": 0,\n      \"disposed_quantity\": 0,\n      \"shipped_quantity\": 25,\n      \"in_process_quantity\": 0,\n      \"requested_date\": \"2026-04-01\",\n      \"last_updated_date\": \"2026-04-05\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2\n}"}]},{"name":"FNSKU Removal Shipments (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/removal-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","removal-shipments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated removal shipments associated with an FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/removal-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","removal-shipments"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"order_id\": \"REM-2026-0001\",\n      \"shipment_date\": \"2026-04-05T10:00:00.000000Z\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"shipped_quantity\": 25,\n      \"disposition\": \"SELLABLE\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2\n}"}]},{"name":"Reconciliation Timeline (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-timeline","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-timeline"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Chronological reconciliation stream (ledger entries + discrepancies) with running tally, FIFO layer data, and summary balances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-timeline","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-timeline"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"type\": \"ledger\",\n      \"id\": 70011,\n      \"event_datetime\": \"2026-02-01T10:00:00.000000Z\",\n      \"event_type\": \"Receipts\",\n      \"quantity\": 100,\n      \"running_tally\": 100,\n      \"reconciled_at\": \"2026-02-02T08:00:00.000000Z\",\n      \"fifo_layer\": {\n        \"id\": 5512,\n        \"cogs\": 4.25\n      }\n    },\n    {\n      \"type\": \"discrepancy\",\n      \"id\": 9111,\n      \"discrepancy_date\": \"2026-04-10\",\n      \"reason_type\": \"ledger_summary_mismatch\",\n      \"quantity\": 5,\n      \"reconciled_at\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 50,\n  \"total\": 121\n}"}]},{"name":"Reconciliation Sync Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-sync-status","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-sync-status"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Summary statistics about how many entries are reconciled.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-sync-status","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-sync-status"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_ledgers\": 120,\n    \"reconciled_ledgers\": 118,\n    \"unreconciled_ledgers\": 2,\n    \"reconciliation_percentage\": 98,\n    \"last_reconciled_at\": \"2026-05-01T08:15:00.000000Z\",\n    \"unreconciled_discrepancies\": 1\n  }\n}"}]},{"name":"Reconciliation Chart Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-chart-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-chart-data"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Time-series data points for the reconciliation chart for a single FNSKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconciliation-chart-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconciliation-chart-data"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"labels\": [\n      \"2026-01\",\n      \"2026-02\",\n      \"2026-03\",\n      \"2026-04\",\n      \"2026-05\"\n    ],\n    \"datasets\": [\n      {\n        \"label\": \"Ledger Balance\",\n        \"data\": [\n          250,\n          305,\n          280,\n          260,\n          250\n        ]\n      },\n      {\n        \"label\": \"Summary Balance\",\n        \"data\": [\n          250,\n          300,\n          275,\n          255,\n          245\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Unlink","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-unlink","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-unlink"]},"description":"Unlink the given FNSKU products from their products (or all filtered IDs when apply_to_all=true). Each is also auto-unreconciled.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-unlink","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-unlink"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unlinked\": 3\n  },\n  \"message\": \"Unlinked 3 FNSKU product(s)\"\n}"}]},{"name":"Unreconcile All (tracked job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unreconcile-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unreconcile-all"]},"description":"Dispatches a tracked a background job. Returns the tracked_job_log_id for progress monitoring.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/unreconcile-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","unreconcile-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4524\n  },\n  \"message\": \"Unreconciliation job started\"\n}"}]},{"name":"Reconcile Single FNSKU","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconcile"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Synchronously reconcile a single FNSKU product's COGS. Long-running (time limit raised to 300s).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","reconcile"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FNSKU product reconciled successfully\"\n}"}]},{"name":"Unreconcile Single FNSKU","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","unreconcile"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Synchronously unreconcile a single FNSKU product's COGS.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","unreconcile"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"FNSKU product unreconciled successfully\"\n}"}]},{"name":"Bulk Update Initial Unit Cost","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-update-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-update-initial-unit-cost"]},"description":"Apply the same initial unit cost to multiple FNSKU products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"initial_unit_cost\": 4.25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-update-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-update-initial-unit-cost"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated_count\": 3,\n    \"initial_unit_cost\": 4.25\n  },\n  \"message\": \"Updated initial unit cost for 3 FNSKU product(s)\"\n}"}]},{"name":"Suggested Initial Unit Cost (single)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/suggested-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","suggested-initial-unit-cost"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns suggestions for the initial unit cost: from the mapped product's unit_cost and from sibling FNSKUs (same product + same country/location).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/suggested-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","suggested-initial-unit-cost"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_suggestion\": {\n      \"source\": \"product\",\n      \"value\": 4.25,\n      \"product_id\": 9001,\n      \"product_sku\": \"SKU-123\",\n      \"product_name\": \"Widget\"\n    },\n    \"sibling_suggestions\": [\n      {\n        \"source\": \"sibling_fnsku\",\n        \"value\": 4.3,\n        \"fnsku_product_id\": 102,\n        \"fnsku\": \"X001SIBLING\",\n        \"location\": \"US\",\n        \"disposition\": \"SELLABLE\",\n        \"integration_instance_name\": \"Amazon US (Production)\"\n      }\n    ]\n  },\n  \"message\": \"Success\"\n}"}]},{"name":"ASIN Suggestion (single)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/asin-suggestion","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","asin-suggestion"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Looks up the ASIN/MSKU/title for the given FNSKU and checks if another FNSKU with the same ASIN is already mapped to a product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/{id}/asin-suggestion","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products",":id","asin-suggestion"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"asin\": \"B0123ABCDE\",\n    \"msku\": \"SELLER-SKU-A\",\n    \"title\": \"Widget Black\",\n    \"suggested_product\": {\n      \"id\": 9001,\n      \"sku\": \"SKU-123\",\n      \"name\": \"Widget\"\n    }\n  },\n  \"message\": \"Success\"\n}"}]},{"name":"Bulk Suggested Initial Unit Cost","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-suggested-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-suggested-initial-unit-cost"]},"description":"Returns per-FNSKU initial unit cost suggestions with pre-computed `recommended_value` and `is_uniform` flags for bulk editing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/bulk-suggested-initial-unit-cost","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","bulk-suggested-initial-unit-cost"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fnsku_product_id\": 101,\n      \"suggestions\": {\n        \"product_suggestion\": {\n          \"source\": \"product\",\n          \"value\": 4.25,\n          \"product_id\": 9001,\n          \"product_sku\": \"SKU-123\",\n          \"product_name\": \"Widget\"\n        },\n        \"sibling_suggestions\": [\n          {\n            \"source\": \"sibling_fnsku\",\n            \"value\": 4.25,\n            \"fnsku_product_id\": 102,\n            \"fnsku\": \"X001SIBLING\",\n            \"location\": \"US\",\n            \"disposition\": \"SELLABLE\",\n            \"integration_instance_name\": \"Amazon US (Production)\"\n          }\n        ]\n      },\n      \"recommended_value\": 4.25,\n      \"all_suggestion_values\": [\n        4.25,\n        4.25\n      ],\n      \"is_uniform\": true\n    }\n  ],\n  \"message\": \"Success\"\n}"}]},{"name":"Create FIFO Layers for Initial Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/create-fifo-layers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","create-fifo-layers"]},"description":"Create FIFO layers for initial inventory. Specific IDs run synchronously; `apply_to_all=true` dispatches a tracked a background job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"fnsku_product_ids\": [\n    101,\n    102,\n    103\n  ],\n  \"apply_to_all\": false,\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\",\n    \"fifo_layer_status\": \"no_fifo_layer\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fnsku-products/create-fifo-layers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fnsku-products","create-fifo-layers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 2,\n    \"skipped\": 1,\n    \"failed\": 0,\n    \"errors\": []\n  },\n  \"message\": \"FIFO layers created: 2, skipped: 1, failed: 0\"\n}"}]},{"name":"List Ledgers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/ledgers?page=1&per_page=10&search=&integration_instance_ids=&date_from=&date_to=&event_type=&status=&sort=-id","host":["{{baseUrl}}"],"path":["api","amazon","unified","ledgers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated IDs","disabled":true},{"key":"date_from","value":"","description":"m/d/Y format","disabled":true},{"key":"date_to","value":"","description":"m/d/Y format","disabled":true},{"key":"event_type","value":"","disabled":true},{"key":"status","value":"","disabled":true},{"key":"sort","value":"-id","description":"Prefix with - for descending","disabled":true}]},"description":"List Ledgers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Ledger","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/ledgers/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","ledgers",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Ledger\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Ledger Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/ledgers/{id}/activity-log?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","amazon","unified","ledgers",":id","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Ledger Activity Log\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Export Ledgers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/ledgers/export?integration_instance_ids=&search=&date_from=&date_to=&event_type=&status=","host":["{{baseUrl}}"],"path":["api","amazon","unified","ledgers","export"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"date_from","value":"","description":"Start of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"date_to","value":"","description":"End of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"event_type","value":"","disabled":true},{"key":"status","value":"","disabled":true}]},"description":"Export Ledgers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List Summary Ledgers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/summary-ledgers?page=1&per_page=10&search=&integration_instance_ids=&date_from=&date_to=&disposition=&status=","host":["{{baseUrl}}"],"path":["api","amazon","unified","summary-ledgers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true},{"key":"date_from","value":"","description":"Start of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"date_to","value":"","description":"End of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"disposition","value":"","disabled":true},{"key":"status","value":"","disabled":true}]},"description":"List Summary Ledgers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Summary Ledger","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/summary-ledgers/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","summary-ledgers",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Summary Ledger\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Current Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/summary-ledgers/current-summary?integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","summary-ledgers","current-summary"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"Get Current Summary\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Export Summary Ledgers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/summary-ledgers/export?integration_instance_ids=&search=&date_from=&date_to=&disposition=&status=","host":["{{baseUrl}}"],"path":["api","amazon","unified","summary-ledgers","export"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"date_from","value":"","description":"Start of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"date_to","value":"","description":"End of the date range (see the Dates & Timezones guide for formats).","disabled":true},{"key":"disposition","value":"","disabled":true},{"key":"status","value":"","disabled":true}]},"description":"Export Summary Ledgers\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Summary Ledger Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/summary-ledgers/{id}/activity-log?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","amazon","unified","summary-ledgers",":id","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Summary Ledger Activity Log\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List FBA Customer Returns (Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns"]},"description":"Returns a paginated list of Amazon FBA customer returns aggregated across all (or selected) Amazon integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filtering, sorting, and pagination. Defaults to 10 items per page. Eager-loads the related `integrationInstance` and `reviewedBy` user."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12345,\n      \"integration_instance_name\": \"Amazon US Marketplace\",\n      \"event_datetime\": \"2026-05-20T14:32:11.000000Z\",\n      \"order_id\": \"112-1234567-1234567\",\n      \"sku\": \"WIDGET-RED-LG\",\n      \"asin\": \"B07XYZ1234\",\n      \"fnsku\": \"X0012345AB\",\n      \"amazon_product\": {\n        \"id\": 789\n      },\n      \"product_name\": \"Acme Red Widget - Large\",\n      \"quantity\": 1,\n      \"fulfillment_center_id\": \"PHX7\",\n      \"detailed_disposition\": \"CUSTOMER_DAMAGED\",\n      \"reason\": \"DAMAGED_BY_CARRIER\",\n      \"status\": \"Reimbursed\",\n      \"license_plate_number\": \"LPN9876543210\",\n      \"customer_comments\": \"Arrived with a torn box and a scratched item.\",\n      \"reviewed_at\": \"2026-05-22T09:15:42.000000Z\",\n      \"reviewed_by\": {\n        \"id\": 7,\n        \"name\": \"Jane Doe\"\n      },\n      \"created_at\": \"2026-05-20T14:35:00.000000Z\",\n      \"updated_at\": \"2026-05-22T09:15:42.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/customer-returns?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"https://example.test/api/amazon/unified/customer-returns?page=12\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/customer-returns?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/customer-returns?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://example.test/api/amazon/unified/customer-returns?page=2\",\n  \"path\": \"https://example.test/api/amazon/unified/customer-returns\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 117\n}"}]},{"name":"Bulk Mark Customer Returns as Reviewed","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/bulk-mark-reviewed","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","bulk-mark-reviewed"]},"description":"Dispatches a tracked background job to mark the given Amazon FBA customer return records as reviewed by the authenticated user.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `ids` (required, array, 1-1000 integers): IDs of `amazon_fba_report_customer_returns` records to mark reviewed.\n\nReturns a `tracked_job_log_id` that the frontend can subscribe to via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12345,\n    12346,\n    12347\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/bulk-mark-reviewed","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","bulk-mark-reviewed"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Bulk mark reviewed started\"\n}"}]},{"name":"Bulk Mark Customer Returns as Unreviewed","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/bulk-mark-unreviewed","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","bulk-mark-unreviewed"]},"description":"Dispatches a tracked background job to mark the given Amazon FBA customer return records as NOT reviewed (clearing `reviewed_at` and `reviewed_by_user_id`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `ids` (required, array, 1-1000 integers): IDs of `amazon_fba_report_customer_returns` records to mark unreviewed.\n\nReturns a `tracked_job_log_id` that the frontend can subscribe to via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12345,\n    12346,\n    12347\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/bulk-mark-unreviewed","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","bulk-mark-unreviewed"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4822\n  },\n  \"message\": \"Bulk mark unreviewed started\"\n}"}]},{"name":"Get Customer Return KPI Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","kpi-stats"]},"description":"Returns headline counts for FBA customer returns across integration instances:\n- total: all customer return rows\n- unreviewed: rows not yet marked as reviewed\n- damaged: rows whose detailed disposition is CARRIER_DAMAGED, CUSTOMER_DAMAGED, DAMAGED, or DEFECTIVE\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters: integration_instance_ids (optional, comma-separated instance IDs; omit to count across all instances)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns","kpi-stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 1284,\n    \"unreviewed\": 211,\n    \"damaged\": 96\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Customer Return","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/{customerReturn}","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns",":customerReturn"],"variable":[{"key":"customerReturn","value":"","description":"Customer return row ID"}]},"description":"Returns a single FBA customer return report row with its cross-links resolved:\n- amazon_product: the matching Amazon listing ({id}), when the SKU resolves\n- reviewed_by: the user who marked the row reviewed ({id, name}), null-fielded when unreviewed\n- linked_sales_order: the SKU.io sales order created from the original Amazon order ({id, sales_order_number, order_status}), or null when no match\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOther fields include order_id (the Amazon order ID), sku, asin, fnsku, product_name, quantity, fulfillment_center_id, detailed_disposition (e.g. SELLABLE, CUSTOMER_DAMAGED), reason (Amazon's return reason code), status, license_plate_number (LPN), customer_comments, reviewed_at, return_date and event_datetime (UTC).\n\nOptional query parameters included / excluded (URL-encoded JSON arrays of column names) limit which columns are returned."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/{customerReturn}","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns",":customerReturn"],"variable":[{"key":"customerReturn","value":"","description":"Customer return row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55107,\n    \"integration_instance_name\": \"Amazon US\",\n    \"event_datetime\": \"2026-06-20T14:35:22.000000Z\",\n    \"order_id\": \"113-9876543-1234567\",\n    \"sku\": \"WIDGET-BLUE-M\",\n    \"asin\": \"B08XYZAB12\",\n    \"fnsku\": \"X002ABCDE1\",\n    \"amazon_product\": {\n      \"id\": 5512\n    },\n    \"product_name\": \"Blue Widget - Medium\",\n    \"quantity\": 1,\n    \"fulfillment_center_id\": \"TUL2\",\n    \"detailed_disposition\": \"SELLABLE\",\n    \"reason\": \"NO_LONGER_NEEDED\",\n    \"status\": \"Unit returned to inventory\",\n    \"license_plate_number\": \"LPNRR123456789\",\n    \"customer_comments\": \"Ordered the wrong size\",\n    \"reviewed_at\": \"2026-06-21T08:12:45.000000Z\",\n    \"reviewed_by\": {\n      \"id\": 12,\n      \"name\": \"Jane Doe\"\n    },\n    \"linked_sales_order\": {\n      \"id\": 88213,\n      \"sales_order_number\": \"SO-102431\",\n      \"order_status\": \"completed\"\n    },\n    \"integration_instance_id\": 3,\n    \"return_date\": \"2026-06-20T00:00:00.000000Z\",\n    \"created_at\": \"2026-06-21T03:05:12.000000Z\",\n    \"updated_at\": \"2026-06-21T08:12:45.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Customer Return Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/{customerReturn}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns",":customerReturn","activity-log"],"variable":[{"key":"customerReturn","value":"","description":"Customer return row ID"}]},"description":"Returns the activity log for a single FBA customer return row: the most recent 200 entries, newest first (not paginated). Each entry contains id, description, event (created / updated / deleted), causer ({id, name, email} of the user who made the change, or null for system changes), properties (old and attributes objects with the changed field values), and created_at (UTC).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/customer-returns/{customerReturn}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","customer-returns",":customerReturn","activity-log"],"variable":[{"key":"customerReturn","value":"","description":"Customer return row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 40233,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": {\n        \"id\": 12,\n        \"name\": \"Jane Doe\",\n        \"email\": \"jane@example.com\"\n      },\n      \"properties\": {\n        \"old\": {\n          \"reviewed_at\": null,\n          \"reviewed_by_user_id\": null\n        },\n        \"attributes\": {\n          \"reviewed_at\": \"2026-06-21T08:12:45.000000Z\",\n          \"reviewed_by_user_id\": 12\n        }\n      },\n      \"created_at\": \"2026-06-21T08:12:45.000000Z\"\n    },\n    {\n      \"id\": 39871,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"causer\": null,\n      \"properties\": {\n        \"old\": null,\n        \"attributes\": {\n          \"order_id\": \"113-9876543-1234567\",\n          \"fnsku\": \"X002ABCDE1\",\n          \"quantity\": 1\n        }\n      },\n      \"created_at\": \"2026-06-21T03:05:12.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Removal Orders (Grouped Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders"]},"description":"Returns paginated removal orders grouped by (order_id, integration_instance_id). Each row is a SUMMARY with aggregated quantities, a representative status/type/disposition, line_count, and a lines array containing line-level rows for expandable UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row also carries is_straddle (the order's shipment predates the FBA inventory tracking start date) and has_pending_straddle (a straddle line still has pending quantity to reconcile). Use filter[needs_attention]=true to list only orders with pending straddle quantity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1234,\n      \"order_id\": \"D-1234567\",\n      \"request_date\": \"2026-04-12T14:30:00.000000Z\",\n      \"order_status\": \"Completed\",\n      \"order_type\": \"Disposal\",\n      \"last_updated_date\": \"2026-04-14T08:15:00.000000Z\",\n      \"sku\": \"SKU-100\",\n      \"fnsku\": \"X001ABCD12\",\n      \"disposition\": \"Sellable\",\n      \"requested_quantity\": 50,\n      \"cancelled_quantity\": 0,\n      \"disposed_quantity\": 0,\n      \"shipped_quantity\": 50,\n      \"in_process_quantity\": 0,\n      \"removal_fee\": \"7.50\",\n      \"currency\": \"USD\",\n      \"is_unknown_item\": false,\n      \"archived_at\": null,\n      \"created_at\": \"2026-04-12T14:30:00.000000Z\",\n      \"updated_at\": \"2026-04-14T08:15:00.000000Z\",\n      \"line_count\": 3,\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US\"\n      },\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"receiving_status\": \"pending\",\n      \"is_straddle\": false,\n      \"has_pending_straddle\": false,\n      \"sku_links\": [],\n      \"fnsku_product\": {\n        \"id\": 42,\n        \"fnsku\": \"X001ABCD12\",\n        \"location\": \"BIN-A1\",\n        \"disposition\": \"Sellable\",\n        \"product\": {\n          \"id\": 99,\n          \"sku\": \"SKU-100\",\n          \"name\": \"Sample Widget\"\n        }\n      },\n      \"lines\": [\n        {\n          \"id\": 1234,\n          \"order_id\": \"D-1234567\",\n          \"sku\": \"SKU-100\",\n          \"fnsku\": \"X001ABCD12\",\n          \"disposition\": \"Sellable\",\n          \"requested_quantity\": 20,\n          \"shipped_quantity\": 20\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"https://app.example.com/api/amazon/unified/removal-orders?page=1\",\n  \"last_page_url\": \"https://app.example.com/api/amazon/unified/removal-orders?page=5\",\n  \"next_page_url\": \"https://app.example.com/api/amazon/unified/removal-orders?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://app.example.com/api/amazon/unified/removal-orders\",\n  \"links\": []\n}"}]},{"name":"Show Removal Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single removal order line-level row, with integrationInstance and amazonFnskuProduct.product eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"order_id\": \"D-1234567\",\n    \"request_date\": \"2026-04-12T14:30:00.000000Z\",\n    \"order_status\": \"Completed\",\n    \"order_type\": \"Disposal\",\n    \"last_updated_date\": \"2026-04-14T08:15:00.000000Z\",\n    \"sku\": \"SKU-100\",\n    \"fnsku\": \"X001ABCD12\",\n    \"disposition\": \"Sellable\",\n    \"requested_quantity\": 20,\n    \"cancelled_quantity\": 0,\n    \"disposed_quantity\": 0,\n    \"shipped_quantity\": 20,\n    \"in_process_quantity\": 0,\n    \"removal_fee\": \"2.50\",\n    \"currency\": \"USD\",\n    \"is_unknown_item\": false,\n    \"archived_at\": null,\n    \"created_at\": \"2026-04-12T14:30:00.000000Z\",\n    \"updated_at\": \"2026-04-14T08:15:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"Amazon US\"\n    },\n    \"integration_instance_id\": 1,\n    \"integration_instance_name\": \"Amazon US\",\n    \"is_straddle\": false,\n    \"has_pending_straddle\": false,\n    \"fnsku_product\": {\n      \"id\": 42,\n      \"fnsku\": \"X001ABCD12\",\n      \"location\": \"BIN-A1\",\n      \"disposition\": \"Sellable\",\n      \"product\": {\n        \"id\": 99,\n        \"sku\": \"SKU-100\",\n        \"name\": \"Sample Widget\"\n      }\n    }\n  }\n}"}]},{"name":"Export Removal Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","export"]},"description":"Exports ALL removal orders (line-level) across integration instances as a JSON collection (no pagination). Used by frontend export flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1234,\n      \"order_id\": \"D-1234567\",\n      \"request_date\": \"2026-04-12T14:30:00.000000Z\",\n      \"order_status\": \"Completed\",\n      \"order_type\": \"Disposal\",\n      \"last_updated_date\": \"2026-04-14T08:15:00.000000Z\",\n      \"sku\": \"SKU-100\",\n      \"fnsku\": \"X001ABCD12\",\n      \"disposition\": \"Sellable\",\n      \"requested_quantity\": 20,\n      \"cancelled_quantity\": 0,\n      \"disposed_quantity\": 0,\n      \"shipped_quantity\": 20,\n      \"in_process_quantity\": 0,\n      \"removal_fee\": \"2.50\",\n      \"currency\": \"USD\",\n      \"is_unknown_item\": false,\n      \"archived_at\": null,\n      \"created_at\": \"2026-04-12T14:30:00.000000Z\",\n      \"updated_at\": \"2026-04-14T08:15:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US\"\n      },\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\"\n    }\n  ]\n}"}]},{"name":"Bulk Archive Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-archive"]},"description":"Dispatches a tracked job to bulk-archive removal orders. Body: { ids: int[] } (required, min 1, max 1000). Returns tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1234,\n    1235,\n    1236\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5678\n  },\n  \"message\": \"Bulk archive started\"\n}"}]},{"name":"Bulk Unarchive Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-unarchive"]},"description":"Dispatches a tracked job to bulk-unarchive removal orders. Body: { ids: int[] } (required, min 1, max 1000). Returns tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1234,\n    1235,\n    1236\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5679\n  },\n  \"message\": \"Bulk unarchive started\"\n}"}]},{"name":"Bulk Unprocess Removal Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-unprocess"]},"description":"Dispatches a tracked job to bulk-unprocess removal orders (undo all receipts). Body: { ids: int[] } (required, min 1, max 1000). Returns tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1234,\n    1235,\n    1236\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-orders/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-orders","bulk-unprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5680\n  },\n  \"message\": \"Bulk unprocess started\"\n}"}]},{"name":"List Removal Shipments (paginated, across instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments"]},"description":"Returns a paginated list of Amazon FBA removal shipments aggregated across integration instances. Excludes archived shipments by default unless filter[archived]=all|only is provided. Eager-loads integrationInstance and amazonFnskuProduct.product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"removal_shipment_id\": 1001,\n      \"order_id\": \"5012345678\",\n      \"request_date\": \"2025-04-12T00:00:00.000000Z\",\n      \"shipment_date\": \"2025-04-15T00:00:00.000000Z\",\n      \"event_datetime\": \"2025-04-15T14:30:00.000000Z\",\n      \"sku\": \"SKU-ABC-001\",\n      \"fnsku\": \"X001ABCDEF\",\n      \"disposition\": \"Sellable\",\n      \"shipped_quantity\": 10,\n      \"qty_discarded\": 0,\n      \"carrier\": \"UPS\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"removal_order_type\": \"Return\",\n      \"created_at\": \"2025-04-16T08:15:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"US Amazon Seller\"\n      },\n      \"fnsku_product\": {\n        \"id\": 501,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"FTW1\",\n        \"disposition\": \"Sellable\",\n        \"product\": {\n          \"id\": 7001,\n          \"sku\": \"INTERNAL-SKU-001\",\n          \"name\": \"Sample Product Name\"\n        }\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 60,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.com/api/amazon/unified/removal-shipments?page=1\",\n  \"last_page_url\": \"https://example.com/api/amazon/unified/removal-shipments?page=4\",\n  \"next_page_url\": \"https://example.com/api/amazon/unified/removal-shipments?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.com/api/amazon/unified/removal-shipments\",\n  \"links\": []\n}"}]},{"name":"Show Removal Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single Amazon FBA removal shipment by id. Eager-loads integrationInstance and amazonFnskuProduct.product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1001,\n    \"removal_shipment_id\": 1001,\n    \"order_id\": \"5012345678\",\n    \"request_date\": \"2025-04-12T00:00:00.000000Z\",\n    \"shipment_date\": \"2025-04-15T00:00:00.000000Z\",\n    \"event_datetime\": \"2025-04-15T14:30:00.000000Z\",\n    \"sku\": \"SKU-ABC-001\",\n    \"fnsku\": \"X001ABCDEF\",\n    \"disposition\": \"Sellable\",\n    \"shipped_quantity\": 10,\n    \"qty_discarded\": 0,\n    \"carrier\": \"UPS\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"removal_order_type\": \"Return\",\n    \"created_at\": \"2025-04-16T08:15:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"US Amazon Seller\"\n    },\n    \"fnsku_product\": {\n      \"id\": 501,\n      \"fnsku\": \"X001ABCDEF\",\n      \"location\": \"FTW1\",\n      \"disposition\": \"Sellable\",\n      \"product\": {\n        \"id\": 7001,\n        \"sku\": \"INTERNAL-SKU-001\",\n        \"name\": \"Sample Product Name\"\n      }\n    }\n  }\n}"}]},{"name":"Export Removal Shipments (across instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","export"]},"description":"Returns all matching Amazon removal shipments (not paginated) across integration instances for export purposes. Results are sorted by shipment_date descending. Note: these are flat top-level query parameters (not Spatie filter[*] format).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"removal_shipment_id\": 1001,\n      \"order_id\": \"5012345678\",\n      \"request_date\": \"2025-04-12T00:00:00.000000Z\",\n      \"shipment_date\": \"2025-04-15T00:00:00.000000Z\",\n      \"event_datetime\": \"2025-04-15T14:30:00.000000Z\",\n      \"sku\": \"SKU-ABC-001\",\n      \"fnsku\": \"X001ABCDEF\",\n      \"disposition\": \"Sellable\",\n      \"shipped_quantity\": 10,\n      \"qty_discarded\": 0,\n      \"carrier\": \"UPS\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"removal_order_type\": \"Return\",\n      \"created_at\": \"2025-04-16T08:15:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"US Amazon Seller\"\n      },\n      \"fnsku_product\": {\n        \"id\": 501,\n        \"fnsku\": \"X001ABCDEF\",\n        \"location\": \"FTW1\",\n        \"disposition\": \"Sellable\",\n        \"product\": {\n          \"id\": 7001,\n          \"sku\": \"INTERNAL-SKU-001\",\n          \"name\": \"Sample Product Name\"\n        }\n      }\n    }\n  ]\n}"}]},{"name":"Bulk Archive Removal Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-archive"]},"description":"Dispatches a tracked background job to bulk-archive the specified removal shipments. Body: `ids` (required array, min 1, max 1000 integers). Returns the tracked_job_log_id so the frontend can subscribe to job progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1001,\n    1002,\n    1003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-archive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4521\n  },\n  \"message\": \"Bulk archive started\"\n}"}]},{"name":"Bulk Unarchive Removal Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-unarchive"]},"description":"Dispatches a tracked background job to bulk-unarchive the specified removal shipments. Body: `ids` (required array, min 1, max 1000 integers). Returns the tracked_job_log_id so the frontend can subscribe to job progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1001,\n    1002,\n    1003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4522\n  },\n  \"message\": \"Bulk unarchive started\"\n}"}]},{"name":"Get Removal Shipment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/{removalShipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments",":removalShipment","activity-log"],"variable":[{"key":"removalShipment","value":"","description":"Removal shipment row ID"}]},"description":"Returns the activity log for a single FBA removal shipment row: the most recent 200 entries, newest first (not paginated). Each entry contains id, description, event (created / updated / deleted), causer ({id, name, email} of the user who made the change, or null for system changes), properties (old and attributes objects with the changed field values), and created_at (UTC).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/{removalShipment}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments",":removalShipment","activity-log"],"variable":[{"key":"removalShipment","value":"","description":"Removal shipment row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 61233,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": {\n        \"id\": 12,\n        \"name\": \"Jane Doe\",\n        \"email\": \"jane@example.com\"\n      },\n      \"properties\": {\n        \"old\": {\n          \"qty_discarded\": 0\n        },\n        \"attributes\": {\n          \"qty_discarded\": 2\n        }\n      },\n      \"created_at\": \"2026-06-25T15:20:31.000000Z\"\n    },\n    {\n      \"id\": 60874,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"causer\": null,\n      \"properties\": {\n        \"old\": null,\n        \"attributes\": {\n          \"order_id\": \"S01234567\",\n          \"fnsku\": \"X002ABCDE1\",\n          \"shipped_quantity\": 12\n        }\n      },\n      \"created_at\": \"2026-06-24T06:10:02.000000Z\"\n    }\n  ]\n}"}]},{"name":"Bulk Unprocess Removal Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-unprocess"]},"description":"Undoes receipt processing for the selected removal shipments — removing the warehouse receipts and inventory movements created when the shipments were processed. Queues a background job and returns a tracked_job_log_id for polling progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- ids (required, array of integers): removal shipment row IDs to unprocess (min 1, max 1000)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    61201,\n    61207,\n    61233\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/removal-shipments/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","removal-shipments","bulk-unprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4512\n  },\n  \"message\": \"Bulk unprocess started\"\n}"}]},{"name":"List Transactions (paginated, cross-instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions"]},"description":"Get paginated Amazon transactions across all (or filtered) integration instances. Response wraps standard Laravel pagination plus an `unfiltered_total` field showing the true catalog size for the ExportModal 'All records' option. By default, superseded transactions are excluded — pass filter[include_superseded]=true to include them.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1234,\n      \"transaction_id\": \"abc-123-def-456\",\n      \"transaction_type\": \"Shipment\",\n      \"transaction_status\": \"RELEASED\",\n      \"description\": \"Order Payment\",\n      \"posted_date\": \"2026-02-15T08:30:00.000000Z\",\n      \"total_amount\": 49.99,\n      \"currency_code\": \"USD\",\n      \"marketplace_id\": \"ATVPDKIKX0DER\",\n      \"amazon_order_id\": \"701-1234567-1234567\",\n      \"is_mcf_order\": false,\n      \"settlement_id\": \"99999\",\n      \"financial_event_group_id\": \"fg-xyz\",\n      \"shipment_id\": null,\n      \"processed_at\": null,\n      \"linked_sales_order\": {\n        \"id\": 5678,\n        \"sales_order_number\": \"SO-1001\"\n      },\n      \"created_at\": \"2026-02-15T09:00:00.000000Z\",\n      \"updated_at\": \"2026-02-15T09:00:00.000000Z\",\n      \"json_object\": {\n        \"some\": \"raw amazon api fields\"\n      },\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US\"\n      },\n      \"items\": [\n        {\n          \"id\": 9001,\n          \"item_index\": 0,\n          \"description\": \"Widget SKU-001\",\n          \"total_amount\": 49.99,\n          \"currency_code\": \"USD\",\n          \"sku\": \"SKU-001\",\n          \"asin\": \"B0ABCDEFGH\",\n          \"quantity\": 1,\n          \"breakdowns\": [\n            {\n              \"id\": 7001,\n              \"breakdown_path\": \"PRODUCTCHARGES.PRINCIPAL\",\n              \"breakdown_type\": \"PRINCIPAL\",\n              \"top_level_type\": \"PRODUCTCHARGES\",\n              \"depth\": 1,\n              \"amount\": 49.99,\n              \"currency_code\": \"USD\"\n            }\n          ]\n        }\n      ],\n      \"breakdowns\": [\n        {\n          \"id\": 7100,\n          \"breakdown_path\": \"AMAZONFEES.FBAFEES\",\n          \"breakdown_type\": \"FBAFEES\",\n          \"top_level_type\": \"AMAZONFEES\",\n          \"depth\": 1,\n          \"amount\": -3.5,\n          \"currency_code\": \"USD\"\n        }\n      ],\n      \"breakdown_totals\": [\n        {\n          \"type\": \"PRODUCTCHARGES\",\n          \"total\": 49.99,\n          \"currency_code\": \"USD\"\n        },\n        {\n          \"type\": \"AMAZONFEES\",\n          \"total\": -3.5,\n          \"currency_code\": \"USD\"\n        }\n      ],\n      \"processed_entities\": []\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 10,\n  \"per_page\": 15,\n  \"total\": 150,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/transactions?page=1\",\n  \"last_page_url\": \"https://example.test/api/amazon/unified/transactions?page=10\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/transactions?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/transactions\",\n  \"links\": [],\n  \"unfiltered_total\": 1234\n}"}]},{"name":"Show Transaction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a single Amazon transaction with full details: integration instance, items + their breakdowns, transaction-level breakdowns, breakdown totals grouped by top-level type, and any entities created when it was processed (SalesCredit, FinancialLine, etc.).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"transaction_id\": \"abc-123-def-456\",\n    \"transaction_type\": \"Shipment\",\n    \"transaction_status\": \"RELEASED\",\n    \"description\": \"Order Payment\",\n    \"posted_date\": \"2026-02-15T08:30:00.000000Z\",\n    \"total_amount\": 49.99,\n    \"currency_code\": \"USD\",\n    \"marketplace_id\": \"ATVPDKIKX0DER\",\n    \"amazon_order_id\": \"701-1234567-1234567\",\n    \"is_mcf_order\": false,\n    \"settlement_id\": \"99999\",\n    \"financial_event_group_id\": \"fg-xyz\",\n    \"shipment_id\": null,\n    \"processed_at\": \"2026-02-16T12:00:00.000000Z\",\n    \"linked_sales_order\": {\n      \"id\": 5678,\n      \"sales_order_number\": \"SO-1001\"\n    },\n    \"created_at\": \"2026-02-15T09:00:00.000000Z\",\n    \"updated_at\": \"2026-02-16T12:00:00.000000Z\",\n    \"json_object\": {\n      \"some\": \"raw amazon api fields\"\n    },\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"Amazon US\"\n    },\n    \"items\": [\n      {\n        \"id\": 9001,\n        \"item_index\": 0,\n        \"description\": \"Widget SKU-001\",\n        \"total_amount\": 49.99,\n        \"currency_code\": \"USD\",\n        \"sku\": \"SKU-001\",\n        \"asin\": \"B0ABCDEFGH\",\n        \"quantity\": 1,\n        \"breakdowns\": [\n          {\n            \"id\": 7001,\n            \"breakdown_path\": \"PRODUCTCHARGES.PRINCIPAL\",\n            \"breakdown_type\": \"PRINCIPAL\",\n            \"top_level_type\": \"PRODUCTCHARGES\",\n            \"depth\": 1,\n            \"amount\": 49.99,\n            \"currency_code\": \"USD\"\n          }\n        ]\n      }\n    ],\n    \"breakdowns\": [\n      {\n        \"id\": 7100,\n        \"breakdown_path\": \"AMAZONFEES.FBAFEES\",\n        \"breakdown_type\": \"FBAFEES\",\n        \"top_level_type\": \"AMAZONFEES\",\n        \"depth\": 1,\n        \"amount\": -3.5,\n        \"currency_code\": \"USD\"\n      }\n    ],\n    \"breakdown_totals\": [\n      {\n        \"type\": \"PRODUCTCHARGES\",\n        \"total\": 49.99,\n        \"currency_code\": \"USD\"\n      },\n      {\n        \"type\": \"AMAZONFEES\",\n        \"total\": -3.5,\n        \"currency_code\": \"USD\"\n      }\n    ],\n    \"processed_entities\": [\n      {\n        \"id\": 4400,\n        \"entity_type\": \"App\\\\Models\\\\SalesCredit\",\n        \"entity_id\": 222,\n        \"created_at\": \"2026-02-16T12:00:00.000000Z\",\n        \"entity\": {\n          \"sales_credit_number\": \"SC-001\",\n          \"credit_status\": \"approved\",\n          \"total_credit\": 49.99,\n          \"credit_date\": \"2026-02-16\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Statistics (grouped breakdowns)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/statistics","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","statistics"]},"description":"Returns breakdown statistics grouped into business categories (sales, fees, refunds, other, net) — amounts per currency — plus available filter values for dropdowns. Excludes superseded transactions to prevent double-counting.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/statistics","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sales\": {\n      \"PRODUCTCHARGES\": {\n        \"amount\": 12345.67,\n        \"count\": 320\n      },\n      \"SALES\": {\n        \"amount\": 2200,\n        \"count\": 18\n      }\n    },\n    \"fees\": {\n      \"AMAZONFEES\": {\n        \"amount\": -1500.5,\n        \"count\": 320\n      },\n      \"DIGITALSERVICESFEE\": {\n        \"amount\": -75,\n        \"count\": 32\n      }\n    },\n    \"refunds\": {\n      \"REFUNDEDSALES\": {\n        \"amount\": -250,\n        \"count\": 5\n      },\n      \"PROMOREBATES\": {\n        \"amount\": -30,\n        \"count\": 2\n      }\n    },\n    \"other\": {\n      \"ADJUSTMENT\": {\n        \"amount\": 10,\n        \"count\": 1\n      }\n    },\n    \"net\": {\n      \"USD\": 10700.17\n    },\n    \"available_filters\": {\n      \"transaction_types\": [\n        \"Shipment\",\n        \"Refund\",\n        \"Service Fee\"\n      ],\n      \"transaction_statuses\": [\n        \"DEFERRED\",\n        \"DEFERRED_RELEASED\",\n        \"RELEASED\"\n      ],\n      \"integration_instances\": [\n        {\n          \"id\": 1,\n          \"name\": \"Amazon US\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"Amazon CA\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Sync Transactions (background job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","sync"]},"description":"Dispatch a background job for each active Amazon integration instance (or only those specified via integration_instance_ids, comma-separated). Returns the count of dispatched jobs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Sync jobs dispatched for 2 integration instance(s)\",\n    \"instances_count\": 2\n  }\n}"}]},{"name":"Process Transaction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{transaction}/process","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":transaction","process"],"variable":[{"key":"transaction","value":"1234","description":"AmazonTransaction ID"}]},"description":"Process a single transaction — creates the appropriate financial entities (SalesCredit, FinancialLine, etc.) and triggers a financials recalculation for affected sales order lines. Returns 422 with an error when the transaction is invalid or has no linked sales order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{transaction}/process","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":transaction","process"],"variable":[{"key":"transaction","value":"1234","description":"AmazonTransaction ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"transaction_id\": \"abc-123-def-456\",\n    \"transaction_type\": \"Shipment\",\n    \"transaction_status\": \"RELEASED\",\n    \"processed_at\": \"2026-05-30T10:00:00.000000Z\",\n    \"linked_sales_order\": {\n      \"id\": 5678,\n      \"sales_order_number\": \"SO-1001\"\n    },\n    \"processed_entities\": [\n      {\n        \"id\": 4400,\n        \"entity_type\": \"App\\\\Models\\\\SalesCredit\",\n        \"entity_id\": 222,\n        \"created_at\": \"2026-05-30T10:00:00.000000Z\",\n        \"entity\": {\n          \"sales_credit_number\": \"SC-001\",\n          \"credit_status\": \"approved\",\n          \"total_credit\": 49.99,\n          \"credit_date\": \"2026-05-30\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Unprocess Transaction","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{transaction}/unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":transaction","unprocess"],"variable":[{"key":"transaction","value":"1234","description":"AmazonTransaction ID"}]},"description":"Reverse processing for a single transaction — deletes/reverses all entities created when the transaction was originally processed. Returns the refreshed transaction resource.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/{transaction}/unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions",":transaction","unprocess"],"variable":[{"key":"transaction","value":"1234","description":"AmazonTransaction ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"transaction_id\": \"abc-123-def-456\",\n    \"processed_at\": null,\n    \"processed_entities\": []\n  }\n}"}]},{"name":"Bulk Process Transactions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/bulk-process","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","bulk-process"]},"description":"Process multiple transactions in one request. Required: transaction_ids (array, min 1, each must exist in amazon_transactions.id). Triggers a financials recalculation after completion.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"transaction_ids\": [\n    1234,\n    1235,\n    1236\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/bulk-process","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","bulk-process"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processed_count\": 2,\n    \"failed_count\": 1,\n    \"failures\": [\n      {\n        \"transaction_id\": 1236,\n        \"reason\": \"No linked sales order found\"\n      }\n    ]\n  }\n}"}]},{"name":"Bulk Unprocess Transactions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","bulk-unprocess"]},"description":"Reverse processing for multiple transactions. Required: transaction_ids (array, min 1, each must exist).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"transaction_ids\": [\n    1234,\n    1235,\n    1236\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/bulk-unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","bulk-unprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unprocessed_count\": 3,\n    \"failed_count\": 0,\n    \"failures\": []\n  }\n}"}]},{"name":"Process All (background job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","process-all"]},"description":"Dispatch a background job — processes all unprocessed transactions matching the optional filters. Returns the tracked job log ID so the frontend can poll progress via /process-all/status or the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","process-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Process all job has been started\",\n    \"job_id\": 8842\n  }\n}"}]},{"name":"Process All Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/process-all/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","process-all","status"]},"description":"Returns the most recent a background job status for the authenticated user — pulled from TrackedJobLog. If a Laravel Bus batch is attached, includes per-batch progress (total/pending/processed/failed jobs, finished/cancelled flags, progress percentage).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/process-all/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","process-all","status"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"job_id\": 8842,\n    \"status\": \"processing\",\n    \"total_items\": 1500,\n    \"processed_items\": 425,\n    \"progress_percentage\": 28.33,\n    \"results\": {\n      \"batch_id\": \"01HX7Z2YQH...\"\n    },\n    \"messages\": [\n      \"Dispatching batch of 1500 transactions\"\n    ],\n    \"created_at\": \"2026-05-30T10:15:00.000000Z\",\n    \"completed_at\": null,\n    \"batch_progress\": {\n      \"total_jobs\": 1500,\n      \"pending_jobs\": 1075,\n      \"processed_jobs\": 425,\n      \"failed_jobs\": 2,\n      \"finished\": false,\n      \"cancelled\": false,\n      \"progress_percentage\": 28.33\n    }\n  }\n}"}]},{"name":"Export Transactions (background job)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","export"]},"description":"Dispatch a background job — generates an xlsx/csv export honouring the current filters (or a selected ID list). Returns a tracked_job_log_id; once complete, download the result via /export/download?file=...\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9921\n  }\n}"}]},{"name":"Download Export File","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/export/download?file=amazon-transactions-2026-05-30-101500.xlsx","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","export","download"],"query":[{"key":"file","value":"amazon-transactions-2026-05-30-101500.xlsx","description":"Required — filename produced by the export job (basename only; path components stripped)","disabled":true}]},"description":"Download a completed export file from the model-exports disk. Returns the binary file with Content-Type set based on extension (text/csv for .csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for .xlsx). 404 if file is missing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/transactions/export/download?file=amazon-transactions-2026-05-30-101500.xlsx","host":["{{baseUrl}}"],"path":["api","amazon","unified","transactions","export","download"],"query":[{"key":"file","value":"amazon-transactions-2026-05-30-101500.xlsx","description":"Required — filename produced by the export job (basename only; path components stripped)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary xlsx file contents>"}]},{"name":"List FBA Shipments Detail (paginated, across instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments"]},"description":"Paginated list of FBA shipments-detail rows aggregated across Amazon integration instances. Each row represents one shipped item line from the GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL report. Filtering uses Spatie QueryBuilder with AdvancedSearchFilter (search across order/shipment/product/tracking/recipient fields) plus ~25 text filters, ~9 numeric filters, and ~8 datetime filters. Response includes linked_sales_order (bulk-resolved via amazon_order_id → amazon_orders → sales_orders join) and amazon_product (bulk-resolved by integration_instance_id + seller_sku). Default sort: -shipment_date.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 44453,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"BCK - North America\",\n      \"amazon_order_id\": \"112-7606445-9266668\",\n      \"merchant_order_id\": null,\n      \"shipment_id\": \"P4p8yWlvp\",\n      \"shipment_item_id\": \"DPrGkyYSzz01R\",\n      \"amazon_order_item_id\": \"158578633674281\",\n      \"merchant_order_item_id\": null,\n      \"purchase_date\": \"2026-04-25T20:31:00.000000Z\",\n      \"payments_date\": \"2026-04-25T22:42:00.000000Z\",\n      \"shipment_date\": \"2026-04-25T22:49:00.000000Z\",\n      \"reporting_date\": \"2026-04-26T00:00:00.000000Z\",\n      \"estimated_arrival_date\": \"2026-04-26T06:00:00.000000Z\",\n      \"event_datetime\": \"2026-04-25T22:49:00.000000Z\",\n      \"sku\": \"ZE-LN56-F7UA\",\n      \"product_name\": \"BIGCAT ROAR Predator Hunter — Patented Handmade Damascus Steel Fixed Blade Hunting Knife\",\n      \"quantity_shipped\": 1,\n      \"currency\": \"USD\",\n      \"item_price\": 49.99,\n      \"item_tax\": 3.5,\n      \"shipping_price\": 1.49,\n      \"shipping_tax\": 0,\n      \"gift_wrap_price\": 0,\n      \"gift_wrap_tax\": 0,\n      \"item_promotion_discount\": 0,\n      \"ship_promotion_discount\": 0,\n      \"recipient_name\": null,\n      \"ship_address_1\": null,\n      \"ship_address_2\": null,\n      \"ship_address_3\": null,\n      \"ship_city\": \"COLUMBIA CITY\",\n      \"ship_state\": \"IN\",\n      \"ship_postal_code\": \"46725-1507\",\n      \"ship_country\": \"US\",\n      \"ship_phone_number\": null,\n      \"bill_address_1\": null,\n      \"bill_address_2\": null,\n      \"bill_address_3\": null,\n      \"bill_city\": null,\n      \"bill_state\": null,\n      \"bill_postal_code\": null,\n      \"bill_country\": null,\n      \"buyer_name\": null,\n      \"buyer_phone_number\": null,\n      \"buyer_email\": null,\n      \"fulfillment_channel\": \"Amazon\",\n      \"sales_channel\": \"amazon.com\",\n      \"ship_service_level\": \"Expedited\",\n      \"carrier\": \"AMZN_US\",\n      \"tracking_number\": \"TBA338512244849\",\n      \"fulfillment_center_id\": \"FWA6\",\n      \"created_at\": \"2026-04-26T00:05:12.000000Z\",\n      \"updated_at\": \"2026-04-26T00:05:12.000000Z\",\n      \"linked_sales_order\": {\n        \"id\": 5678,\n        \"sales_order_number\": \"SO-1001\",\n        \"order_status\": \"shipped\"\n      },\n      \"amazon_product\": {\n        \"id\": 9012\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/amazon/unified/shipments?page=1\",\n  \"from\": 1,\n  \"last_page\": 30,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/amazon/unified/shipments?page=30\",\n  \"links\": [],\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/amazon/unified/shipments?page=2\",\n  \"path\": \"{{protocol}}{{domain}}/api/amazon/unified/shipments\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 450\n}"}]},{"name":"FBA Shipments Detail — KPI Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments","kpi-stats"]},"description":"Cross-instance KPI summary for the FBA Shipments Detail listing. Returns total_shipments (row count), total_units (sum of quantity_shipped), total_revenue (sum of item_price), and unique_orders (distinct amazon_order_id count). Used to drive the dashboard-card row above the listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments","kpi-stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_shipments\": 12450,\n    \"total_units\": 18792,\n    \"total_revenue\": 619437.21,\n    \"unique_orders\": 9874\n  }\n}"}]},{"name":"Show FBA Shipment Detail Row","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments",":shipment"],"variable":[{"key":"shipment","value":"44453","description":"Numeric AmazonFbaReportShipment ID"}]},"description":"Single FBA shipment-detail row by ID with eager-loaded integrationInstance and bulk-resolved cross-links: linked_sales_order (via amazon_order_id) and amazon_product (via integration_instance_id + seller SKU). Use this to power the detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","amazon","unified","shipments",":shipment"],"variable":[{"key":"shipment","value":"44453","description":"Numeric AmazonFbaReportShipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 44453,\n    \"integration_instance_id\": 1,\n    \"integration_instance_name\": \"BCK - North America\",\n    \"amazon_order_id\": \"112-7606445-9266668\",\n    \"merchant_order_id\": null,\n    \"shipment_id\": \"P4p8yWlvp\",\n    \"shipment_item_id\": \"DPrGkyYSzz01R\",\n    \"amazon_order_item_id\": \"158578633674281\",\n    \"merchant_order_item_id\": null,\n    \"purchase_date\": \"2026-04-25T20:31:00.000000Z\",\n    \"payments_date\": \"2026-04-25T22:42:00.000000Z\",\n    \"shipment_date\": \"2026-04-25T22:49:00.000000Z\",\n    \"reporting_date\": \"2026-04-26T00:00:00.000000Z\",\n    \"estimated_arrival_date\": \"2026-04-26T06:00:00.000000Z\",\n    \"event_datetime\": \"2026-04-25T22:49:00.000000Z\",\n    \"sku\": \"ZE-LN56-F7UA\",\n    \"product_name\": \"BIGCAT ROAR Predator Hunter Knife\",\n    \"quantity_shipped\": 1,\n    \"currency\": \"USD\",\n    \"item_price\": 49.99,\n    \"item_tax\": 3.5,\n    \"shipping_price\": 1.49,\n    \"shipping_tax\": 0,\n    \"gift_wrap_price\": 0,\n    \"gift_wrap_tax\": 0,\n    \"item_promotion_discount\": 0,\n    \"ship_promotion_discount\": 0,\n    \"recipient_name\": null,\n    \"ship_address_1\": null,\n    \"ship_address_2\": null,\n    \"ship_address_3\": null,\n    \"ship_city\": \"COLUMBIA CITY\",\n    \"ship_state\": \"IN\",\n    \"ship_postal_code\": \"46725-1507\",\n    \"ship_country\": \"US\",\n    \"ship_phone_number\": null,\n    \"bill_address_1\": null,\n    \"bill_address_2\": null,\n    \"bill_address_3\": null,\n    \"bill_city\": null,\n    \"bill_state\": null,\n    \"bill_postal_code\": null,\n    \"bill_country\": null,\n    \"buyer_name\": null,\n    \"buyer_phone_number\": null,\n    \"buyer_email\": null,\n    \"fulfillment_channel\": \"Amazon\",\n    \"sales_channel\": \"amazon.com\",\n    \"ship_service_level\": \"Expedited\",\n    \"carrier\": \"AMZN_US\",\n    \"tracking_number\": \"TBA338512244849\",\n    \"fulfillment_center_id\": \"FWA6\",\n    \"created_at\": \"2026-04-26T00:05:12.000000Z\",\n    \"updated_at\": \"2026-04-26T00:05:12.000000Z\",\n    \"linked_sales_order\": {\n      \"id\": 5678,\n      \"sales_order_number\": \"SO-1001\",\n      \"order_status\": \"shipped\"\n    },\n    \"amazon_product\": {\n      \"id\": 9012\n    }\n  }\n}"}]},{"name":"List FBA Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-inventory?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-inventory"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List FBA Inventory\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get FBA Inventory Record","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-inventory/{inventory}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-inventory",":inventory"],"variable":[{"key":"inventory","value":"","description":"FBA inventory row ID"}]},"description":"Returns a single FBA-managed inventory report row (from Amazon's FBA inventory report) with cross-links resolved:\n- sku: {value, amazon_product_id} — the seller SKU and the matching Amazon listing ID when one resolves\n- fnsku_product: {id} of the matching FNSKU product record for the same integration instance, or null when the FNSKU is not mapped\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuantity fields cover the fulfillment network position: afn_warehouse_quantity, afn_fulfillable_quantity, afn_unsellable_quantity, afn_reserved_quantity, afn_total_quantity, the inbound pipeline (afn_inbound_working_quantity, afn_inbound_shipped_quantity, afn_inbound_receiving_quantity), afn_researching_quantity and future-supply fields, plus merchant-fulfilled counterparts (mfn_listing_exists, mfn_fulfillable_quantity). Also includes country_code, condition, your_price and per_unit_volume.\n\nOptional query parameters included / excluded (URL-encoded JSON arrays of column names) limit which columns are returned."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-inventory/{inventory}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-inventory",":inventory"],"variable":[{"key":"inventory","value":"","description":"FBA inventory row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 90211,\n    \"integration_instance_name\": \"Amazon US\",\n    \"country_code\": \"US\",\n    \"sku\": {\n      \"value\": \"WIDGET-BLUE-M\",\n      \"amazon_product_id\": 5512\n    },\n    \"fnsku\": \"X002ABCDE1\",\n    \"product_name\": \"Blue Widget - Medium\",\n    \"condition\": \"New\",\n    \"your_price\": \"24.99\",\n    \"mfn_listing_exists\": \"No\",\n    \"mfn_fulfillable_quantity\": 0,\n    \"afn_listing_exists\": \"Yes\",\n    \"afn_warehouse_quantity\": \"380\",\n    \"afn_fulfillable_quantity\": 352,\n    \"afn_unsellable_quantity\": 4,\n    \"afn_reserved_quantity\": 24,\n    \"afn_total_quantity\": 580,\n    \"per_unit_volume\": 0.42,\n    \"afn_inbound_working_quantity\": 100,\n    \"afn_inbound_shipped_quantity\": 80,\n    \"afn_inbound_receiving_quantity\": 20,\n    \"afn_researching_quantity\": 2,\n    \"afn_reserved_future_supply\": 0,\n    \"afn_future_supply_buyable\": 0,\n    \"created_at\": \"2026-07-05T06:00:14.000000Z\",\n    \"updated_at\": \"2026-07-06T06:00:22.000000Z\",\n    \"fnsku_product\": {\n      \"id\": 1592\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments"]},"description":"Returns a paginated `LengthAwarePaginator` of new (v2) FBA inbound shipments across one or more Amazon integration instances. Each item is transformed by Amazon new FBA inbound shipment object and includes identifier fields (`shipmentId`, `shipmentConfirmationId`, `amazonReferenceId`, `name`, `sourceName`), status info (`status`, `pending_status`, `errorLog`, `is_archived`), destination block (`destinationCountry`, `destinationWarehouse`, `destinationType`, `destination`), transportation IDs, the `sku_link` block (linked Purchase Order or Warehouse Transfer), `actual_source` (resolved supplier/from-warehouse derived from the SKU link), and `ship_from_mapping` (the mapping that *would* be applied today — used to surface divergence client-side). When the relevant relations are eager-loaded the resource also returns `pending_inbound`, `receipts`, and `items`. Defaults to excluding archived shipments unless `filter[archived]` is provided.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"US Marketplace\",\n      \"shipmentId\": \"FBA15ABCDEFG\",\n      \"shipmentConfirmationId\": \"FBA15ABCDEFG\",\n      \"amazonReferenceId\": \"AMZN-REF-123\",\n      \"name\": \"FBA (07/14/2025 18:22) - 1\",\n      \"sourceName\": \"SKU Warehouse - California\",\n      \"status\": \"SHIPPED\",\n      \"pending_status\": null,\n      \"errorLog\": null,\n      \"is_before_initial_count\": false,\n      \"is_archived\": false,\n      \"archived_at\": null,\n      \"destinationCountry\": \"US\",\n      \"destinationWarehouse\": \"ONT8\",\n      \"destinationType\": \"FC\",\n      \"destinationAddress\": {\n        \"name\": \"Amazon.com Services, Inc.\",\n        \"addressLine1\": \"24300 Nandina Ave\",\n        \"city\": \"Moreno Valley\",\n        \"stateOrProvinceCode\": \"CA\",\n        \"postalCode\": \"92551\",\n        \"countryCode\": \"US\"\n      },\n      \"destination\": {\n        \"warehouseId\": \"ONT8\",\n        \"address\": {\n          \"name\": \"Amazon.com Services, Inc.\",\n          \"addressLine1\": \"24300 Nandina Ave\",\n          \"city\": \"Moreno Valley\",\n          \"stateOrProvinceCode\": \"CA\",\n          \"postalCode\": \"92551\",\n          \"countryCode\": \"US\"\n        }\n      },\n      \"selectedTransportationOptionId\": \"toid_8a1b9d2e\",\n      \"placementOptionId\": \"pid_3c0a771e\",\n      \"cached_shipment_date\": \"2025-07-14T18:22:00.000000Z\",\n      \"sku_link\": {\n        \"id\": 442,\n        \"type\": \"App\\\\Models\\\\PurchaseOrder\",\n        \"name\": \"PO-2025-0442\",\n        \"displayType\": \"Purchase Order\"\n      },\n      \"actual_source\": {\n        \"name\": \"Acme Supplies Co.\",\n        \"type\": \"Supplier\",\n        \"link_type\": \"App\\\\Models\\\\Supplier\",\n        \"link_id\": 18,\n        \"route\": \"/crm/suppliers/18\"\n      },\n      \"ship_from_mapping\": {\n        \"name\": \"SKU Warehouse - California\",\n        \"mapping_id\": 7,\n        \"target\": {\n          \"name\": \"SKU Warehouse - California\",\n          \"type\": \"Warehouse\",\n          \"link_type\": \"App\\\\Models\\\\Warehouse\",\n          \"link_id\": 3,\n          \"route\": \"/crm/warehouses/3\"\n        }\n      },\n      \"pending_inbound\": {\n        \"id\": 91,\n        \"status\": \"shipped\",\n        \"shipped_at\": \"2025-07-14T18:22:00.000000Z\"\n      },\n      \"created_at\": \"2025-07-14T18:22:00.000000Z\",\n      \"updated_at\": \"2025-07-15T02:11:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 117,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/new-inbound-shipments?page=1\",\n  \"last_page_url\": \"https://example.test/api/amazon/unified/new-inbound-shipments?page=12\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/new-inbound-shipments?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/amazon/unified/new-inbound-shipments\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/new-inbound-shipments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/new-inbound-shipments?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ]\n}"}]},{"name":"Export Shipment Items (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","export"]},"description":"Streams a CSV download of new inbound shipment items (line-level rows) across the supplied integration instances. Each row represents one line item with its parent shipment info repeated. Columns: `sr_no`, `confirmation_id`, `shipment_id`, `shipment_name`, `status`, `source_name`, `destination_country`, `destination_warehouse`, `integration`, `msku`, `fnsku`, `asin`, `quantity_sent`, `quantity_received`, `shipment_created_at`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen the resulting item set is empty the endpoint returns a JSON message instead of a file (`You can't export empty data`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": true,\n  \"data\": null,\n  \"message\": \"You can't export empty data\"\n}"}]},{"name":"Refresh All (Sync from Amazon)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","refresh"]},"description":"Dispatches a background job to (re)sync new FBA inbound shipments (via their plans) from Amazon for one or more integration instances. Returns immediately with a `tracked_job_log_id` that the frontend uses to render progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body / query params:**\n- `integration_instance_ids` (optional) — comma-separated string or array of AmazonIntegrationInstance IDs. When omitted, the job runs for every Amazon integration instance.\n\nThe job name is `Sync FBA New Inbound Shipments: <instance name | N Integrations>` — frontend watchers should match on that `startsWith`.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": true,\n  \"data\": {\n    \"tracked_job_log_id\": 8821,\n    \"integration_instance_count\": 2\n  },\n  \"message\": \"Refresh started — track progress in the job tray\"\n}"}]},{"name":"Process All (Apply Unprocessed Shipments)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","process-all"]},"description":"Dispatches a background job which links unprocessed new FBA inbound shipments to their SKU.io source records (Purchase Orders / Warehouse Transfers via ship-from mappings) and processes cancellations across one or more integration instances. Returns immediately with a `tracked_job_log_id` for the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body / query params:**\n- `integration_instance_ids` (optional) — comma-separated string or array of AmazonIntegrationInstance IDs. When omitted, the job runs for every Amazon integration instance.\n\nThe job name is `Process FBA New Inbound Shipments: <instance name | N Integrations>` — frontend watchers should match on that `startsWith`.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","process-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": true,\n  \"data\": {\n    \"tracked_job_log_id\": 8822,\n    \"integration_instance_count\": 2\n  },\n  \"message\": \"Processing started — track progress in the job tray\"\n}"}]},{"name":"KPI Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","kpi-stats"]},"description":"Returns KPI counts for the New Inbound Shipments page, scoped to active (non-archived) shipments only. Counts are computed across the provided integration instances (or all instances when none supplied). Response keys:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `awaiting_over_14_days` — shipments in SHIPPED / IN_TRANSIT / DELIVERED / CHECKED_IN / RECEIVING status whose `cached_shipment_date` is older than 14 days.\n- `discrepancies` — shipments in MIXED status.\n- `errored` — shipments whose `errorLog` is set and non-empty."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/new-inbound-shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","new-inbound-shipments","kpi-stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": true,\n  \"data\": {\n    \"awaiting_over_14_days\": 12,\n    \"discrepancies\": 3,\n    \"errored\": 1\n  },\n  \"message\": \"\"\n}"}]},{"name":"List Legacy FBA Inbound Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments"]},"description":"Returns a paginated list of legacy `AmazonFbaInboundShipment` records aggregated across one or more integration instances. Eager loads `integrationInstance` and `skuLink`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports both flat `filter[...]` syntax and grouped advanced filters via the `filter_groups` payload (POST-style array). Allowed sorts include id, ShipmentId, ShipmentName, ShipFromName, DestinationFulfillmentCenterId, ShipmentStatus, LabelPrepType, BoxContentsSource, errorLog, is_before_initial_count, created_at, updated_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"US Marketplace\",\n      \"ShipmentId\": \"FBA15ABC123\",\n      \"ShipmentName\": \"Replenishment 2026-05\",\n      \"ShipFromName\": \"Main Warehouse\",\n      \"DestinationFulfillmentCenterId\": \"ONT8\",\n      \"ShipmentStatus\": \"SHIPPED\",\n      \"LabelPrepType\": \"SELLER_LABEL\",\n      \"BoxContentsSource\": \"BOX_CONTENT_PROVIDED\",\n      \"errorLog\": null,\n      \"is_before_initial_count\": false,\n      \"sku_link\": {\n        \"id\": 4471,\n        \"type\": \"App\\\\Models\\\\WarehouseTransfer\",\n        \"name\": \"WT-000123\",\n        \"displayType\": \"Warehouse Transfer\"\n      },\n      \"created_at\": \"2026-05-10T14:22:31.000000Z\",\n      \"updated_at\": \"2026-05-22T09:11:08.000000Z\"\n    }\n  ],\n  \"links\": {\n    \"first\": \"https://example.test/api/amazon/unified/legacy-inbound-shipments?page=1\",\n    \"last\": \"https://example.test/api/amazon/unified/legacy-inbound-shipments?page=12\",\n    \"prev\": null,\n    \"next\": \"https://example.test/api/amazon/unified/legacy-inbound-shipments?page=2\"\n  },\n  \"meta\": {\n    \"current_page\": 1,\n    \"from\": 1,\n    \"last_page\": 12,\n    \"path\": \"https://example.test/api/amazon/unified/legacy-inbound-shipments\",\n    \"per_page\": 10,\n    \"to\": 10,\n    \"total\": 113\n  }\n}"}]},{"name":"Export Shipment Items (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","export"]},"description":"Exports legacy inbound shipment items (line-level) across the specified integration instances as a CSV file download. One row per `AmazonFbaInboundShipmentItem` with shipment metadata repeated per line.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse is a CSV file (Content-Type: text/csv) with filename pattern `legacy-inbound-shipment-items-YYYY-MM-DD-HHmmss.csv`. The file is auto-deleted server-side after send.\n\nColumns: sr_no, shipment_id, shipment_name, status, ship_from_name, destination_fc, from_country_code, integration, seller_sku, fnsku, quantity_shipped, quantity_received_api, quantity_received_calculated, shipment_created_at.\n\nIf no items match, returns a JSON response with message `You can't export empty data` instead of a file."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","export"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [],\n  \"message\": \"You can't export empty data\",\n  \"status\": true\n}"}]},{"name":"Refresh All Shipments (dispatch tracked job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","refresh"]},"description":"Dispatches a background job to refresh legacy inbound shipments from Amazon across the specified integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body / query accepts `integration_instance_ids` as either:\n- A JSON array of ints: `[1, 2]`\n- A comma-separated string: `\"1,2\"`\n\nIf omitted, ALL `AmazonIntegrationInstance` IDs are used.\n\nReturns immediately with a `tracked_job_log_id` that the frontend uses to display progress via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 88231,\n    \"integration_instance_count\": 2\n  },\n  \"message\": \"Refresh started — track progress in the job tray\",\n  \"status\": true\n}"}]},{"name":"Process All Unprocessed Shipments (dispatch tracked job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","process-all"]},"description":"Dispatches a background job to process unprocessed legacy inbound shipments across the specified integration instances. Processing handles SKU linking, ledger entries, and cancellation reconciliation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body / query accepts `integration_instance_ids` as either:\n- A JSON array of ints: `[1, 2]`\n- A comma-separated string: `\"1,2\"`\n\nIf omitted, ALL `AmazonIntegrationInstance` IDs are used.\n\nReturns immediately with a `tracked_job_log_id` that the frontend uses to display progress via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/process-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","process-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 88232,\n    \"integration_instance_count\": 2\n  },\n  \"message\": \"Processing started — track progress in the job tray\",\n  \"status\": true\n}"}]},{"name":"Get KPI Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","kpi-stats"]},"description":"Returns KPI counts for legacy inbound shipments aggregated across the specified integration instances:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `awaiting_over_14_days` — count of shipments in SHIPPED/IN_TRANSIT/DELIVERED/CHECKED_IN/RECEIVING status whose cached_shipment_date is older than 14 days.\n- `discrepancies` — currently hardcoded to 0 (placeholder).\n- `errored` — count of shipments in ERROR status or with a non-empty errorLog.\n\nArchived shipments (`archived_at IS NOT NULL`) are excluded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/legacy-inbound-shipments/kpi-stats","host":["{{baseUrl}}"],"path":["api","amazon","unified","legacy-inbound-shipments","kpi-stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"awaiting_over_14_days\": 7,\n    \"discrepancies\": 0,\n    \"errored\": 3\n  },\n  \"message\": \"\",\n  \"status\": true\n}"}]},{"name":"List Discrepancies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Discrepancies\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Create Discrepancy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies"]},"description":"Create Discrepancy\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"Get Discrepancy","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Discrepancy\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Export Discrepancies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","export"]},"description":"Export Discrepancies\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Discrepancy Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/statistics","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","statistics"]},"description":"Get Discrepancy Statistics\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Recheck Discrepancy","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/recheck","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","recheck"],"variable":[{"key":"discrepancy","value":"","description":"The discrepancy ID."}]},"description":"Recheck Discrepancy\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Recheck All Discrepancies (Async)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/recheck-all-async","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","recheck-all-async"]},"description":"Recheck All Discrepancies (Async)\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Update Investigation Status","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/investigation-status","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","investigation-status"],"variable":[{"key":"discrepancy","value":"","description":"The discrepancy ID."}]},"description":"Update Investigation Status\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"investigation_status\": \"investigating\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Discrepancy Recheck Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/recheck-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","recheck-progress",":trackedJobLogId"],"variable":[{"key":"trackedJobLogId","value":"","description":"Tracked job log ID returned by the asynchronous recheck-all endpoint (tracked_job_log_id)"}]},"description":"Polls the progress of a queued discrepancy recheck background job. Start the job with POST /api/amazon/unified/discrepancies/recheck-all-async, which returns a tracked_job_log_id to use as the path parameter here.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response reports:\n- status: pending, processing, completed, failed, or cancelled\n- total_items / processed_items and progress_percentage (0-100)\n- results: aggregated recheck counters — by_status (resolved, deleted, still_exist, updated, skipped, failed) and by_reason_type (the same counters per discrepancy reason type, e.g. ledger_summary_mismatch)\n- messages: the latest progress message emitted by the job\n\nPoll this endpoint until status is completed, failed, or cancelled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/recheck-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","recheck-progress",":trackedJobLogId"],"variable":[{"key":"trackedJobLogId","value":"","description":"Tracked job log ID returned by the asynchronous recheck-all endpoint (tracked_job_log_id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"status\": \"processing\",\n    \"total_items\": 250,\n    \"processed_items\": 120,\n    \"progress_percentage\": 48,\n    \"results\": {\n      \"by_status\": {\n        \"resolved\": 34,\n        \"deleted\": 34,\n        \"still_exist\": 78,\n        \"updated\": 11,\n        \"skipped\": 8,\n        \"failed\": 0\n      },\n      \"by_reason_type\": {\n        \"ledger_summary_mismatch\": {\n          \"deleted\": 34,\n          \"still_exist\": 78,\n          \"updated\": 11,\n          \"skipped\": 0,\n          \"failed\": 0\n        },\n        \"internal_report_missing\": {\n          \"deleted\": 0,\n          \"still_exist\": 0,\n          \"updated\": 0,\n          \"skipped\": 8,\n          \"failed\": 0\n        }\n      }\n    },\n    \"messages\": \"Rechecking discrepancies\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Discrepancy Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","activity-log"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]},"description":"Returns the paginated activity log for a single FBA inventory ledger discrepancy, newest first. Each entry contains id, description, event (created / updated / deleted / bulk_upsert), properties (the recorded old and new attribute values plus the change source), causer_name (the user who made the change, null for system changes), and created_at (UTC).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters: page, per_page (default 15), filter[event], filter[source], filter[batch_uuid]."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","activity-log"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3021,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"properties\": {\n        \"old\": {\n          \"investigation_status\": \"new\"\n        },\n        \"attributes\": {\n          \"investigation_status\": \"investigating\"\n        },\n        \"source\": \"manual\"\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2026-06-18T09:41:32.000000Z\"\n    },\n    {\n      \"id\": 2874,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"properties\": {\n        \"attributes\": {\n          \"quantity\": -3,\n          \"reason_type\": \"ledger_summary_mismatch\",\n          \"event_type\": \"Shipments\"\n        },\n        \"source\": \"amazon_sync\"\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-05-15T02:10:44.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Discrepancy Detailed Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/detailed-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","detailed-data"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]},"description":"Returns a discrepancy together with the contextual data needed to investigate it. All dates are Y-m-d in the application timezone.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAlways included (when the discrepancy is linked to an FNSKU product):\n- discrepancy: the full discrepancy record\n- related_discrepancies: other discrepancies for the same FNSKU product within 10 days either side of the discrepancy date\n- summary_reports: the daily inventory ledger summary rows for the same window (starting/ending warehouse balances, receipts, customer shipments, customer returns, vendor returns, warehouse transfers, adjustments)\n- date_range: start_date, end_date and discrepancy_date of the window\n\nFor ledger_summary_mismatch discrepancies, also includes:\n- ledger_summary: the mismatched daily summary row\n- ledgers: the individual ledger events for the discrepancy date and event type\n- current_calculations: per event type (Receipts, Shipments, CustomerReturns, VendorReturns, WhseTransfers, Adjustments), the summary value vs the ledger total and the current difference\n\nFor internal_report_missing discrepancies, also includes:\n- summary_report_dates: a per-day existence map covering 30 days either side of the discrepancy date\n- summary_report_statistics: total_days, days_with_summary, days_missing and the date range\n- last_report_before_gap: the most recent summary row before the gap, when one exists"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/detailed-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","detailed-data"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"discrepancy\": {\n      \"id\": 4821,\n      \"integration_instance_id\": 3,\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"Amazon US\"\n      },\n      \"amazon_fnsku_product_id\": 1592,\n      \"amazon_fba_report_inventory_ledger_summary_id\": 88214,\n      \"fnsku\": \"X002ABCDE1\",\n      \"product\": {\n        \"id\": 731,\n        \"sku\": \"WIDGET-BLUE-M\",\n        \"name\": \"Blue Widget - Medium\"\n      },\n      \"location\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"discrepancy_date\": \"2026-05-14\",\n      \"reason_type\": \"ledger_summary_mismatch\",\n      \"event_type\": \"Shipments\",\n      \"quantity\": -3,\n      \"cogs\": 12.45,\n      \"extended_cogs\": -37.35,\n      \"reconciled_at\": null,\n      \"investigation_status\": \"investigating\",\n      \"notes\": \"Discrepancy in Shipments on 2026-05-14: Summary Report = -120, Ledgers = -117\",\n      \"investigation_notes\": \"Case 12345678901 opened with Amazon seller support\",\n      \"auto_resolved_at\": null,\n      \"status\": \"unreconciled\",\n      \"created_at\": \"2026-05-15T02:10:44.000Z\",\n      \"updated_at\": \"2026-06-18T09:41:32.000Z\"\n    },\n    \"related_discrepancies\": [\n      {\n        \"id\": 4821,\n        \"discrepancy_date\": \"2026-05-14\",\n        \"reason_type\": \"ledger_summary_mismatch\",\n        \"event_type\": \"Shipments\",\n        \"quantity\": -3,\n        \"cogs\": 12.45,\n        \"extended_cogs\": -37.35,\n        \"status\": \"unreconciled\",\n        \"notes\": \"Discrepancy in Shipments on 2026-05-14: Summary Report = -120, Ledgers = -117\",\n        \"is_current_discrepancy\": true\n      },\n      {\n        \"id\": 4836,\n        \"discrepancy_date\": \"2026-05-19\",\n        \"reason_type\": \"ledger_summary_mismatch\",\n        \"event_type\": \"Adjustments\",\n        \"quantity\": 1,\n        \"cogs\": 12.45,\n        \"extended_cogs\": 12.45,\n        \"status\": \"reconciled\",\n        \"notes\": \"Discrepancy in Adjustments on 2026-05-19: Summary Report = 1, Ledgers = 0\",\n        \"is_current_discrepancy\": false\n      }\n    ],\n    \"summary_reports\": [\n      {\n        \"id\": 88214,\n        \"date\": \"2026-05-14\",\n        \"starting_warehouse_balance\": 265,\n        \"ending_warehouse_balance\": 145,\n        \"in_transit_between_warehouses\": 8,\n        \"receipts\": 0,\n        \"customer_shipments\": -120,\n        \"customer_returns\": 2,\n        \"vendor_returns\": 0,\n        \"warehouse_transfer_in_out\": -2,\n        \"adjustments\": 0,\n        \"is_discrepancy_date\": true\n      },\n      {\n        \"id\": 88342,\n        \"date\": \"2026-05-15\",\n        \"starting_warehouse_balance\": 145,\n        \"ending_warehouse_balance\": 141,\n        \"in_transit_between_warehouses\": 8,\n        \"receipts\": 0,\n        \"customer_shipments\": -5,\n        \"customer_returns\": 1,\n        \"vendor_returns\": 0,\n        \"warehouse_transfer_in_out\": 0,\n        \"adjustments\": 0,\n        \"is_discrepancy_date\": false\n      }\n    ],\n    \"date_range\": {\n      \"start_date\": \"2026-05-04\",\n      \"end_date\": \"2026-05-24\",\n      \"discrepancy_date\": \"2026-05-14\"\n    },\n    \"ledger_summary\": {\n      \"id\": 88214,\n      \"date\": \"2026-05-14T00:00:00.000000Z\",\n      \"receipts\": 0,\n      \"customer_shipments\": -120,\n      \"customer_returns\": 2,\n      \"vendor_returns\": 0,\n      \"warehouse_transfer_in_out\": -2,\n      \"adjustments\": 0\n    },\n    \"ledgers\": [\n      {\n        \"id\": 771203,\n        \"event_type\": \"Shipments\",\n        \"quantity\": -2,\n        \"reference_id\": \"113-9876543-1234567\",\n        \"fulfillment_center\": \"TUL2\",\n        \"reason\": null,\n        \"event_datetime\": \"2026-05-14T16:22:05.000000Z\"\n      },\n      {\n        \"id\": 771208,\n        \"event_type\": \"Shipments\",\n        \"quantity\": -1,\n        \"reference_id\": \"112-4455667-8899001\",\n        \"fulfillment_center\": \"BNA2\",\n        \"reason\": null,\n        \"event_datetime\": \"2026-05-14T19:03:47.000000Z\"\n      }\n    ],\n    \"current_calculations\": {\n      \"Receipts\": {\n        \"summary_value\": 0,\n        \"ledger_value\": 0,\n        \"discrepancy\": 0\n      },\n      \"Shipments\": {\n        \"summary_value\": -120,\n        \"ledger_value\": -117,\n        \"discrepancy\": -3\n      },\n      \"CustomerReturns\": {\n        \"summary_value\": 2,\n        \"ledger_value\": 2,\n        \"discrepancy\": 0\n      },\n      \"VendorReturns\": {\n        \"summary_value\": 0,\n        \"ledger_value\": 0,\n        \"discrepancy\": 0\n      },\n      \"WhseTransfers\": {\n        \"summary_value\": -2,\n        \"ledger_value\": -2,\n        \"discrepancy\": 0\n      },\n      \"Adjustments\": {\n        \"summary_value\": 0,\n        \"ledger_value\": 0,\n        \"discrepancy\": 0\n      }\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Discrepancy Impact Analysis","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/impact-analysis","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","impact-analysis"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]},"description":"Compares SKU.io's cost-layer-derived inventory position for the discrepancy's FNSKU product against Amazon's daily inventory ledger summary balances, so you can see whether the discrepancy still affects on-hand inventory.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns an impact block for the discrepancy date and, when a more recent summary row exists, a second impact block for the most recent summary date (most_recent_date_impact is null when the discrepancy date is already the latest, or when no summary exists for that date). Each impact block contains: warehouse_qty, in_transit_qty and total_qty (SKU.io side), summary_warehouse_qty, summary_in_transit_qty and summary_total_qty (Amazon ledger summary side), and the calculated warehouse_discrepancy, in_transit_discrepancy and total_discrepancy differences.\n\nReturns 400 when the discrepancy has no linked FNSKU product. Dates are Y-m-d."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/impact-analysis","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","impact-analysis"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"discrepancy_date\": \"2026-05-14\",\n    \"discrepancy_date_impact\": {\n      \"warehouse_qty\": 142,\n      \"in_transit_qty\": 8,\n      \"total_qty\": 150,\n      \"summary_warehouse_qty\": 145,\n      \"summary_in_transit_qty\": 8,\n      \"summary_total_qty\": 153,\n      \"warehouse_discrepancy\": -3,\n      \"in_transit_discrepancy\": 0,\n      \"total_discrepancy\": -3\n    },\n    \"most_recent_summary_date\": \"2026-07-05\",\n    \"most_recent_date_impact\": {\n      \"warehouse_qty\": 117,\n      \"in_transit_qty\": 12,\n      \"total_qty\": 129,\n      \"summary_warehouse_qty\": 120,\n      \"summary_in_transit_qty\": 12,\n      \"summary_total_qty\": 132,\n      \"warehouse_discrepancy\": -3,\n      \"in_transit_discrepancy\": 0,\n      \"total_discrepancy\": -3\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Related Discrepancy Ledgers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/related-ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","related-ledgers"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]},"description":"Returns the paginated individual ledger events recorded for the discrepancy's FNSKU product around the discrepancy date (default: 7 days either side, adjustable with days_range), newest first. Useful for spotting the specific ledger rows behind a summary mismatch.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row contains: id, date (Y-m-d), event_datetime (UTC), event_type (Adjustments, CustomerReturns, Receipts, Shipments, VendorReturns, WhseTransfers), quantity, reference_id (e.g. the Amazon order ID or shipment reference), fulfillment_center, reason, status (reconciled or unreconciled), reconciled_at, and the linked cost-layer values cogs, extended_cogs and fifo_id (null when the event has no cost layer yet).\n\nQuery parameters: page, per_page (default 15), days_range (default 7), event_type. Returns an empty page when the discrepancy has no linked FNSKU product."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/related-ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","related-ledgers"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 771208,\n      \"date\": \"2026-05-14\",\n      \"event_datetime\": \"2026-05-14T19:03:47.000000Z\",\n      \"event_type\": \"Shipments\",\n      \"quantity\": -1,\n      \"reference_id\": \"112-4455667-8899001\",\n      \"fulfillment_center\": \"BNA2\",\n      \"reason\": null,\n      \"status\": \"reconciled\",\n      \"reconciled_at\": \"2026-05-16T04:12:09.000000Z\",\n      \"cogs\": 12.45,\n      \"extended_cogs\": -12.45,\n      \"fifo_id\": 30412\n    },\n    {\n      \"id\": 771203,\n      \"date\": \"2026-05-14\",\n      \"event_datetime\": \"2026-05-14T16:22:05.000000Z\",\n      \"event_type\": \"Shipments\",\n      \"quantity\": -2,\n      \"reference_id\": \"113-9876543-1234567\",\n      \"fulfillment_center\": \"TUL2\",\n      \"reason\": null,\n      \"status\": \"unreconciled\",\n      \"reconciled_at\": null,\n      \"cogs\": null,\n      \"extended_cogs\": null,\n      \"fifo_id\": null\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/related-ledgers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/related-ledgers?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/related-ledgers?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/amazon/unified/discrepancies/4821/related-ledgers\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Update Discrepancy Investigation Notes","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/investigation-notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","investigation-notes"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]},"description":"Updates the free-text investigation notes on a single discrepancy. Send investigation_notes as a string of up to 5000 characters, or null to clear the notes. The investigation status is not changed by this endpoint (use the investigation-status endpoints for that).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the updated discrepancy record.","body":{"mode":"raw","raw":"{\n  \"investigation_notes\": \"Case 12345678901 opened with Amazon seller support on 2026-06-18. Awaiting reimbursement decision.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/{discrepancy}/investigation-notes","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies",":discrepancy","investigation-notes"],"variable":[{"key":"discrepancy","value":"","description":"Discrepancy ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"integration_instance_id\": 3,\n    \"amazon_fnsku_product_id\": 1592,\n    \"amazon_fba_report_inventory_ledger_summary_id\": 88214,\n    \"fnsku\": \"X002ABCDE1\",\n    \"location\": \"US\",\n    \"disposition\": \"SELLABLE\",\n    \"discrepancy_date\": \"2026-05-14\",\n    \"reason_type\": \"ledger_summary_mismatch\",\n    \"event_type\": \"Shipments\",\n    \"quantity\": -3,\n    \"cogs\": 12.45,\n    \"extended_cogs\": -37.35,\n    \"reconciled_at\": null,\n    \"investigation_status\": \"investigating\",\n    \"notes\": \"Discrepancy in Shipments on 2026-05-14: Summary Report = -120, Ledgers = -117\",\n    \"investigation_notes\": \"Case 12345678901 opened with Amazon seller support\",\n    \"auto_resolved_at\": null,\n    \"status\": \"unreconciled\",\n    \"created_at\": \"2026-05-15T02:10:44.000Z\",\n    \"updated_at\": \"2026-06-18T09:41:32.000Z\"\n  },\n  \"message\": \"Investigation notes updated\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Update Discrepancy Investigation Status","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/bulk-investigation-status","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","bulk-investigation-status"]},"description":"Sets the investigation status on multiple discrepancies in one call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- discrepancy_ids (required, array of integers): IDs of existing discrepancies to update (min 1)\n- investigation_status (required, string): one of new, investigating, case_opened, reimbursed, written_off, resolved\n- investigation_notes (optional, string, max 5000): when provided, the same notes are written to every selected discrepancy\n\nRuns synchronously and returns a message with the number of discrepancies updated.","body":{"mode":"raw","raw":"{\n  \"discrepancy_ids\": [\n    4821,\n    4836,\n    4901\n  ],\n  \"investigation_status\": \"investigating\",\n  \"investigation_notes\": \"Batch review 2026-07-06: escalated to Amazon seller support.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/bulk-investigation-status","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","bulk-investigation-status"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Updated investigation status to investigating for 3 discrepancies\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Recheck Discrepancies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/bulk-recheck","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","bulk-recheck"]},"description":"Re-evaluates the selected discrepancies against the current ledger summary and ledger event data, synchronously (results are returned in the same request).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- discrepancy_ids (required, array of integers): IDs of existing discrepancies to recheck (min 1)\n\nOnly ledger_summary_mismatch discrepancies are rechecked; other reason types (and rows whose summary no longer exists) are counted as skipped. For each rechecked row: if the summary-vs-ledger difference is now zero the discrepancy is deleted (and the product's cost history is recalculated when needed); if the difference changed, the discrepancy's quantity and notes are updated in place.\n\nReturns counters: resolved, deleted, still_exist, updated, skipped.","body":{"mode":"raw","raw":"{\n  \"discrepancy_ids\": [\n    4821,\n    4836,\n    4901,\n    4922,\n    4930,\n    4954\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/bulk-recheck","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","bulk-recheck"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"resolved\": 2,\n    \"deleted\": 2,\n    \"still_exist\": 3,\n    \"updated\": 1,\n    \"skipped\": 1\n  },\n  \"message\": \"Rechecked 6 discrepancies\",\n  \"status\": \"success\"\n}"}]},{"name":"Recheck All Discrepancies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/recheck-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","recheck-all"]},"description":"Re-evaluates every ledger_summary_mismatch discrepancy matching the filters against the current ledger summary and ledger event data. This variant runs synchronously in the request — with large numbers of discrepancies it can be slow; prefer POST /api/amazon/unified/discrepancies/recheck-all-async, which queues a background job and returns a tracked_job_log_id for polling progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional):\n- include_reconciled (boolean, default false): also recheck discrepancies that have already been reconciled\n- integration_instance_ids (string): comma-separated integration instance IDs to scope the recheck (e.g. \"1,3\"); omit for all instances\n\nFor each rechecked row: if the summary-vs-ledger difference is now zero the discrepancy is deleted (and the product's cost history is recalculated when needed); if the difference changed, the quantity and notes are updated in place. Returns counters (resolved, deleted, still_exist, updated, skipped), or a message-only response when no discrepancies match the criteria.","body":{"mode":"raw","raw":"{\n  \"include_reconciled\": false,\n  \"integration_instance_ids\": \"1,3\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/discrepancies/recheck-all","host":["{{baseUrl}}"],"path":["api","amazon","unified","discrepancies","recheck-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"resolved\": 34,\n    \"deleted\": 34,\n    \"still_exist\": 78,\n    \"updated\": 11,\n    \"skipped\": 8\n  },\n  \"message\": \"Rechecked 120 discrepancies\",\n  \"status\": \"success\"\n}"}]},{"name":"List Financial Event Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Financial Event Groups\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Financial Event Group","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get Financial Event Group\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Export Financial Event Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","export"]},"description":"Export Financial Event Groups\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Generate Accounting Transactions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/{financialEventGroup}/generate-accounting-transactions","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups",":financialEventGroup","generate-accounting-transactions"],"variable":[{"key":"financialEventGroup","value":"","description":"The financial event group ID."}]},"description":"Generate Accounting Transactions\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Delete Accounting Transactions","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/{financialEventGroup}/accounting-transactions","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups",":financialEventGroup","accounting-transactions"],"variable":[{"key":"financialEventGroup","value":"","description":"The financial event group ID."}]},"description":"Delete Accounting Transactions\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Generate","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-generate","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-generate"]},"description":"Bulk Generate\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"financial_event_group_ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Base Currency Rate","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/{financialEventGroup}/base-currency-rate","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups",":financialEventGroup","base-currency-rate"],"variable":[{"key":"financialEventGroup","value":"","description":"The financial event group ID."}]},"description":"Update Base Currency Rate\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"base_currency_rate\": 1.25,\n  \"deposit_amount\": null\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Bulk Manage Preflight for Financial Event Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-manage/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-manage","preflight"]},"description":"Returns a read-only preview for the Bulk Manage Financial Event Groups action, without making any changes. Financial event groups are Amazon settlement (bank transaction) groupings used to generate accounting transactions in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains:\n- `ready_groups_count` - the number of financial event groups currently eligible (\"ready\") for accounting transaction generation.\n- `transactions` - every existing accounting transaction linked to a financial event group (`source_type` = `group`) or to a settlement landed-cost bill (`source_type` = `landed_cost_bill`). Each entry includes the transaction type, total, reference, whether it is pushed to an external accounting integration (`has_integration_link`), and the Amazon financial event group identifier it belongs to (`group_financial_event_group_id`).\n\nUse this preview to decide which transaction IDs to pass to `POST /api/amazon/unified/financial-event-groups/bulk-manage` and whether to regenerate afterwards. Runs synchronously.\n\nQuery parameters:\n- `integration_instance_ids` (optional) - comma-separated integration instance IDs to scope the preview."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-manage/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-manage","preflight"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ready_groups_count\": 4,\n    \"transactions\": [\n      {\n        \"id\": 8123,\n        \"type\": \"sales_order_invoice\",\n        \"total\": 15321.44,\n        \"reference\": \"16130199621 - Sales Revenue - 8123\",\n        \"has_integration_link\": false,\n        \"integration_link_type\": null,\n        \"source_type\": \"group\",\n        \"source_id\": 42,\n        \"group_financial_event_group_id\": \"16130199621\"\n      },\n      {\n        \"id\": 8124,\n        \"type\": \"bill\",\n        \"total\": 2140.12,\n        \"reference\": \"16130199621 - Amazon Fees - 8124\",\n        \"has_integration_link\": true,\n        \"integration_link_type\": \"invoice\",\n        \"source_type\": \"landed_cost_bill\",\n        \"source_id\": 913,\n        \"group_financial_event_group_id\": \"16130199621\"\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Manage Financial Event Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-manage","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-manage"]},"description":"Bulk manages accounting transactions for Amazon financial event groups (settlement/bank-transaction groupings): selectively deletes the specified accounting transactions (including their lines, and clearing settlement-data links back to them), then optionally generates accounting transactions for every eligible (\"ready\") group.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns synchronously in the request - this endpoint does NOT queue a background job; the summary in the response reflects completed work.\n\nBody fields:\n- `transaction_ids_to_delete` (optional, array of integers) - accounting transaction IDs to delete. Use `GET .../bulk-manage/preflight` to list candidates.\n- `confirmation` (optional, string) - must be exactly `DELETE` when any selected transaction is linked to an external accounting integration; otherwise the request fails with 422.\n- `generate` (optional, boolean, default false) - when true, generates accounting transactions for all ready groups after the deletions.\n- `integration_instance_ids` (optional, array of integers or comma-separated string) - scopes the generation step to specific Amazon integration instances.","body":{"mode":"raw","raw":"{\n  \"transaction_ids_to_delete\": [\n    8123,\n    8124\n  ],\n  \"confirmation\": \"DELETE\",\n  \"generate\": true,\n  \"integration_instance_ids\": [\n    1,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-manage","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-manage"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": 2,\n    \"deleted_had_links\": 1,\n    \"generated\": [\n      {\n        \"id\": 42,\n        \"group_id\": \"16130199621\"\n      },\n      {\n        \"id\": 45,\n        \"group_id\": \"16171123908\"\n      }\n    ],\n    \"failed\": [\n      {\n        \"id\": 47,\n        \"group_id\": \"16204581122\",\n        \"error\": \"Cannot generate accounting transactions. Blocked by: All lines mapped\"\n      }\n    ],\n    \"summary\": {\n      \"deleted\": 2,\n      \"generated\": 2,\n      \"failed\": 1\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Bulk Regenerate Preflight for Financial Event Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-regenerate/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-regenerate","preflight"]},"description":"Returns a read-only impact summary for the Bulk Regenerate Accounting Transactions action, without making any changes. It inspects every financial event group that currently has accounting transactions and reports:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `total` - number of groups that have accounting transactions.\n- `eligible` - groups whose transactions can be safely deleted and regenerated (none are linked to an external accounting integration).\n- `has_integration_links` - groups that will be SKIPPED by the bulk regenerate because one or more of their transactions were pushed to an accounting integration (each with its internal `id`, the Amazon `group_id`, and `linked_count`).\n\nRuns synchronously.\n\nQuery parameters:\n- `integration_instance_ids` (optional) - comma-separated integration instance IDs to scope the preview."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-regenerate/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-regenerate","preflight"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 12,\n    \"eligible\": 10,\n    \"has_integration_links\": [\n      {\n        \"id\": 42,\n        \"group_id\": \"16130199621\",\n        \"linked_count\": 2\n      },\n      {\n        \"id\": 51,\n        \"group_id\": \"16171123908\",\n        \"linked_count\": 1\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Regenerate Accounting Transactions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-regenerate","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-regenerate"]},"description":"Deletes and regenerates accounting transactions for every Amazon financial event group that currently has them. Groups with transactions linked to an external accounting integration are skipped (they are never deleted by this action). Use `GET .../bulk-regenerate/preflight` first to see how many groups are eligible and which will be skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns synchronously in the request - this endpoint does NOT queue a background job; the response summary reflects completed work.\n\nBody fields:\n- `confirmation` (required, string) - must be exactly `YES`.\n- `integration_instance_ids` (optional, array of integers or comma-separated string) - scopes the operation to specific Amazon integration instances.","body":{"mode":"raw","raw":"{\n  \"confirmation\": \"YES\",\n  \"integration_instance_ids\": [\n    1,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/bulk-regenerate","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","bulk-regenerate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"regenerated\": [\n      {\n        \"id\": 42,\n        \"group_id\": \"16130199621\"\n      },\n      {\n        \"id\": 45,\n        \"group_id\": \"16171123908\"\n      }\n    ],\n    \"skipped\": [\n      {\n        \"id\": 51,\n        \"group_id\": \"16204581122\",\n        \"reason\": \"Has integration-linked accounting transactions\"\n      }\n    ],\n    \"failed\": [],\n    \"summary\": {\n      \"total\": 3,\n      \"regenerated\": 2,\n      \"skipped\": 1,\n      \"failed\": 0\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Purge Pre-Start Preflight for Financial Event Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/purge-pre-start/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","purge-pre-start","preflight"]},"description":"Dry run of the purge-pre-start action: lists the Amazon financial event groups whose settlement period starts BEFORE the account's inventory start date. These are historical records that will never have matching settlement reports imported. No changes are made.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains:\n- `purged` - the number of groups that WOULD be deleted (dry-run count).\n- `groups` - details for each group: internal `id`, Amazon `group_id`, integration name, period `start_date` (ISO 8601), and how many settlement data rows and accounting transactions it currently has.\n- `inventory_start_date` - the account's inventory start date (ISO 8601, UTC) used as the cutoff.\n- `dry_run` - always true for this endpoint.\n\nQuery parameters:\n- `integration_instance_ids` (optional) - comma-separated integration instance IDs to scope the preview."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/purge-pre-start/preflight","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","purge-pre-start","preflight"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"purged\": 2,\n    \"groups\": [\n      {\n        \"id\": 7,\n        \"group_id\": \"14988201455\",\n        \"integration\": \"Amazon US\",\n        \"start_date\": \"2023-11-02T00:00:00+00:00\",\n        \"settlement_data_count\": 1542,\n        \"accounting_transactions_count\": 0\n      },\n      {\n        \"id\": 8,\n        \"group_id\": \"15012349876\",\n        \"integration\": \"Amazon CA\",\n        \"start_date\": \"2023-11-16T00:00:00+00:00\",\n        \"settlement_data_count\": 388,\n        \"accounting_transactions_count\": 0\n      }\n    ],\n    \"inventory_start_date\": \"2024-01-01T00:00:00+00:00\",\n    \"dry_run\": true\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Purge Pre-Start Financial Event Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/purge-pre-start","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","purge-pre-start"]},"description":"Queues a background job that deletes every Amazon financial event group (settlement transaction) whose settlement period starts BEFORE the account's inventory start date, along with its settlement data. These historical records predate inventory tracking and will never have matching settlement reports. Run `GET .../purge-pre-start/preflight` first to review exactly which groups will be removed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe deletion happens asynchronously after this request returns; the response only confirms that the background job was dispatched (no job id is returned).\n\nBody fields:\n- `confirmation` (required, string) - must be exactly `PURGE`.\n- `integration_instance_ids` (optional, array of integers or comma-separated string) - scopes the purge to specific Amazon integration instances.","body":{"mode":"raw","raw":"{\n  \"confirmation\": \"PURGE\",\n  \"integration_instance_ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/financial-event-groups/purge-pre-start","host":["{{baseUrl}}"],"path":["api","amazon","unified","financial-event-groups","purge-pre-start"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"message\": \"Purge job has been dispatched. Settlement transactions will be deleted in the background.\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Reports","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports?page=1&per_page=10&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Reports\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId"],"variable":[{"key":"reportId","value":"","description":"The report ID."}]},"description":"Get Report\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Report Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/statistics?integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports","statistics"],"query":[{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"Get Report Statistics\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Available Report Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/available-types","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports","available-types"]},"description":"Get Available Report Types\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Process Report","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/process","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","process"],"variable":[{"key":"reportId","value":"","description":"The report ID."}]},"description":"Process Report\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Request Raw Data Download","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/request-raw-data-download","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","request-raw-data-download"],"variable":[{"key":"reportId","value":"","description":"ID of the Amazon report to download raw data for"}]},"description":"Queues an asynchronous a background job to fetch the report's raw data from the SP-API. The job broadcasts an `amazon.report-raw-data.ready` event (status `ready` or `failed`) on the requesting user's private channel (`App.Models.User.{tenantId}.{userId}`) when it finishes, so the SPA can refetch the raw data without polling. Returns immediately with 200 once the job is dispatched, or 404 if the report does not exist.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/request-raw-data-download","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","request-raw-data-download"],"variable":[{"key":"reportId","value":"","description":"ID of the Amazon report to download raw data for"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Raw data download started. This page will update automatically when it is ready.\"\n}"}]},{"name":"Get Report Raw Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/raw-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","raw-data"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]},"description":"Returns the raw file content of a downloaded Amazon SP-API report as a string, together with its stored filename. Amazon reports are typically tab-separated (TSV) text.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe raw file must already have been downloaded from Amazon (see `POST .../reports/:reportId/request-raw-data-download`). Returns 404 when the report does not exist, the file has not been downloaded yet, or the file exceeds the 50 MB safety limit for in-memory loading."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/raw-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","raw-data"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Success\",\n  \"data\": {\n    \"raw_data\": \"Date\\tFNSKU\\tASIN\\tMSKU\\tTitle\\tEvent Type\\tReference ID\\tQuantity\\tFulfillment Center\\tDisposition\\tReason\\tCountry\\n2026-05-14\\tX002QK7F5T\\tB08XYZL4M2\\tWIDGET-BLK-12\\tWidget Pro 12-Pack, Black\\tShipments\\tDnMKQ8pnN\\t-2\\tONT8\\tSELLABLE\\t\\tUS\",\n    \"filename\": \"1466394018495.tsv\"\n  }\n}"}]},{"name":"List Report Associated Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/associated-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","associated-data"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]},"description":"Returns the paginated data rows that were imported into SKU.io from a specific Amazon SP-API report. Currently supported for ledger-based report types (inventory ledger detail, FBA inventory, removal orders and removal shipments reports); for those the response contains the Amazon inventory ledger entries created from the report, sorted by event date descending. Report types without associated data return 422.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- `page` (optional, default 1) and `per_page` (optional, default 15) - standard pagination.\n- `filter[search]` (optional) - matches ledger ID exactly, or event type / reference ID / fulfillment center partially.\n- `filter[date_from]` / `filter[date_to]` (optional) - event date range, format m/d/Y; invalid dates are ignored.\n\nEach row includes reconciliation state (`reconciled_quantity`, `unreconciled_quantity`, `status` of `reconciled` or `unreconciled`) and FIFO costing fields (`fifo_id`, `cogs`, `extended_cogs`) when a FIFO layer is linked."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/associated-data","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","associated-data"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"checksum\": \"c0b7d1f2a3e45f6890ab12cd34ef5678\",\n      \"integration_instance_id\": 3,\n      \"amazon_product_id\": 4521,\n      \"amazon_report_id\": 512,\n      \"errorLog\": null,\n      \"date\": \"2026-05-14\",\n      \"blocked_by_ledger_id\": null,\n      \"event_datetime\": \"2026-05-14T10:22:00.000000Z\",\n      \"fnsku\": \"X002QK7F5T\",\n      \"country\": \"US\",\n      \"disposition\": \"SELLABLE\",\n      \"asin\": \"B08XYZL4M2\",\n      \"msku\": \"WIDGET-BLK-12\",\n      \"title\": \"Widget Pro 12-Pack, Black\",\n      \"event_type\": \"Shipments\",\n      \"reference_id\": \"DnMKQ8pnN\",\n      \"quantity\": -2,\n      \"fulfillment_center\": \"ONT8\",\n      \"reason\": null,\n      \"reconciled_quantity\": 2,\n      \"unreconciled_quantity\": 0,\n      \"last_reconciliation_attempted_at\": \"2026-05-15T02:10:11.000000Z\",\n      \"reconciled_at\": \"2026-05-15T02:10:11.000000Z\",\n      \"status\": \"reconciled\",\n      \"created_at\": \"2026-05-15T02:00:41.000000Z\",\n      \"updated_at\": \"2026-05-15T02:10:11.000000Z\",\n      \"fnsku_product_id\": 55,\n      \"fifo_id\": 7742,\n      \"cogs\": 4.25,\n      \"extended_cogs\": 8.5,\n      \"error_count\": 0,\n      \"report_line_number\": 118,\n      \"is_from_reattempted_report\": false\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=1\",\n  \"from\": 1,\n  \"last_page\": 23,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=23\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/unified/reports/512/associated-data\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 341\n}"}]},{"name":"Get Report Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","status"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]},"description":"Returns the current lifecycle status of an Amazon SP-API report record for progress monitoring/polling.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSide effect: before responding, SKU.io attempts to sync the report record from Amazon so the returned state is current (best-effort - if the Amazon call fails, the stored state is returned).\n\nResponse `data` fields:\n- `status` - one of `pending`, `in_progress`, `retrying`, `downloading`, `processing`, `completed`, `cancelled`, `failed`.\n- `message` - human-readable progress message (includes the Amazon report ID when assigned).\n- `progress` - 0-100 progress indicator.\n- `processing_status` - raw Amazon processing status (`IN_QUEUE`, `IN_PROGRESS`, `DONE`, `CANCELLED`, `FATAL`, or the internal `RETRY`).\n- `has_raw_data` - whether the report file has been downloaded.\n- `is_processed` - whether the report data has been imported into SKU.io.\n- `created_time`, `processed_at` - ISO 8601 timestamps (nullable)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","status"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Success\",\n  \"data\": {\n    \"status\": \"in_progress\",\n    \"message\": \"Amazon is generating the report... (Report ID: 1466394018495)\",\n    \"progress\": 25,\n    \"report_id\": 512,\n    \"processing_status\": \"IN_PROGRESS\",\n    \"has_raw_data\": false,\n    \"is_processed\": false,\n    \"created_time\": \"2026-06-02T04:15:11+00:00\",\n    \"processed_at\": null\n  }\n}"}]},{"name":"Clone Report","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/clone","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","clone"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]},"description":"Clones an existing Amazon SP-API report record: immediately requests a NEW report from Amazon with the same report type, data date range, marketplaces and options as the original, but with duplicate protection enabled (`disallow_duplicates` = true, so rows already imported from earlier reports are skipped when the clone is processed).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis calls the Amazon SP-API synchronously to create the report request; the report itself is then generated by Amazon asynchronously - poll `GET .../reports/:reportId/status` on the returned record to track it.\n\nNo request body. Returns the newly created report record. Returns 404 when the source report does not exist and 400 when Amazon rejects the request (for example when a report of the same type is already in progress)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/clone","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","clone"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Report cloned successfully\",\n  \"data\": {\n    \"integration_instance_id\": 3,\n    \"reportType\": \"GET_LEDGER_DETAIL_VIEW_DATA\",\n    \"dataStartTime\": \"2026-05-01T00:00:00.000000Z\",\n    \"dataEndTime\": \"2026-05-31T23:59:59.000000Z\",\n    \"marketplaceIds\": [\n      \"ATVPDKIKX0DER\"\n    ],\n    \"options\": null,\n    \"reportId\": \"1466512018622\",\n    \"processingStatus\": \"IN_QUEUE\",\n    \"createdTime\": \"2026-06-03T09:41:52.000000Z\",\n    \"disallow_duplicates\": true,\n    \"updated_at\": \"2026-06-03T09:41:52.000000Z\",\n    \"created_at\": \"2026-06-03T09:41:52.000000Z\",\n    \"id\": 519\n  }\n}"}]},{"name":"Cancel Report","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/cancel","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","cancel"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]},"description":"Cancels an in-progress Amazon SP-API report record in SKU.io by marking its processing status as `CANCELLED`. This is a local status change only - it does not cancel the report request on Amazon's side. Use it to unblock creating a new report request of the same type when a previous request is stuck.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Returns the updated report record."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/reports/{reportId}/cancel","host":["{{baseUrl}}"],"path":["api","amazon","unified","reports",":reportId","cancel"],"variable":[{"key":"reportId","value":"512","description":"The SKU.io internal report record ID (not the Amazon report ID)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Report cancelled\",\n  \"data\": {\n    \"id\": 512,\n    \"integration_instance_id\": 3,\n    \"reportId\": \"1466394018495\",\n    \"reportType\": \"GET_LEDGER_DETAIL_VIEW_DATA\",\n    \"dataStartTime\": \"2026-05-01T00:00:00.000000Z\",\n    \"dataEndTime\": \"2026-05-31T23:59:59.000000Z\",\n    \"options\": null,\n    \"reportScheduledId\": null,\n    \"createdTime\": \"2026-06-02T04:15:11.000000Z\",\n    \"processingStatus\": \"CANCELLED\",\n    \"processingStartTime\": null,\n    \"processingEndTime\": null,\n    \"marketplaceIds\": [\n      \"ATVPDKIKX0DER\"\n    ],\n    \"reportDocumentId\": null,\n    \"filename\": null,\n    \"processed_at\": null,\n    \"disallow_duplicates\": false,\n    \"created_at\": \"2026-06-02T04:15:11.000000Z\",\n    \"updated_at\": \"2026-06-03T10:02:07.000000Z\"\n  }\n}"}]},{"name":"List Settlement Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-data?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-data"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Settlement Data\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Settlement Data Lookups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-data/lookups","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-data","lookups"]},"description":"Get Settlement Data Lookups\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"List Type Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Type Mapping Lookups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/lookups","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","lookups"]},"description":"Get Type Mapping Lookups\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Assign Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","bulk-assign"]},"description":"Bulk Assign Type Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": []\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/export","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","export"]},"description":"Export Type Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Import Type Mappings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","import"]},"description":"Import Type Mappings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}}},{"name":"List Settlement Type Mapping Instances by Financial Code","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/instances?financial_code=Order: ItemFees - Commission","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","instances"],"query":[{"key":"financial_code","value":"Order: ItemFees - Commission","description":"Required. The settlement financial code to resolve, in the format \"{transaction_type}: {amount_type} - {amount_description}\" (e.g. \"Order: ItemFees - Commission\").","disabled":true}]},"description":"Returns the resolved settlement type mapping for a single financial code, per Amazon integration instance. Settlement type mappings map Amazon settlement fee/transaction types to nominal codes (and settlement mapping groups) used when generating accounting transactions; overrides are per-instance exceptions to the global mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOne row is returned per instance with the EFFECTIVE values - the per-instance override when one exists, otherwise the global default:\n- `integration_instance` - `{id, name}` of the Amazon integration instance.\n- `nominalCode` - resolved nominal code `{id, code, name}` or null when unmapped.\n- `mappingGroup` - resolved settlement mapping group `{id, name, document_type}` (document_type is `invoice` or `bill`) or null.\n- `is_override` - true when the row comes from a per-instance override rather than the global mapping.\n- `override_id` - the override record ID (use it with `DELETE .../overrides/:id`), or null.\n\nQuery parameters:\n- `financial_code` (required, string).\n- `integration_instance_ids[]` (optional, array of integers) - limit to specific instances."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/instances?financial_code=Order: ItemFees - Commission","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","instances"],"query":[{"key":"financial_code","value":"Order: ItemFees - Commission","description":"Required. The settlement financial code to resolve, in the format \"{transaction_type}: {amount_type} - {amount_description}\" (e.g. \"Order: ItemFees - Commission\").","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Amazon US\"\n      },\n      \"nominalCode\": {\n        \"id\": 45,\n        \"code\": \"4000\",\n        \"name\": \"Amazon Sales\"\n      },\n      \"mappingGroup\": {\n        \"id\": 3,\n        \"name\": \"Sales Revenue\",\n        \"document_type\": \"invoice\"\n      },\n      \"is_override\": false,\n      \"override_id\": null\n    },\n    {\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"Amazon CA\"\n      },\n      \"nominalCode\": {\n        \"id\": 61,\n        \"code\": \"5015\",\n        \"name\": \"Amazon Commission Fees\"\n      },\n      \"mappingGroup\": {\n        \"id\": 4,\n        \"name\": \"Amazon Fees\",\n        \"document_type\": \"bill\"\n      },\n      \"is_override\": true,\n      \"override_id\": 812\n    }\n  ]\n}"}]},{"name":"Create Settlement Type Mapping Override","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/overrides","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","overrides"]},"description":"Creates a per-instance override for a settlement financial code, replacing the global mapping for that Amazon integration instance only. If an override already exists for the same instance and financial code, it is updated in place (upsert). The global mapping row for the financial code must already exist - otherwise a 404 is returned.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOnly the keys present in the request body are applied to the override, so you can override just the nominal code, just the mapping group, or both.\n\nBody fields:\n- `integration_instance_id` (required, integer) - the Amazon integration instance the override applies to. Must exist.\n- `financial_code` (required, string) - format \"{transaction_type}: {amount_type} - {amount_description}\".\n- `nominal_code_id` (optional, integer or null) - nominal code to use for this instance. Must exist when provided.\n- `amazon_settlement_mapping_group_id` (optional, integer or null) - settlement mapping group to route this code to for this instance. Must exist when provided.\n\nReturns the created/updated override with its resolved `nominalCode` and `mappingGroup`.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 3,\n  \"financial_code\": \"Order: ItemFees - Commission\",\n  \"nominal_code_id\": 61,\n  \"amazon_settlement_mapping_group_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/overrides","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","overrides"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 812,\n    \"transaction_type\": \"Order\",\n    \"amount_type\": \"ItemFees\",\n    \"amount_description\": \"Commission\",\n    \"financial_code\": \"Order: ItemFees - Commission\",\n    \"typical_amount_sign\": \"-\",\n    \"amazon_settlement_mapping_group_id\": 4,\n    \"nominalCode\": {\n      \"id\": 61,\n      \"code\": \"5015\",\n      \"name\": \"Amazon Commission Fees\"\n    },\n    \"mappingGroup\": {\n      \"id\": 4,\n      \"name\": \"Amazon Fees\",\n      \"document_type\": \"bill\"\n    },\n    \"is_override\": false,\n    \"created_at\": \"2026-06-12T18:04:31.000000Z\",\n    \"updated_at\": \"2026-06-12T18:04:31.000000Z\"\n  },\n  \"message\": \"Override created successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Settlement Type Mapping Override","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/overrides/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","overrides",":id"],"variable":[{"key":"id","value":"812","description":"The override record ID (see override_id from the instances endpoint). Must be a per-instance override; global mappings cannot be deleted here."}]},"description":"Deletes a per-instance settlement type mapping override. The affected Amazon integration instance falls back to the global mapping for that financial code. Only override records (rows tied to an integration instance) can be deleted - passing the ID of a global mapping returns 404.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-type-mappings/overrides/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-type-mappings","overrides",":id"],"variable":[{"key":"id","value":"812","description":"The override record ID (see override_id from the instances endpoint). Must be a per-instance override; global mappings cannot be deleted here."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Override deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Fallback Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-fallback-settings","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-fallback-settings"]},"description":"Get Fallback Settings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Update Fallback Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-fallback-settings","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-fallback-settings"]},"description":"Update Fallback Settings\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}}},{"name":"List Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups"]},"description":"List Mapping Groups\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Create Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups"]},"description":"Create Mapping Group\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Update Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"settlementMappingGroup","value":"","description":"The settlement mapping group ID."}]},"description":"Update Mapping Group\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"name\": \"\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups/{settlementMappingGroup}","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups",":settlementMappingGroup"],"variable":[{"key":"settlementMappingGroup","value":"","description":"The settlement mapping group ID."}]},"description":"Delete Mapping Group\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Reorder Settlement Mapping Groups","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups","reorder"]},"description":"Reorders the global Amazon settlement mapping groups. Mapping groups control how settlement lines are grouped into generated accounting documents (each group produces one invoice or bill per settlement), and their order determines display/processing order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `ids` (required, array of integers, min 1) - settlement mapping group IDs in the desired order. Each ID must exist; the new sort order is assigned from the array position.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    4,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/unified/settlement-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","amazon","unified","settlement-mapping-groups","reorder"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Groups reordered successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get AWD initial inventory status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","status"]},"description":"Returns the AWD initial inventory setup status for each NA-region Amazon integration instance, including the as-of date (day before fba_inventory_tracking_start_date). The as-of date is converted from UTC to the app timezone for display.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/status","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","status"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"awd_sync_enabled\": true,\n      \"awd_initial_inventory_imported\": true,\n      \"awd_initial_inventory_confirmed_no_inventory\": false,\n      \"is_awd_sync_allowed\": true,\n      \"awd_access_denied\": false,\n      \"as_of_date\": \"2024-04-21\",\n      \"as_of_date_formatted\": \"Apr 21, 2024\",\n      \"fba_inventory_tracking_start_date\": \"2024-04-22\",\n      \"fba_inventory_tracking_start_date_formatted\": \"Apr 22, 2024\"\n    }\n  ]\n}"}]},{"name":"Get AWD initial inventory summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/summary","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","summary"]},"description":"Returns aggregated AWD initial inventory summary statistics (counts, totals, unique FNSKUs/countries) for each integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/summary","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"total_entries\": 124,\n      \"total_units\": 8420,\n      \"reconciled_entries\": 110,\n      \"unreconciled_entries\": 14,\n      \"unique_fnskus\": 95,\n      \"unique_countries\": 1\n    }\n  ]\n}"}]},{"name":"List AWD shipments (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments"]},"description":"Paginated AWD shipments across integration instances. Eager loads integrationInstance and items, and calls loadUnitQuantitiesForItems() per shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"shipment_id\": \"FBA15ABCD123\",\n      \"shipment_status\": \"SHIPPED\",\n      \"order_id\": \"ORD-99\",\n      \"items\": [],\n      \"sku_link\": null,\n      \"pending_inbound\": null,\n      \"destination_country\": \"US\",\n      \"destination_name\": \"Amazon Warehouse ABE2\",\n      \"origin_name\": \"Supplier ACME\",\n      \"origin_warehouse_id\": null,\n      \"origin_supplier_id\": 22,\n      \"origin_warehouse_name\": null,\n      \"origin_supplier_name\": \"ACME Co.\",\n      \"origin_address\": {\n        \"name\": \"Supplier ACME\",\n        \"addressLine1\": \"123 Main St\",\n        \"city\": \"Reno\",\n        \"stateOrRegion\": \"NV\",\n        \"countryCode\": \"US\",\n        \"postalCode\": \"89501\"\n      },\n      \"destination_address\": {\n        \"name\": \"Amazon Warehouse ABE2\",\n        \"addressLine1\": \"500 McCarthy Dr\",\n        \"city\": \"Lehigh Valley\",\n        \"stateOrRegion\": \"PA\",\n        \"countryCode\": \"US\",\n        \"postalCode\": \"18031\"\n      },\n      \"carrier_code\": \"UPS\",\n      \"tracking_id\": \"1Z999AA10123456784\",\n      \"external_reference_id\": null,\n      \"warehouse_reference_id\": null,\n      \"ship_by_date\": \"2024-05-15\",\n      \"api_created_at\": \"2024-04-22T07:00:00Z\",\n      \"api_updated_at\": \"2024-04-25T07:00:00Z\",\n      \"details_fetched_at\": \"2024-04-25T08:00:00.000000Z\",\n      \"received_quantity\": 0,\n      \"expected_quantity\": 100,\n      \"discrepancy_quantity\": 0,\n      \"received_quantity_details\": [],\n      \"expected_quantity_details\": [],\n      \"discrepancy_quantity_details\": [],\n      \"shipment_container_quantities\": [],\n      \"shipment_container_details\": [],\n      \"shipment_charges\": [],\n      \"is_active\": true,\n      \"is_completed\": false,\n      \"is_cancelled\": false,\n      \"is_processable\": true,\n      \"is_processed\": false,\n      \"needs_detail_sync\": false,\n      \"error_log\": null,\n      \"created_at\": \"2024-04-22T08:00:00.000000Z\",\n      \"updated_at\": \"2024-04-25T08:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 47,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Delete AWD shipments","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments"]},"description":"Deletes selected AWD shipments by IDs. Same validation pattern as process/unprocess: ids array OR apply_to_all + filters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 2 shipment(s)\",\n  \"data\": {\n    \"deleted\": 2\n  }\n}"}]},{"name":"Show AWD shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single AWD shipment with items, origin warehouse, origin supplier, integrationInstance, and full quantity/inventory data eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1001,\n    \"integration_instance_id\": 1,\n    \"integration_instance_name\": \"Amazon US\",\n    \"shipment_id\": \"FBA15ABCD123\",\n    \"shipment_status\": \"SHIPPED\",\n    \"order_id\": \"ORD-99\",\n    \"items\": [],\n    \"sku_link\": null,\n    \"pending_inbound\": null,\n    \"destination_country\": \"US\",\n    \"destination_name\": \"Amazon Warehouse ABE2\",\n    \"origin_name\": \"Supplier ACME\",\n    \"origin_warehouse_id\": null,\n    \"origin_supplier_id\": 22,\n    \"origin_warehouse_name\": null,\n    \"origin_supplier_name\": \"ACME Co.\",\n    \"origin_address\": {},\n    \"destination_address\": {},\n    \"carrier_code\": \"UPS\",\n    \"tracking_id\": \"1Z999AA10123456784\",\n    \"external_reference_id\": null,\n    \"warehouse_reference_id\": null,\n    \"ship_by_date\": \"2024-05-15\",\n    \"api_created_at\": \"2024-04-22T07:00:00Z\",\n    \"api_updated_at\": \"2024-04-25T07:00:00Z\",\n    \"details_fetched_at\": \"2024-04-25T08:00:00.000000Z\",\n    \"received_quantity\": 0,\n    \"expected_quantity\": 100,\n    \"discrepancy_quantity\": 0,\n    \"received_quantity_details\": [],\n    \"expected_quantity_details\": [],\n    \"discrepancy_quantity_details\": [],\n    \"shipment_container_quantities\": [],\n    \"shipment_container_details\": [],\n    \"shipment_charges\": [],\n    \"is_active\": true,\n    \"is_completed\": false,\n    \"is_cancelled\": false,\n    \"is_processable\": true,\n    \"is_processed\": false,\n    \"needs_detail_sync\": false,\n    \"error_log\": null,\n    \"created_at\": \"2024-04-22T08:00:00.000000Z\",\n    \"updated_at\": \"2024-04-25T08:00:00.000000Z\"\n  }\n}"}]},{"name":"List AWD ledgers (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers"]},"description":"Paginated AWD ledger entries across integration instances. Eager-loads integrationInstance, fnskuProduct.product, fifoLayer, fifoConsumptions, salesOrderLines.salesOrder/product, warehouseTransferLines.warehouseTransfer, fbaWarehouseTransfer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7777,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"checksum\": \"a1b2c3d4e5f6\",\n      \"date\": \"2024-05-01T07:00:00+00:00\",\n      \"fnsku\": \"X001ABCD23\",\n      \"asin\": \"B0ABCDEF12\",\n      \"msku\": \"SKU-001\",\n      \"title\": \"Example Product Title\",\n      \"event_type\": \"RECEIVED\",\n      \"reference_id\": \"FBA15ABCD123\",\n      \"quantity\": 100,\n      \"fulfillment_center\": \"AWD1\",\n      \"disposition\": \"SELLABLE\",\n      \"reason\": null,\n      \"reconciled_quantity\": 100,\n      \"unreconciled_quantity\": 0,\n      \"reconciled_at\": \"2024-05-02T08:00:00+00:00\",\n      \"is_reconciled\": true,\n      \"amazon_fnsku_product_id\": 401,\n      \"amazon_fifo_layer_id\": 9012,\n      \"fnsku_product\": {\n        \"id\": 401,\n        \"fnsku\": \"X001ABCD23\",\n        \"asin\": \"B0ABCDEF12\",\n        \"msku\": \"SKU-001\",\n        \"product_id\": 5005,\n        \"product\": {\n          \"id\": 5005,\n          \"sku\": \"SKU-001\",\n          \"name\": \"Example Product\"\n        }\n      },\n      \"fifo_layer\": {\n        \"id\": 9012,\n        \"quantity\": 100,\n        \"cogs\": 4.25,\n        \"fifo_layer_date\": \"2024-05-01T07:00:00+00:00\"\n      },\n      \"fifo_consumptions_count\": 0,\n      \"has_provisional_cogs\": false,\n      \"is_sales_order_type\": false,\n      \"is_linked_to_sales_order\": false,\n      \"sales_order_line\": null,\n      \"is_linked_to_warehouse_transfer\": false,\n      \"warehouse_transfer_line\": null,\n      \"created_at\": \"2024-05-02T08:00:00+00:00\",\n      \"updated_at\": \"2024-05-02T08:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 8,\n  \"per_page\": 15,\n  \"total\": 117,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Delete AWD ledgers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers"]},"description":"Deletes AWD ledger entries by IDs. Same validation pattern as other bulk ledger ops.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 AWD ledger entries deleted.\",\n  \"data\": {\n    \"count\": 2\n  }\n}"}]},{"name":"Refresh AWD shipments (dispatch jobs)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","refresh"]},"description":"Dispatches a background job for each instance. Skips non-NA region, AWD-sync-disabled, and AWD-access-denied instances. Blocks instances whose initial inventory has not been handled. The job fetches the shipment list, dispatches detail-fetch jobs, then auto-processes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/refresh","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD refresh jobs dispatched for 1 integration(s). Shipments will be synced and processed in the background.\",\n  \"data\": {\n    \"results\": [\n      {\n        \"integration_instance_id\": 1,\n        \"integration_instance_name\": \"Amazon US\",\n        \"status\": \"dispatched\",\n        \"message\": \"AWD refresh job dispatched\"\n      }\n    ],\n    \"summary\": {\n      \"total\": 1,\n      \"dispatched\": 1,\n      \"blocked\": 0,\n      \"skipped\": 0,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"Process AWD shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/process","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments","process"]},"description":"Processes selected AWD shipments by IDs (creates WT/PO links based on ship-from mappings). Pass ids: [...] for explicit selection, OR apply_to_all: true + filters: {...} to operate on every shipment matching the filter set. Validation: apply_to_all (sometimes|boolean), filters (required_if:apply_to_all,true|array), ids (required_without:apply_to_all|array), ids.* (integer).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"apply_to_all\": false,\n  \"ids\": [\n    1001,\n    1002,\n    1003\n  ],\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\",\n    \"process_status\": \"processable\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/process","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments","process"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Processed 3 shipment(s)\",\n  \"data\": {\n    \"shipments\": []\n  }\n}"}]},{"name":"List ship-from mappings (paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings"]},"description":"Paginated AWD/FBA ship-from mappings across integration instances. Eager loads integrationInstance and the polymorphic link (Supplier or Warehouse).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"name\": \"Supplier ACME\",\n      \"link_id\": 22,\n      \"link_type\": \"App\\\\Models\\\\Supplier\",\n      \"link_type_label\": \"Supplier\",\n      \"link_name\": \"ACME Co.\",\n      \"created_at\": \"2024-03-01T12:00:00+00:00\",\n      \"updated_at\": \"2024-04-12T08:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 28,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get AWD initial inventory details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/details?integration_instance_ids=1","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","details"],"query":[{"key":"integration_instance_ids","value":"1","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]},"description":"Returns detailed AWD initial inventory entries with their FIFO layer data (unit_cost, total_value, fifo_layer_id, cogs_source) for the specified integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/details?integration_instance_ids=1","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","details"],"query":[{"key":"integration_instance_ids","value":"1","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"entries\": [\n        {\n          \"id\": 501,\n          \"fnsku\": \"X001ABCD23\",\n          \"asin\": \"B0ABCDEF12\",\n          \"msku\": \"SKU-001\",\n          \"title\": \"Example Product Title\",\n          \"purchase_order_id\": null,\n          \"country\": \"US\",\n          \"date\": \"2024-04-21\",\n          \"ending_units\": 120,\n          \"package_quantity\": 10,\n          \"ending_warehouse_balance\": 120,\n          \"unit_cost\": 4.25,\n          \"total_value\": 510,\n          \"fifo_layer_id\": 9012,\n          \"cogs_source\": \"manual\",\n          \"reconciled_at\": \"2024-04-22T07:00:00+00:00\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Confirm no AWD initial inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/confirm-no-inventory?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","confirm-no-inventory"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]},"description":"Marks the specified integration instances as having no AWD initial inventory. Sets awd_initial_inventory_confirmed_no_inventory=true so AWD sync can proceed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/confirm-no-inventory?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","confirm-no-inventory"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Confirmed no initial inventory for 1 integration(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"integration_instance_id\": 1,\n        \"integration_instance_name\": \"Amazon US\",\n        \"status\": \"confirmed\",\n        \"message\": \"Confirmed no AWD initial inventory\"\n      }\n    ],\n    \"summary\": {\n      \"total\": 1,\n      \"confirmed\": 1\n    }\n  }\n}"}]},{"name":"Import AWD initial inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","import"]},"description":"Imports AWD initial inventory from a previously uploaded CSV file (AWD Inventory Ledger - Summary report). The integration instance is auto-detected from FNSKU data; integration_instance_id is used as a fallback if auto-detection fails. Required field: stored_name (string). Optional: integration_instance_id (integer). The endpoint validates that FNSKUs are mapped before proceeding.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"stored_name\": \"uploads/awd-initial-inventory-20260529-abcdef.csv\",\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD initial inventory import completed for Amazon US. 200 rows processed: 180 created, 10 duplicates, 5 invalid, 5 zero balance skipped. 180 FIFO layers created. 5400 total units.\",\n  \"data\": {\n    \"total_rows\": 200,\n    \"created\": 180,\n    \"skipped_duplicates\": 10,\n    \"skipped_invalid\": 5,\n    \"skipped_zero_balance\": 5,\n    \"fifo_layers_created\": 180,\n    \"total_units\": 5400,\n    \"errors\": []\n  }\n}"}]},{"name":"Delete AWD initial inventory","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]},"description":"Deletes all AWD initial inventory entries (and their FIFO layers) for the specified integration instances. Resets the awd_initial_inventory_imported and awd_initial_inventory_confirmed_no_inventory flags so initial inventory can be re-imported or re-confirmed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/initial-inventory?integration_instance_ids=1,2","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","initial-inventory"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Comma-separated integration instance IDs (REQUIRED).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted 124 AWD initial inventory entries\",\n  \"data\": {\n    \"results\": [\n      {\n        \"integration_instance_id\": 1,\n        \"integration_instance_name\": \"Amazon US\",\n        \"status\": \"deleted\",\n        \"deleted\": 124\n      }\n    ],\n    \"total_deleted\": 124\n  }\n}"}]},{"name":"Update AWD sync enabled","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/sync-enabled","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","sync-enabled"]},"description":"Enables or disables AWD sync per integration instance (stored in integration_settings, replaces the legacy AMAZON_AWD_SYNC_ENABLED env var). Required fields: integration_instance_ids (array of integers, min 1, each must exist in integration_instances.id), awd_sync_enabled (boolean).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    1,\n    2\n  ],\n  \"awd_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/sync-enabled","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","sync-enabled"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD sync enabled for 2 integration(s).\",\n  \"data\": {\n    \"results\": [\n      {\n        \"integration_instance_id\": 1,\n        \"integration_instance_name\": \"Amazon US\",\n        \"awd_sync_enabled\": true\n      },\n      {\n        \"integration_instance_id\": 2,\n        \"integration_instance_name\": \"Amazon CA\",\n        \"awd_sync_enabled\": true\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"awd_sync_enabled\": true\n    }\n  }\n}"}]},{"name":"Unprocess AWD shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments","unprocess"]},"description":"Unlinks (unprocesses) selected AWD shipments by IDs, clearing their sku_link. Same validation pattern as process: pass ids or use apply_to_all + filters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"apply_to_all\": false,\n  \"ids\": [\n    1001,\n    1002\n  ],\n  \"filters\": {\n    \"integration_instance_ids\": \"1\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/unprocess","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments","unprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Unprocessed 2 shipment(s)\",\n  \"data\": []\n}"}]},{"name":"Get eligible purchase orders for AWD shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/eligible-purchase-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","eligible-purchase-orders"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns the purchase orders eligible for linking to the given AWD shipment, with PO line summaries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/eligible-purchase-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","eligible-purchase-orders"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4001,\n      \"purchase_order_number\": \"PO-2024-001\",\n      \"purchase_order_date\": \"2024-03-15T00:00:00+00:00\",\n      \"supplier_id\": 22,\n      \"supplier_name\": \"ACME Co.\",\n      \"destination_warehouse\": \"AWD Origin Warehouse\",\n      \"order_status\": \"approved\",\n      \"receipt_status\": \"partial\",\n      \"total_quantity\": 500,\n      \"lines\": [\n        {\n          \"id\": 8801,\n          \"product_id\": 5005,\n          \"product_sku\": \"SKU-001\",\n          \"product_name\": \"Example Product\",\n          \"quantity\": 500,\n          \"received_quantity\": 100\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Link AWD shipment to purchase order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/link-purchase-order","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","link-purchase-order"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Links the AWD shipment to an existing purchase order. Required: purchase_order_id (integer, must exist in purchase_orders.id).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"purchase_order_id\": 4001\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/link-purchase-order","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","link-purchase-order"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipment linked to purchase order successfully.\",\n  \"data\": {\n    \"shipment\": {\n      \"id\": 1001,\n      \"shipment_id\": \"FBA15ABCD123\",\n      \"sku_link\": {\n        \"id\": 4001,\n        \"type\": \"App\\\\Models\\\\PurchaseOrder\",\n        \"name\": \"PO-2024-001\",\n        \"displayType\": \"Purchase Order\"\n      }\n    },\n    \"warnings\": []\n  }\n}"}]},{"name":"Unlink AWD shipment from purchase order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/unlink-purchase-order","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","unlink-purchase-order"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unlinks an AWD shipment from its linked purchase order, clearing the sku_link reference. No body required.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/shipments/{id}/unlink-purchase-order","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","shipments",":id","unlink-purchase-order"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipment unlinked from purchase order successfully.\",\n  \"data\": {\n    \"id\": 1001,\n    \"shipment_id\": \"FBA15ABCD123\",\n    \"sku_link\": null\n  }\n}"}]},{"name":"Import AWD ledger CSV","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","import"]},"description":"Imports an AWD ledger CSV file. Integration instance is auto-detected from the FNSKU/Reference ID data in the CSV. Required: stored_name (string). Optional: integration_instance_id (integer) as fallback when auto-detection fails. Checks for unmapped FNSKUs before processing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"stored_name\": \"uploads/awd-ledger-20260529-abcdef.csv\",\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/import","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD ledger import completed. 500 rows processed: 480 created, 15 duplicates skipped, 5 invalid skipped, 460 reconciled.\",\n  \"data\": {\n    \"total_rows\": 500,\n    \"created\": 480,\n    \"skipped_duplicates\": 15,\n    \"skipped_invalid\": 5,\n    \"reconciled\": 460,\n    \"errors\": []\n  }\n}"}]},{"name":"Reconcile AWD ledgers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","reconcile"]},"description":"Reconciles AWD ledger entries by IDs. Groups by integration instance internally. Same validation as other bulk ops: ids array OR apply_to_all + filters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"apply_to_all\": false,\n  \"ids\": [\n    7777,\n    7778,\n    7779\n  ],\n  \"filters\": {\n    \"integration_instance_ids\": \"1,2\",\n    \"event_type\": \"RECEIVED\",\n    \"reconciled\": \"0\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/reconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","reconcile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"AWD ledger reconciliation completed. 3 processed, 0 skipped, 3 FIFO layers created, 0 consumptions created.\",\n  \"data\": {\n    \"processed\": 3,\n    \"skipped\": 0,\n    \"fifo_layers_created\": 3,\n    \"consumptions_created\": 0\n  }\n}"}]},{"name":"Unreconcile AWD ledgers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","unreconcile"]},"description":"Unreconciles AWD ledger entries by IDs. Clears reconciled_at, reconciled_quantity, and amazon_fifo_layer_id. Same validation pattern.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"apply_to_all\": false,\n  \"ids\": [\n    7777,\n    7778\n  ],\n  \"filters\": {\n    \"integration_instance_ids\": \"1\",\n    \"reconciled\": \"1\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ledgers/unreconcile","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ledgers","unreconcile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 AWD ledger entries unreconciled.\",\n  \"data\": {\n    \"count\": 2\n  }\n}"}]},{"name":"Update ship-from mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a ship-from mapping's link target. Optional: link_id (integer, nullable), link_type (string, nullable, must be 'App\\\\Models\\\\Supplier' or 'App\\\\Models\\\\Warehouse'). Pass null link_id to clear the mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"link_id\": 22,\n  \"link_type\": \"App\\\\Models\\\\Supplier\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings/{id}","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping updated successfully\",\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 1,\n    \"integration_instance_name\": \"Amazon US\",\n    \"name\": \"Supplier ACME\",\n    \"link_id\": 22,\n    \"link_type\": \"App\\\\Models\\\\Supplier\",\n    \"link_type_label\": \"Supplier\",\n    \"link_name\": \"ACME Co.\",\n    \"created_at\": \"2024-03-01T12:00:00+00:00\",\n    \"updated_at\": \"2024-05-29T12:00:00+00:00\"\n  }\n}"}]},{"name":"Bulk update ship-from mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings","bulk-update"]},"description":"Bulk updates ship-from mappings. Two modes: (1) explicit ids: [...] OR (2) apply_to_all: true + filters: {...}. Validation: apply_to_all (sometimes|boolean), filters (required_if:apply_to_all,true|array), ids (required_without:apply_to_all|array), ids.* (integer, must exist in amazon_fba_inbound_ship_from_mappings.id), link_id (nullable|integer), link_type (nullable|string|in:App\\\\Models\\\\Supplier,App\\\\Models\\\\Warehouse). Pass null link_id to clear mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"apply_to_all\": false,\n  \"ids\": [\n    12,\n    13,\n    14\n  ],\n  \"filters\": {\n    \"integration_instance_ids\": \"1\",\n    \"link_status\": \"unmapped\"\n  },\n  \"link_id\": 22,\n  \"link_type\": \"App\\\\Models\\\\Supplier\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/ship-from-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","ship-from-mappings","bulk-update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 mapping(s) updated successfully\",\n  \"data\": [\n    {\n      \"id\": 12,\n      \"integration_instance_id\": 1,\n      \"integration_instance_name\": \"Amazon US\",\n      \"name\": \"Supplier ACME\",\n      \"link_id\": 22,\n      \"link_type\": \"App\\\\Models\\\\Supplier\",\n      \"link_type_label\": \"Supplier\",\n      \"link_name\": \"ACME Co.\",\n      \"created_at\": \"2024-03-01T12:00:00+00:00\",\n      \"updated_at\": \"2024-05-29T12:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Reset AWD Access","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/reset-access","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","reset-access"]},"description":"Resets the stored \"AWD access denied\" flag for the specified Amazon integration instances. An instance is flagged as access-denied when Amazon's AWD (Amazon Warehousing & Distribution) API returns a 403 for it; while flagged, AWD syncing is skipped for that instance. Resetting the flag causes the next AWD sync to re-probe Amazon and re-check eligibility.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRuns synchronously and returns a per-instance result with one of three statuses: `reset` (flag cleared), `not_denied` (nothing to reset), or `error` (instance not found).\n\nBody fields:\n- `integration_instance_ids` (required, array of integers or comma-separated string) - the Amazon integration instances to reset. Returns 400 when omitted or empty.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/awd/reset-access","host":["{{baseUrl}}"],"path":["api","amazon","unified","awd","reset-access"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Reset AWD access for 1 integration(s). The next sync will re-check AWD availability.\",\n  \"data\": {\n    \"results\": [\n      {\n        \"integration_instance_id\": 2,\n        \"integration_instance_name\": \"Amazon US\",\n        \"status\": \"reset\",\n        \"message\": \"AWD access flag reset - will re-check on next sync\"\n      },\n      {\n        \"integration_instance_id\": 5,\n        \"integration_instance_name\": \"Amazon CA\",\n        \"status\": \"not_denied\",\n        \"message\": \"AWD access is not currently denied\"\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"reset\": 1\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Restock Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/restock-report?page=1&per_page=10&search=&integration_instance_ids=","host":["{{baseUrl}}"],"path":["api","amazon","unified","restock-report"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"search","value":"","description":"Free-text search across the resource’s searchable fields.","disabled":true},{"key":"integration_instance_ids","value":"","description":"Comma-separated integration instance IDs to scope the query.","disabled":true}]},"description":"List Restock Report\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Restock Report Row","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/restock-report/{restockReport}","host":["{{baseUrl}}"],"path":["api","amazon","unified","restock-report",":restockReport"],"variable":[{"key":"restockReport","value":"","description":"Restock report row ID"}]},"description":"Returns a single row from Amazon's FBA restock recommendations report, with the amazon_product cross-link resolved ({id} of the Amazon listing matching the row's merchant SKU on the same integration instance, or null when no match).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields include Amazon's replenishment guidance (recommended_replenishment_qty, recommended_ship_date, alert), sales velocity (sales_last_30_days, units_sold_last_30_days), the current inventory position (total_units, inbound, available, fc_transfer, fc_processing, customer_order, unfulfillable, working, shipped, receiving), days of supply (total_days_of_supply, days_of_supply_at_amazon_fulfillment_network), and identifiers (merchant_sku, fnsku, asin, country, condition, supplier, supplier_part_no, currency_code, price, fulfilled_by).\n\nOptional query parameters included / excluded (URL-encoded JSON arrays of column names) limit which columns are returned."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/restock-report/{restockReport}","host":["{{baseUrl}}"],"path":["api","amazon","unified","restock-report",":restockReport"],"variable":[{"key":"restockReport","value":"","description":"Restock report row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 30455,\n    \"integration_instance_id\": 3,\n    \"integration_instance_name\": \"Amazon US\",\n    \"amazon_product\": {\n      \"id\": 5512\n    },\n    \"recommended_replenishment_qty\": 250,\n    \"recommended_ship_date\": \"2026-07-15T00:00:00.000000Z\",\n    \"product_name\": \"Blue Widget - Medium\",\n    \"merchant_sku\": \"WIDGET-BLUE-M\",\n    \"fnsku\": \"X002ABCDE1\",\n    \"asin\": \"B08XYZAB12\",\n    \"country\": \"US\",\n    \"condition\": \"New\",\n    \"supplier\": \"Acme Supply Co\",\n    \"supplier_part_no\": \"ACM-4432\",\n    \"currency_code\": \"USD\",\n    \"price\": 24.99,\n    \"sales_last_30_days\": 3120.55,\n    \"units_sold_last_30_days\": 125,\n    \"total_units\": 640,\n    \"inbound\": 200,\n    \"available\": 380,\n    \"fc_transfer\": 24,\n    \"fc_processing\": 12,\n    \"customer_order\": 24,\n    \"unfulfillable\": 0,\n    \"working\": 100,\n    \"shipped\": 80,\n    \"receiving\": 20,\n    \"fulfilled_by\": \"AMAZON\",\n    \"total_days_of_supply\": \"45.2\",\n    \"days_of_supply_at_amazon_fulfillment_network\": \"38.6\",\n    \"alert\": \"Low inventory\",\n    \"created_at\": \"2026-07-05T06:00:14.000000Z\",\n    \"updated_at\": \"2026-07-06T06:00:22.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Unified MCF Fulfillment Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders"]},"description":"Returns a paginated list of MCF (Multi-Channel Fulfillment) orders aggregated across all Amazon integration instances the user has access to. Supports Spatie QueryBuilder filters and sorts. Each item includes related integration instance, sales order fulfillment, items, and shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 7,\n      \"sales_order_fulfillment_id\": 5510,\n      \"seller_fulfillment_order_id\": \"SO-12345\",\n      \"displayable_order_id\": \"AMZ-0001\",\n      \"displayable_order_date\": \"2026-05-15T14:32:00.000000Z\",\n      \"displayable_order_comment\": \"Thanks for your order!\",\n      \"marketplace_id\": \"ATVPDKIKX0DER\",\n      \"shipping_speed_category\": \"Standard\",\n      \"delivery_window\": {\n        \"startDate\": \"2026-05-20T00:00:00Z\",\n        \"endDate\": \"2026-05-22T00:00:00Z\"\n      },\n      \"destination_address\": {\n        \"name\": \"Jane Doe\",\n        \"addressLine1\": \"123 Main St\",\n        \"city\": \"Seattle\",\n        \"stateOrRegion\": \"WA\",\n        \"postalCode\": \"98101\",\n        \"countryCode\": \"US\"\n      },\n      \"fulfillment_action\": \"Ship\",\n      \"fulfillment_policy\": \"FillOrKill\",\n      \"cod_settings\": null,\n      \"received_date\": \"2026-05-15T14:32:10.000000Z\",\n      \"fulfillment_order_status\": \"COMPLETE\",\n      \"status_updated_date\": \"2026-05-17T22:08:45.000000Z\",\n      \"notification_emails\": [\n        \"customer@example.com\"\n      ],\n      \"feature_constraints\": [\n        {\n          \"featureName\": \"BLANK_BOX\",\n          \"featureFulfillmentPolicy\": \"Required\"\n        }\n      ],\n      \"created_at\": \"2026-05-15T14:33:00.000000Z\",\n      \"updated_at\": \"2026-05-17T22:08:45.000000Z\",\n      \"integration_instance\": {\n        \"id\": 7,\n        \"name\": \"Amazon US — Hitlights\"\n      },\n      \"integration_instance_name\": \"Amazon US — Hitlights\",\n      \"sales_order_fulfillment\": {\n        \"id\": 5510,\n        \"sales_order_id\": 9871\n      },\n      \"item_count\": 2,\n      \"items\": [\n        {\n          \"id\": 8001,\n          \"seller_sku\": \"SKU-ABC-001\",\n          \"seller_fulfillment_order_item_id\": \"ITEM-001\",\n          \"quantity\": 2,\n          \"cancelled_quantity\": 0,\n          \"unfulfillable_quantity\": 0,\n          \"displayable_comment\": null,\n          \"gift_message\": null,\n          \"fulfillment_network_sku\": \"X0001ABCDE\",\n          \"estimated_ship_date\": \"2026-05-16T08:00:00.000000Z\",\n          \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n          \"per_unit_price_currency_code\": \"USD\",\n          \"per_unit_price_currency_value\": \"19.99\",\n          \"per_unit_tax_currency_code\": \"USD\",\n          \"per_unit_tax_value\": \"1.80\",\n          \"per_unit_declared_value_currency_code\": \"USD\",\n          \"per_unit_declared_value_value\": \"19.99\"\n        },\n        {\n          \"id\": 8002,\n          \"seller_sku\": \"SKU-XYZ-009\",\n          \"seller_fulfillment_order_item_id\": \"ITEM-002\",\n          \"quantity\": 1,\n          \"cancelled_quantity\": 0,\n          \"unfulfillable_quantity\": 0,\n          \"displayable_comment\": null,\n          \"gift_message\": null,\n          \"fulfillment_network_sku\": \"X0009XYZAB\",\n          \"estimated_ship_date\": \"2026-05-16T08:00:00.000000Z\",\n          \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n          \"per_unit_price_currency_code\": \"USD\",\n          \"per_unit_price_currency_value\": \"34.50\",\n          \"per_unit_tax_currency_code\": \"USD\",\n          \"per_unit_tax_value\": \"3.10\",\n          \"per_unit_declared_value_currency_code\": \"USD\",\n          \"per_unit_declared_value_value\": \"34.50\"\n        }\n      ],\n      \"shipment_count\": 1,\n      \"shipments\": [\n        {\n          \"id\": 4400,\n          \"amazon_shipment_id\": \"AMZ-SHIP-998877\",\n          \"fulfillment_center_id\": \"PHX7\",\n          \"fulfillment_shipment_status\": \"SHIPPED\",\n          \"shipping_date\": \"2026-05-16T09:15:00.000000Z\",\n          \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n          \"shipping_notes\": null\n        }\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.test/api/amazon/unified/fulfillment-orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"https://example.test/api/amazon/unified/fulfillment-orders?page=12\",\n  \"next_page_url\": \"https://example.test/api/amazon/unified/fulfillment-orders?page=2\",\n  \"path\": \"https://example.test/api/amazon/unified/fulfillment-orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 117,\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/fulfillment-orders?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.test/api/amazon/unified/fulfillment-orders?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ]\n}"}]},{"name":"Show Unified MCF Fulfillment Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders/{fulfillmentOrder}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders",":fulfillmentOrder"],"variable":[{"key":"fulfillmentOrder","value":"1024","description":"AmazonFulfillmentOrder ID (resolved via route model binding)."}]},"description":"Returns a single MCF fulfillment order with full detail, including the integration instance, related sales order fulfillment, all order items, shipments, and return authorizations. Response is wrapped in the application's standard envelope (top-level `data`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders/{fulfillmentOrder}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders",":fulfillmentOrder"],"variable":[{"key":"fulfillmentOrder","value":"1024","description":"AmazonFulfillmentOrder ID (resolved via route model binding)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"integration_instance_id\": 7,\n    \"sales_order_fulfillment_id\": 5510,\n    \"seller_fulfillment_order_id\": \"SO-12345\",\n    \"displayable_order_id\": \"AMZ-0001\",\n    \"displayable_order_date\": \"2026-05-15T14:32:00.000000Z\",\n    \"displayable_order_comment\": \"Thanks for your order!\",\n    \"marketplace_id\": \"ATVPDKIKX0DER\",\n    \"shipping_speed_category\": \"Standard\",\n    \"delivery_window\": {\n      \"startDate\": \"2026-05-20T00:00:00Z\",\n      \"endDate\": \"2026-05-22T00:00:00Z\"\n    },\n    \"destination_address\": {\n      \"name\": \"Jane Doe\",\n      \"addressLine1\": \"123 Main St\",\n      \"addressLine2\": null,\n      \"city\": \"Seattle\",\n      \"stateOrRegion\": \"WA\",\n      \"postalCode\": \"98101\",\n      \"countryCode\": \"US\",\n      \"phone\": \"+1-555-123-4567\"\n    },\n    \"fulfillment_action\": \"Ship\",\n    \"fulfillment_policy\": \"FillOrKill\",\n    \"cod_settings\": null,\n    \"received_date\": \"2026-05-15T14:32:10.000000Z\",\n    \"fulfillment_order_status\": \"COMPLETE\",\n    \"status_updated_date\": \"2026-05-17T22:08:45.000000Z\",\n    \"notification_emails\": [\n      \"customer@example.com\"\n    ],\n    \"feature_constraints\": [\n      {\n        \"featureName\": \"BLANK_BOX\",\n        \"featureFulfillmentPolicy\": \"Required\"\n      }\n    ],\n    \"created_at\": \"2026-05-15T14:33:00.000000Z\",\n    \"updated_at\": \"2026-05-17T22:08:45.000000Z\",\n    \"integration_instance\": {\n      \"id\": 7,\n      \"name\": \"Amazon US — Hitlights\"\n    },\n    \"integration_instance_name\": \"Amazon US — Hitlights\",\n    \"sales_order_fulfillment\": {\n      \"id\": 5510,\n      \"sales_order_id\": 9871\n    },\n    \"item_count\": 2,\n    \"items\": [\n      {\n        \"id\": 8001,\n        \"seller_sku\": \"SKU-ABC-001\",\n        \"seller_fulfillment_order_item_id\": \"ITEM-001\",\n        \"quantity\": 2,\n        \"cancelled_quantity\": 0,\n        \"unfulfillable_quantity\": 0,\n        \"displayable_comment\": null,\n        \"gift_message\": null,\n        \"fulfillment_network_sku\": \"X0001ABCDE\",\n        \"estimated_ship_date\": \"2026-05-16T08:00:00.000000Z\",\n        \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n        \"per_unit_price_currency_code\": \"USD\",\n        \"per_unit_price_currency_value\": \"19.99\",\n        \"per_unit_tax_currency_code\": \"USD\",\n        \"per_unit_tax_value\": \"1.80\",\n        \"per_unit_declared_value_currency_code\": \"USD\",\n        \"per_unit_declared_value_value\": \"19.99\"\n      },\n      {\n        \"id\": 8002,\n        \"seller_sku\": \"SKU-XYZ-009\",\n        \"seller_fulfillment_order_item_id\": \"ITEM-002\",\n        \"quantity\": 1,\n        \"cancelled_quantity\": 0,\n        \"unfulfillable_quantity\": 0,\n        \"displayable_comment\": null,\n        \"gift_message\": null,\n        \"fulfillment_network_sku\": \"X0009XYZAB\",\n        \"estimated_ship_date\": \"2026-05-16T08:00:00.000000Z\",\n        \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n        \"per_unit_price_currency_code\": \"USD\",\n        \"per_unit_price_currency_value\": \"34.50\",\n        \"per_unit_tax_currency_code\": \"USD\",\n        \"per_unit_tax_value\": \"3.10\",\n        \"per_unit_declared_value_currency_code\": \"USD\",\n        \"per_unit_declared_value_value\": \"34.50\"\n      }\n    ],\n    \"shipment_count\": 1,\n    \"shipments\": [\n      {\n        \"id\": 4400,\n        \"amazon_shipment_id\": \"AMZ-SHIP-998877\",\n        \"fulfillment_center_id\": \"PHX7\",\n        \"fulfillment_shipment_status\": \"SHIPPED\",\n        \"shipping_date\": \"2026-05-16T09:15:00.000000Z\",\n        \"estimated_arrival_date\": \"2026-05-20T18:00:00.000000Z\",\n        \"shipping_notes\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Fulfillment Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders/{fulfillmentOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders",":fulfillmentOrder","activity-log"],"variable":[{"key":"fulfillmentOrder","value":"","description":"Multi-channel fulfillment order ID"}]},"description":"Returns the activity log for a single multi-channel fulfillment (MCF) order: the most recent 200 entries, newest first (not paginated). Each entry contains id, description, event (created / updated / deleted), causer ({id, name, email} of the user who made the change, or null for system changes), properties (old and attributes objects with the changed field values), and created_at (UTC).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-orders/{fulfillmentOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-orders",":fulfillmentOrder","activity-log"],"variable":[{"key":"fulfillmentOrder","value":"","description":"Multi-channel fulfillment order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 51204,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"causer\": null,\n      \"properties\": {\n        \"old\": {\n          \"fulfillment_order_status\": \"PROCESSING\"\n        },\n        \"attributes\": {\n          \"fulfillment_order_status\": \"COMPLETE\"\n        }\n      },\n      \"created_at\": \"2026-06-28T17:44:09.000000Z\"\n    },\n    {\n      \"id\": 50981,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"causer\": {\n        \"id\": 12,\n        \"name\": \"Jane Doe\",\n        \"email\": \"jane@example.com\"\n      },\n      \"properties\": {\n        \"old\": null,\n        \"attributes\": {\n          \"seller_fulfillment_order_id\": \"SO-102431\",\n          \"fulfillment_order_status\": \"RECEIVED\"\n        }\n      },\n      \"created_at\": \"2026-06-27T10:02:51.000000Z\"\n    }\n  ]\n}"}]},{"name":"List FBA Storage Fees (Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees"]},"description":"Paginated monthly FBA storage fee report rows (GET_FBA_STORAGE_FEE_CHARGES_DATA) aggregated across all Amazon integration instances. One row per FNSKU per fulfillment center per charge month.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires a Bearer token (Personal Access Token).\n\nFilters: integration_instance_ids (comma-separated), currency, country_code, month_of_charge (single Y-m-d month), search (fnsku/asin/product_name/fulfillment_center/product_size_tier/integration name), plus advanced text filters (fnsku, asin, product_name, fulfillment_center, country_code, product_size_tier — each with a *_op operator), advanced numeric filters (average_quantity_on_hand, base_rate, estimated_monthly_storage_fee), and advanced datetime filters (month_of_charge, created_at, updated_at).\n\nPagination: page (default 1), per_page (default 10, min 1).\n\nCost entries: importing these rows has no accounting impact unless the per-instance 'Automatically create cost entries from FBA storage fee reports' setting is enabled, in which case each month's report becomes a cost entry with per-product allocations."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"AMZ partusa\",\n      \"amazon_report_id\": 8841,\n      \"month_of_charge\": \"2026-03-01\",\n      \"asin\": \"B0TEST0001\",\n      \"fnsku\": \"X00TESTAA1\",\n      \"product_name\": \"Widget A\",\n      \"amazon_fnsku_product_id\": 551,\n      \"fulfillment_center\": \"PHX3\",\n      \"country_code\": \"US\",\n      \"average_quantity_on_hand\": 120.5,\n      \"product_size_tier\": \"Large standard-size\",\n      \"base_rate\": 0.78,\n      \"estimated_monthly_storage_fee\": 18,\n      \"currency\": \"USD\",\n      \"created_at\": \"2026-04-05T09:15:00+00:00\",\n      \"updated_at\": \"2026-04-05T09:15:00+00:00\",\n      \"cost_entry_id\": 1,\n      \"cost_entry\": {\n        \"id\": 1,\n        \"reference_number\": \"AMZ-STORAGE-3-2026-05\",\n        \"amount\": 361.32,\n        \"route\": \"/accounting/cost-entries/1\"\n      },\n      \"cost_allocation\": {\n        \"id\": 5012,\n        \"amount\": 18\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Storage Fee Currencies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","currencies"]},"description":"Distinct currency codes present across storage fee rows, optionally scoped to specific integration instances. Used to populate the Currency filter on the Storage Fees report page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","currencies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"USD\",\n    \"CAD\",\n    \"GBP\"\n  ]\n}"}]},{"name":"Request Latest Storage Fee Report (Sync)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","sync"]},"description":"Request the FBA storage fee report (GET_FBA_STORAGE_FEE_CHARGES_DATA) from Amazon, backfilling from the instance's FBA inventory tracking start month forward. Per instance, only the next contiguous block of charge months with NO data yet is requested (a single report covers a multi-month window), so months already imported are never re-requested. When every month through the last completed month is already present, no report is requested and the response carries requested=false.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nScope with filter[integration_instance_ids] (comma-separated) or integration_instance_ids. Returns 409 if a storage fee report is already in progress. Dispatches a tracked a background job per request (track via the tracked job log endpoints). Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requested\": true,\n    \"tracked_job_log_id\": 12345,\n    \"tracked_job_log_ids\": [\n      12345\n    ]\n  },\n  \"message\": \"Storage fee report requested\"\n}"}]},{"name":"Get Cost Entry Creation Setting","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/cost-entry-setting","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","cost-entry-setting"]},"description":"Aggregate state of the per-instance \"create cost entries from FBA storage fee reports\" setting across the selected Amazon integrations. The same setting gates both the storage fee and aged-inventory surcharge reports. `enabled` is true when every instance has it on, false when all off, and null when mixed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/cost-entry-setting","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","cost-entry-setting"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"instance_count\": 1\n  }\n}"}]},{"name":"Update Cost Entry Creation Setting","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/cost-entry-setting","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","cost-entry-setting"]},"description":"Enable or disable cost entry creation across the selected Amazon integrations (omit integration_instance_ids to apply to all). Returns the resulting aggregate state. When enabled, future report runs turn each month's report into a cost entry with per-product allocations.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody: enabled (required boolean), integration_instance_ids (optional, comma-separated).\n\nAuthentication: Requires a Bearer token (Personal Access Token).","body":{"mode":"raw","raw":"{\n  \"enabled\": true,\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/cost-entry-setting","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","cost-entry-setting"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"instance_count\": 1\n  }\n}"}]},{"name":"Get Report Schedule (Next Run)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/schedule","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","schedule"]},"description":"Report-pipeline status for the daily FBA storage fee and aged-inventory surcharge report requests, powering the always-visible status strip on each report page. Scoped to the selected (FBA-enabled) integration instances via the optional `integration_instance_ids` filter.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFor each report type (`storage_fee`, `aged_inventory_surcharge`) the response returns:\n- `cron` / `next_run` — the configured cron and next scheduled run (absolute ISO 8601), for the live countdown.\n- `state` — one of `in_progress`, `failed`, `idle` (up to date / healthy), `never_run`.\n- `looks_stuck` (bool) — true when an in-progress run has been pending longer than `stuck_threshold_hours`.\n- `stuck_threshold_hours` (int) — hours after which an in-progress run is flagged as stuck.\n- `in_progress_since` (ISO 8601|null) — when the oldest in-flight run was requested.\n- `last_success_at` (ISO 8601|null) — when the last report was successfully imported.\n- `last_failure_at` (ISO 8601|null) — when the last run failed (FATAL), if the most recent run failed.\n- `data_through_month` (YYYY-MM|null) — latest charge month the imported data covers.\n- `expected_through_month` (YYYY-MM) — the most recent charge month Amazon has finalised, which the data is expected to cover. Amazon finalises a month's storage fees between the 7th and 15th of the following month (the aged-inventory surcharge is assessed on the 15th), so before the monthly `report_ready_day` this is the month *before* last; on/after it, the previous calendar month.\n- `awaiting_month` (YYYY-MM|null) — the latest calendar month still pending Amazon's mid-month finalisation and not yet imported, or null when nothing is awaited. When set, the pipeline is correctly waiting on Amazon (not behind); the report is auto-requested once that month becomes ready.\n- `report_ready_day` (int) — day of the month (default 16) from which the previous month's data is expected and requested.\n- `is_behind` (bool) — true when `data_through_month` is older than `expected_through_month`.\n- `instance_count` (int) — number of FBA-enabled instances in scope.\n\nAuthentication: Requires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/schedule","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","schedule"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"storage_fee\": {\n      \"cron\": \"40 1 * * *\",\n      \"next_run\": \"2026-07-01T01:40:00+00:00\",\n      \"state\": \"in_progress\",\n      \"looks_stuck\": true,\n      \"stuck_threshold_hours\": 6,\n      \"in_progress_since\": \"2026-06-10T01:40:12+00:00\",\n      \"last_success_at\": \"2026-05-02T01:42:55+00:00\",\n      \"last_failure_at\": null,\n      \"data_through_month\": \"2026-04\",\n      \"expected_through_month\": \"2026-05\",\n      \"awaiting_month\": null,\n      \"report_ready_day\": 16,\n      \"is_behind\": true,\n      \"instance_count\": 2\n    },\n    \"aged_inventory_surcharge\": {\n      \"cron\": \"50 1 * * *\",\n      \"next_run\": \"2026-07-01T01:50:00+00:00\",\n      \"state\": \"idle\",\n      \"looks_stuck\": false,\n      \"stuck_threshold_hours\": 6,\n      \"in_progress_since\": null,\n      \"last_success_at\": \"2026-06-01T01:51:30+00:00\",\n      \"last_failure_at\": null,\n      \"data_through_month\": \"2026-05\",\n      \"expected_through_month\": \"2026-05\",\n      \"awaiting_month\": null,\n      \"report_ready_day\": 16,\n      \"is_behind\": false,\n      \"instance_count\": 2\n    }\n  }\n}"}]},{"name":"Process Cost Entries Now","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/process-cost-entries","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","process-cost-entries"]},"description":"Runs the storage fee cost entry creation logic now on already-imported report data — building/refreshing one cost entry per month with per-product allocations, per FBA-enabled instance. Does NOT re-fetch from Amazon. The manual counterpart to the automatic per-instance setting. Returns tracked job log IDs so the UI can follow progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody: integration_instance_ids (optional, comma-separated; omit for all Amazon instances).\n\nAuthentication: Requires a Bearer token (Personal Access Token).","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-storage-fees/process-cost-entries","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-storage-fees","process-cost-entries"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost entry processing started\",\n  \"data\": {\n    \"tracked_job_log_id\": 90620,\n    \"tracked_job_log_ids\": [\n      90620\n    ]\n  }\n}"}]},{"name":"Get Unmatched FNSKUs for Cost Entry","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/cost-entries/{costEntry}/unmatched-fnskus","host":["{{baseUrl}}"],"path":["api","amazon","cost-entries",":costEntry","unmatched-fnskus"],"variable":[{"key":"costEntry","value":"801","description":"Cost entry ID"}]},"description":"For a cost entry automatically created from an Amazon storage fee report (monthly storage fees or the long-term/aged inventory surcharge), returns the per-FNSKU fee rows that could not be allocated to a product because the FNSKU has no product mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe unmatched breakdown is not persisted on the cost entry; it is recomputed on demand by re-aggregating the source report's per-FNSKU fees for the entry's source month with the same logic that built the original allocations. FNSKUs whose fee rounds to zero, or that have since been mapped to a product, are excluded.\n\nEach row contains: fnsku, product_name (as reported by Amazon, may be null), and fee (in major currency units). Returns 404 when the cost entry was not created from an Amazon report, when it is not a storage fee entry type, or when the source report no longer exists. This endpoint is not scoped to an integration instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/cost-entries/{costEntry}/unmatched-fnskus","host":["{{baseUrl}}"],"path":["api","amazon","cost-entries",":costEntry","unmatched-fnskus"],"variable":[{"key":"costEntry","value":"801","description":"Cost entry ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"fnsku\": \"X002ABCDE1\",\n      \"product_name\": \"Leaf Razor, Black\",\n      \"fee\": 12.34\n    },\n    {\n      \"fnsku\": \"X003QWERT7\",\n      \"product_name\": \"Shave Soap Refill 3-Pack\",\n      \"fee\": 3.08\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"List FBA Aged Inventory Surcharges (Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees"]},"description":"Paginated FBA aged-inventory surcharge (long-term storage fee) report rows (GET_FBA_FULFILLMENT_LONGTERM_STORAGE_FEE_CHARGES_DATA) aggregated across all Amazon integration instances. One row per aged-inventory snapshot per SKU.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires a Bearer token (Personal Access Token).\n\nFilters: integration_instance_ids, currency, country, surcharge_age_tier, snapshot_date (single Y-m-d), search (sku/fnsku/asin/product_name/surcharge_age_tier/integration name), plus advanced text filters (sku, fnsku, asin, product_name, condition, surcharge_age_tier, country — each with a *_op operator), advanced numeric filters (qty_charged, rate_surcharge, amount_charged), and advanced datetime filters (snapshot_date, created_at, updated_at).\n\nPagination: page (default 1), per_page (default 10, min 1).\n\nCost entries: importing these rows has no accounting impact unless the per-instance 'Automatically create cost entries from FBA storage fee reports' setting is enabled, in which case each month's surcharge becomes a cost entry with per-product allocations."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"AMZ partusa\",\n      \"amazon_report_id\": 8902,\n      \"snapshot_date\": \"2026-03-15\",\n      \"sku\": \"SKU-LT-1\",\n      \"fnsku\": \"X00LTSFAA1\",\n      \"asin\": \"B0LTSF0001\",\n      \"product_name\": \"Aged Widget A\",\n      \"amazon_fnsku_product_id\": 551,\n      \"condition\": \"SELLABLE\",\n      \"qty_charged\": 4,\n      \"rate_surcharge\": 1.55,\n      \"amount_charged\": 6.2,\n      \"surcharge_age_tier\": \"365+ days\",\n      \"currency\": \"USD\",\n      \"country\": \"US\",\n      \"created_at\": \"2026-04-05T09:15:00+00:00\",\n      \"updated_at\": \"2026-04-05T09:15:00+00:00\",\n      \"cost_entry_id\": 1,\n      \"cost_entry\": {\n        \"id\": 1,\n        \"reference_number\": \"AMZ-LTSF-3-2026-05\",\n        \"amount\": 361.32,\n        \"route\": \"/accounting/cost-entries/1\"\n      },\n      \"cost_allocation\": {\n        \"id\": 5012,\n        \"amount\": 18\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 10,\n  \"total\": 37,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Aged Inventory Surcharge Currencies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","currencies"]},"description":"Distinct currency codes present across aged-inventory surcharge rows, optionally scoped to specific integration instances. Used to populate the Currency filter.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","currencies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"USD\",\n    \"CAD\"\n  ]\n}"}]},{"name":"Request Latest Aged Inventory Surcharge Report (Sync)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","sync"]},"description":"Request the FBA aged inventory surcharge / long-term storage fee report (GET_FBA_FULFILLMENT_LONGTERM_STORAGE_FEE_CHARGES_DATA) from Amazon, backfilling from the instance's FBA inventory tracking start month forward. Per instance, only the next contiguous block of charge months with NO data yet is requested (a single report covers a multi-month window), so months already imported are never re-requested. When every month through the last completed month is already present, no report is requested and the response carries requested=false.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nScope with filter[integration_instance_ids] (comma-separated) or integration_instance_ids. Returns 409 if an aged inventory surcharge report is already in progress. Dispatches a tracked a background job per request (track via the tracked job log endpoints). Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requested\": true,\n    \"tracked_job_log_id\": 12346,\n    \"tracked_job_log_ids\": [\n      12346\n    ]\n  },\n  \"message\": \"Aged inventory surcharge report requested\"\n}"}]},{"name":"Process Cost Entries Now","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/process-cost-entries","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","process-cost-entries"]},"description":"Runs the aged inventory surcharge cost entry creation logic now on already-imported report data — building/refreshing one cost entry per month with per-product allocations, per FBA-enabled instance. Does NOT re-fetch from Amazon. The manual counterpart to the automatic per-instance setting. Returns tracked job log IDs so the UI can follow progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody: integration_instance_ids (optional, comma-separated; omit for all Amazon instances).\n\nAuthentication: Requires a Bearer token (Personal Access Token).","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-longterm-storage-fees/process-cost-entries","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-longterm-storage-fees","process-cost-entries"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost entry processing started\",\n  \"data\": {\n    \"tracked_job_log_id\": 90620,\n    \"tracked_job_log_ids\": [\n      90620\n    ]\n  }\n}"}]},{"name":"List Fulfillment Centers (Across Instances)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers"]},"description":"Distinct fulfillment centers across all five FC-bearing sources (storage fees, ledger, customer returns, shipments, inbound shipments). A fulfillment center is a virtual entity keyed by (integration instance, normalized FC code); every aggregate is computed in a single derived query, so the list is fully sortable and filterable on any aggregate column.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row carries: per-source counts (storage_fee_rows, ledger_events, customer_returns, shipments, inbound_shipments), total estimated storage fee (storage_fee_total), current on-hand units (inventory_quantity) and their approximate value at weighted-average cost (inventory_value), derived country (display only — not sortable/filterable), and last_activity (max created_at across sources).\n\nFilters: filter[search] / filter[code.*] on the FC code; filter[integration_instance_ids] (comma-separated); numeric advanced filters on storage_fee_rows, storage_fee_total, ledger_events, customer_returns, shipments, inbound_shipments, inventory_quantity, inventory_value (operators: is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty); datetime filter on last_activity (before, after, on_or_before, on_or_after, between, today, past_week, past_month, past_year, ...).\n\nSort (sort=, prefix - for DESC). Allowed sorts: code, integration_instance_id, storage_fee_rows, storage_fee_total, ledger_events, customer_returns, shipments, inbound_shipments, inventory_quantity, inventory_value, last_activity. Default: code ASC.\n\nPaginated (per_page default 10). Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"code\": \"BNA2\",\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"AMZ partusa\",\n      \"country\": \"US\",\n      \"storage_fee_rows\": 4,\n      \"ledger_events\": 41,\n      \"customer_returns\": 0,\n      \"shipments\": 25,\n      \"inbound_shipments\": 2,\n      \"storage_fee_total\": 4.55,\n      \"inventory_quantity\": 2,\n      \"inventory_value\": 2075.17,\n      \"last_activity\": \"2026-06-12T21:26:17+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 37,\n  \"per_page\": 10,\n  \"total\": 370,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Fulfillment Center Overview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Aggregate KPIs for one fulfillment center: country, storage fee total, and counts of storage rows, ledger events, customer returns, shipments, and inbound shipments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"code\": \"BNA2\",\n    \"integration_instance_id\": 3,\n    \"integration_instance_name\": \"AMZ partusa\",\n    \"country\": \"US\",\n    \"storage_fee_rows\": 4,\n    \"ledger_events\": 114,\n    \"customer_returns\": 0,\n    \"shipments\": 43,\n    \"inbound_shipments\": 2,\n    \"storage_fee_total\": 0.26,\n    \"last_activity\": \"2026-06-12T21:26:17+00:00\"\n  }\n}"}]},{"name":"Storage Fees at FC","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","storage-fees"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Paginated monthly storage fee rows at this fulfillment center (normalized FC match).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/storage-fees","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","storage-fees"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Ledger Events at FC","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","ledgers"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Paginated FBA inventory ledger events at this fulfillment center.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/ledgers","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","ledgers"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Customer Returns at FC","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/customer-returns","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","customer-returns"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Paginated customer returns processed at this fulfillment center.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/customer-returns","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","customer-returns"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Shipments from FC","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","shipments"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Paginated outbound (customer) shipment lines from this fulfillment center.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","shipments"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Inbound Shipments to FC","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","inbound-shipments"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]},"description":"Paginated inbound shipments destined for this fulfillment center.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fulfillment-centers/{code}/inbound-shipments","host":["{{baseUrl}}"],"path":["api","amazon","unified","fulfillment-centers",":code","inbound-shipments"],"variable":[{"key":"code","value":"BNA2","description":"Fulfillment center code (case-insensitive; quotes auto-stripped)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"List FBA Reimbursements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements"]},"description":"Paginated list of FBA reimbursements Amazon has already paid, unified across all Amazon integration instances. Rows are ingested from the FBA reimbursements report and form the authoritative payout log that reimbursement cases are reconciled against; `amazon_reimbursement_case_id` (and the embedded `reimbursement_case` object) is set when a row has been matched to a tracked case.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: `page` and `per_page` (default 10).\nSorting: `sort=<field>` ascending or `sort=-<field>` descending. Sortable fields: id, reimbursement_id, approval_date, case_id, amazon_order_id, reason, reason_category, sku, fnsku, asin, amount_per_unit, amount_total, currency, quantity_reimbursed_cash, quantity_reimbursed_inventory, quantity_reimbursed_total, created_at, updated_at.\n\nSimple filters:\n- `filter[search]` — fuzzy search across reimbursement_id, case_id, amazon_order_id, sku, asin, fnsku, reason and the integration instance name. Restrict with `search_columns` and force exact matching per column with `search_strict_columns`.\n- `filter[integration_instance_ids]` — comma-separated Amazon integration instance IDs.\n- `filter[reason_category]` — comma-separated list of normalized reason categories.\n- `filter[currency]` — comma-separated list of currency codes.\n- `filter[has_case_id]` — true/false (also accepts 1/0, yes/no): rows that do or do not carry an Amazon case ID.\n- `filter[has_linked_case]` — true/false (also accepts 1/0, yes/no): rows that are or are not linked to a SKU.io reimbursement case.\n\nAdvanced operator filters use the syntax `filter[column.operator]=value`; a bare `filter[column]=value` is treated as the `is` operator.\n- Text columns (reimbursement_id, case_id, amazon_order_id, reason, reason_category, sku, fnsku, asin, condition) support: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\n- Numeric columns (amount_per_unit, amount_total, quantity_reimbursed_cash, quantity_reimbursed_inventory, quantity_reimbursed_total) support: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\n- Date columns (approval_date, created_at, updated_at) support: is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days. Date values use ISO 8601 / Y-m-d; `between` takes two comma-separated values.\n\nComplex AND/OR filter trees can be sent via `filter_groups` (base64-encoded JSON tree of conditions and nested groups)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1187,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"reimbursement_id\": \"6740912345\",\n      \"approval_date\": \"2026-06-02T00:00:00+00:00\",\n      \"case_id\": \"17389245671\",\n      \"amazon_order_id\": \"113-4092817-5544312\",\n      \"reason\": \"CustomerReturn\",\n      \"reason_category\": \"customer_return_not_received\",\n      \"sku\": \"LEAF-RAZOR-STD\",\n      \"fnsku\": \"X001M8KQZ3\",\n      \"asin\": \"B0B7H2JKLM\",\n      \"condition\": \"SELLABLE\",\n      \"product_id\": 655,\n      \"amazon_fnsku_product_id\": 1994,\n      \"amount_per_unit\": 18.9,\n      \"amount_total\": 18.9,\n      \"currency\": \"USD\",\n      \"quantity_reimbursed_cash\": 1,\n      \"quantity_reimbursed_inventory\": 0,\n      \"quantity_reimbursed_total\": 1,\n      \"amazon_reimbursement_case_id\": 38,\n      \"reimbursement_case\": {\n        \"id\": 38,\n        \"status\": \"reimbursed\",\n        \"amazon_case_id\": \"17389245671\"\n      },\n      \"created_at\": \"2026-06-03T04:10:22+00:00\",\n      \"updated_at\": \"2026-06-03T04:10:22+00:00\"\n    },\n    {\n      \"id\": 1163,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US\",\n      \"reimbursement_id\": \"6738554821\",\n      \"approval_date\": \"2026-05-27T00:00:00+00:00\",\n      \"case_id\": null,\n      \"amazon_order_id\": null,\n      \"reason\": \"Lost_Warehouse\",\n      \"reason_category\": \"warehouse_lost\",\n      \"sku\": \"BCK-CANISTER-16OZ\",\n      \"fnsku\": \"X002QDR3V7\",\n      \"asin\": \"B08XYZ4Q2M\",\n      \"condition\": \"SELLABLE\",\n      \"product_id\": 918,\n      \"amazon_fnsku_product_id\": 2451,\n      \"amount_per_unit\": 14.25,\n      \"amount_total\": 28.5,\n      \"currency\": \"USD\",\n      \"quantity_reimbursed_cash\": 2,\n      \"quantity_reimbursed_inventory\": 0,\n      \"quantity_reimbursed_total\": 2,\n      \"amazon_reimbursement_case_id\": null,\n      \"reimbursement_case\": null,\n      \"created_at\": \"2026-05-28T04:09:47+00:00\",\n      \"updated_at\": \"2026-05-28T04:09:47+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=1\",\n  \"from\": 1,\n  \"last_page\": 22,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=22\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=2\",\n      \"label\": \"2\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/amazon/unified/fba-reimbursements\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 214\n}"}]},{"name":"List FBA Reimbursement Currencies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements","currencies"]},"description":"Returns the distinct currency codes present in the stored FBA reimbursements, sorted alphabetically — useful for populating a currency filter. Optionally scope to specific instances with `integration_instance_ids` (comma-separated).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements/currencies","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements","currencies"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"CAD\",\n    \"USD\"\n  ]\n}"}]},{"name":"Sync FBA Reimbursements","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements","sync"]},"description":"Requests a fresh FBA reimbursements report from Amazon for every Amazon integration instance (or the subset given in `integration_instance_ids`) and ingests the rows into the unified payout log. Queues a background job; returns a job id (`tracked_job_log_id`) for polling progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAmazon only allows one FBA reimbursements report in flight per account, so if a matching report is already being generated the request is rejected with HTTP 409 and details of the conflicting report.\n\n`integration_instance_ids` accepts an array of integers or a comma-separated string; omit it (or send an empty value) to sync every Amazon instance.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": [\n    3,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/unified/fba-reimbursements/sync","host":["{{baseUrl}}"],"path":["api","amazon","unified","fba-reimbursements","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Reimbursement sync started\",\n  \"data\": {\n    \"tracked_job_log_id\": 15240\n  }\n}"}]},{"name":"List Notification Subscriptions (with health)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"List every SP-API push-notification subscription (any status) for the given Amazon integration instance, each with a computed `healthy` flag. A subscription is healthy when it is ACTIVE and has seen an event (or, if brand-new, been alive) within the `window_minutes` silence window (config `amazon.notifications.health_window_minutes`, default 120). Backs the per-instance Notification Health panel. Requires an initialized tenant context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"integration_instance_id\": 3,\n      \"notification_type\": \"ORDER_CHANGE\",\n      \"phase\": 2,\n      \"channel\": \"sqs\",\n      \"subscription_id\": \"b1d4c0e2-9f3a-4d5b-8c7e-1a2b3c4d5e6f\",\n      \"destination_id\": \"9a8b7c6d-5e4f-3210-fedc-ba9876543210\",\n      \"payload_version\": \"1.0\",\n      \"status\": \"active\",\n      \"last_event_at\": \"2026-06-09T11:42:00+00:00\",\n      \"healthy\": true,\n      \"window_minutes\": 120,\n      \"created_at\": \"2026-06-01T08:00:00+00:00\",\n      \"updated_at\": \"2026-06-09T11:42:00+00:00\"\n    },\n    {\n      \"id\": 13,\n      \"integration_instance_id\": 3,\n      \"notification_type\": \"LISTINGS_ITEM_ISSUES_CHANGE\",\n      \"phase\": 5,\n      \"channel\": \"eventbridge\",\n      \"subscription_id\": \"c2e5d1f3-0a4b-5e6c-9d8f-2b3c4d5e6f70\",\n      \"destination_id\": \"0b9c8d7e-6f50-4321-0edc-cb9876543211\",\n      \"payload_version\": \"1.0\",\n      \"status\": \"active\",\n      \"last_event_at\": null,\n      \"healthy\": true,\n      \"window_minutes\": 120,\n      \"created_at\": \"2026-06-09T11:30:00+00:00\",\n      \"updated_at\": \"2026-06-09T11:30:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Tear Down All Subscriptions","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Tear down every active subscription for the instance. Best-effort on Amazon's side (per-type), always marked deleted locally. Returns the count of subscriptions unsubscribed. Requires an initialized tenant context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unsubscribed\": 4\n  },\n  \"message\": \"Subscriptions torn down\"\n}"}]},{"name":"Resync (Reconcile) Subscriptions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions/resync","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions","resync"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]},"description":"Force a reconcile: converge the instance's live subscriptions onto exactly what its enabled phase flags imply — create newly-enabled notification types, re-point relocated SQS/EventBridge destinations, and tear down disabled types. Idempotent and safe to re-run after a partial failure; degrades per-type rather than aborting, so one failing type never blocks the rest. Returns counts of what changed. Requires an initialized tenant context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/instances/{integrationInstance}/notification-subscriptions/resync","host":["{{baseUrl}}"],"path":["api","amazon","instances",":integrationInstance","notification-subscriptions","resync"],"variable":[{"key":"integrationInstance","value":"3","description":"Amazon integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"subscribed\": 3,\n    \"unsubscribed\": 1,\n    \"skipped\": 9,\n    \"failed\": 0\n  },\n  \"message\": \"Subscriptions reconciled\"\n}"}]},{"name":"List Notification Events (audit log, paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/notification-events","host":["{{baseUrl}}"],"path":["api","amazon","notification-events"]},"description":"Paginated debug/audit log of delivered SP-API notification events across all Amazon instances, newest first. Read-only — lets support staff inspect exactly what Amazon delivered and how each event was processed (pending/processing/processed/failed, plus the raw payload and any error) when reconciling a missed or mis-handled notification. Filter by notification_type, processing_status, integration_instance_ids, or a free-text search over notification_id/error.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/notification-events","host":["{{baseUrl}}"],"path":["api","amazon","notification-events"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US - Main\",\n      \"notification_id\": \"a1b2c3d4-0000-1111-2222-333344445555\",\n      \"notification_type\": \"ORDER_CHANGE\",\n      \"phase\": 2,\n      \"payload_version\": \"1.0\",\n      \"event_time\": \"2026-06-09T11:42:00+00:00\",\n      \"processing_status\": \"processed\",\n      \"processed_at\": \"2026-06-09T11:42:03+00:00\",\n      \"error\": null,\n      \"payload\": {\n        \"NotificationType\": \"ORDER_CHANGE\",\n        \"Payload\": {\n          \"OrderChangeNotification\": {\n            \"AmazonOrderId\": \"111-2223334-5556667\"\n          }\n        }\n      },\n      \"created_at\": \"2026-06-09T11:42:01+00:00\",\n      \"updated_at\": \"2026-06-09T11:42:03+00:00\"\n    },\n    {\n      \"id\": 5011,\n      \"integration_instance_id\": 3,\n      \"integration_instance_name\": \"Amazon US - Main\",\n      \"notification_id\": \"b2c3d4e5-1111-2222-3333-444455556666\",\n      \"notification_type\": \"LISTINGS_ITEM_ISSUES_CHANGE\",\n      \"phase\": 5,\n      \"payload_version\": \"1.0\",\n      \"event_time\": \"2026-06-09T11:40:00+00:00\",\n      \"processing_status\": \"failed\",\n      \"processed_at\": \"2026-06-09T11:40:02+00:00\",\n      \"error\": \"No matching AmazonProduct for SKU ABC-123\",\n      \"payload\": {\n        \"NotificationType\": \"LISTINGS_ITEM_ISSUES_CHANGE\",\n        \"Payload\": {}\n      },\n      \"created_at\": \"2026-06-09T11:40:01+00:00\",\n      \"updated_at\": \"2026-06-09T11:40:02+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Replenishment Grid","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment?source_mode=WAREHOUSE_TRANSFER&origin_warehouse_id=3","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment"],"query":[{"key":"source_mode","value":"WAREHOUSE_TRANSFER","description":"Required. WAREHOUSE_TRANSFER or PURCHASE_ORDER — determines sourcing context for suggestions","disabled":true},{"key":"origin_warehouse_id","value":"3","description":"Required when source_mode=WAREHOUSE_TRANSFER. Warehouse the transfer ships from","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated FBA replenishment grid for an Amazon integration instance. Rows start from listed Amazon products (so products without existing FBA inventory or a restock report still appear), enriched with:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- FBA stock position (available, inbound, reserved) from the FBA inventory report\n- Amazon restock recommendation data (GET_RESTOCK_INVENTORY_RECOMMENDATIONS_REPORT) when present\n- Channel-scoped sales velocity (this instance's sales channel) and other-channel velocity\n- Origin warehouse availability + other-warehouse stock (warehouse transfer mode)\n- Supplier stock, MOQ and lead time (purchase order mode)\n- Quantity already committed on open draft inbound plans and open backorders\n- A calculated suggestion: TargetUnits = ceil(velocity x (target_days + lead_time + buffer)) minus net at Amazon, capped by origin/supplier availability, rounded down to case packs, with MOQ handling in PO mode\n\nSorted by Amazon's recommended replenishment quantity (desc, nulls last), then product SKU.\n\nAuthentication: Bearer token.\n\nValidation: source_mode is required; origin_warehouse_id is required for WAREHOUSE_TRANSFER; supplier_id is required for PURCHASE_ORDER.\n\nEach row includes `amazon_product_id` (the AmazonProduct row id) for deep-linking to the Amazon product detail page.\n\nSupports server `sort` and advanced `filter_groups` (GroupedFilterSupport). In PURCHASE_ORDER mode with `supplier_id`, rows are scoped to that supplier's catalog and each row carries `is_default_supplier` (false = supplier carries the product but isn't its default). Rows also include `amazon_fnsku_product_id`, `unit_weight_lb`, and `unit_volume_cuft` (for cart weight/volume/pallet estimates). Each row's `case_pack_qty` / `case_pack_rounding` come from the product's replenishment settings override, falling back to the instance default. Rows also carry the product's master-carton data — `units_per_case`, `case_weight_lb`, `case_volume_cuft` (normalized from the product's case-pack dimensions) — used to estimate cartons, pallet weight and pallet count in the cart."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment?source_mode=WAREHOUSE_TRANSFER&origin_warehouse_id=3","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment"],"query":[{"key":"source_mode","value":"WAREHOUSE_TRANSFER","description":"Required. WAREHOUSE_TRANSFER or PURCHASE_ORDER — determines sourcing context for suggestions","disabled":true},{"key":"origin_warehouse_id","value":"3","description":"Required when source_mode=WAREHOUSE_TRANSFER. Warehouse the transfer ships from","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"amazon_product_id\": 184,\n      \"amazon_fnsku_product_id\": 91,\n      \"is_default_supplier\": null,\n      \"unit_weight_lb\": 1.3,\n      \"unit_volume_cuft\": 0.05,\n      \"units_per_case\": 4,\n      \"case_weight_lb\": 36,\n      \"case_volume_cuft\": 6.15,\n      \"product_id\": 101,\n      \"product_sku\": \"WIDGET-001\",\n      \"product_name\": \"Blue Widget\",\n      \"product_image_url\": \"https://cdn.example.com/widget.jpg\",\n      \"msku\": \"WIDGET-001-FBA\",\n      \"asin\": \"B00WIDGET1\",\n      \"fnsku\": \"X00WIDGET1\",\n      \"country_code\": \"US\",\n      \"fba_available\": 42,\n      \"fba_inbound\": 24,\n      \"fba_reserved\": 3,\n      \"velocity\": 4.5,\n      \"velocity_window_days\": 30,\n      \"other_channel_velocity\": 1.2,\n      \"planned_unshipped\": 12,\n      \"open_backorders\": 5,\n      \"origin_available\": 320,\n      \"other_warehouse_stock\": 80,\n      \"on_purchase_order\": 150,\n      \"supplier_stock_qty\": null,\n      \"supplier_in_stock\": null,\n      \"supplier_lead_time_days\": null,\n      \"minimum_order_quantity\": null,\n      \"case_pack_qty\": 6,\n      \"case_pack_rounding\": \"always_round_down\",\n      \"target_days_of_supply\": 30,\n      \"buffer_days\": 7,\n      \"lead_time_days\": 0,\n      \"restock_units_sold_last_30_days\": 135,\n      \"restock_total_days_of_supply\": 14.6,\n      \"restock_alert\": \"Low inventory\",\n      \"restock_recommended_qty\": 120,\n      \"restock_recommended_ship_date\": \"2026-06-20\",\n      \"suggestion\": {\n        \"target_units\": 167,\n        \"net_at_amazon\": 78,\n        \"raw_suggested\": 89,\n        \"reserve_other\": 0,\n        \"cap\": 320,\n        \"suggested_quantity\": 84,\n        \"pre_rounding_quantity\": 89,\n        \"is_overstocked\": false,\n        \"is_capped\": false,\n        \"is_case_pack_rounded\": true,\n        \"moq_bumped\": false,\n        \"below_moq\": false\n      }\n    }\n  ],\n  \"first_page_url\": \"https://sku.test/api/amazon/1/replenishment?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"https://sku.test/api/amazon/1/replenishment?page=4\",\n  \"links\": [],\n  \"next_page_url\": \"https://sku.test/api/amazon/1/replenishment?page=2\",\n  \"path\": \"https://sku.test/api/amazon/1/replenishment\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 25,\n  \"total\": 93\n}"}]},{"name":"Refresh Restock Report","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Request a fresh GET_RESTOCK_INVENTORY_RECOMMENDATIONS_REPORT from Amazon for this instance. The report is created immediately and monitored via a tracked job — use the returned tracked_job_log_id with the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 409 Conflict when a restock report request is already in progress for this instance, including details of the conflicting report.\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/refresh","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5512\n  },\n  \"message\": \"Restock report refresh started\"\n}"}]},{"name":"Get Replenishment Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","settings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Replenishment settings for this instance: the instance-level default (product_id null) plus any per-product overrides, and the timestamp of the last restock report refresh.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSettings control the suggestion formula: target_days_of_supply, buffer_days, velocity_window_days, case_pack_qty, min_shelf_life_days and blackout_dates.\n\nAuthentication: Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","settings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"default\": {\n      \"id\": 1,\n      \"integration_instance_id\": 1,\n      \"product_id\": null,\n      \"target_days_of_supply\": 30,\n      \"buffer_days\": 7,\n      \"velocity_window_days\": 30,\n      \"case_pack_qty\": null,\n      \"min_shelf_life_days\": null,\n      \"blackout_dates\": null,\n      \"created_at\": \"2026-06-10T09:00:00.000000Z\",\n      \"updated_at\": \"2026-06-10T09:00:00.000000Z\",\n      \"case_pack_rounding\": \"always_round_down\"\n    },\n    \"overrides\": [\n      {\n        \"id\": 2,\n        \"integration_instance_id\": 1,\n        \"product_id\": 101,\n        \"target_days_of_supply\": 21,\n        \"buffer_days\": 3,\n        \"velocity_window_days\": 14,\n        \"case_pack_qty\": 6,\n        \"min_shelf_life_days\": 90,\n        \"blackout_dates\": null,\n        \"created_at\": \"2026-06-11T10:00:00.000000Z\",\n        \"updated_at\": \"2026-06-11T10:00:00.000000Z\",\n        \"case_pack_rounding\": \"always_round_down\"\n      }\n    ],\n    \"restock_report_generated_at\": \"2026-06-12T03:15:42+00:00\"\n  }\n}"}]},{"name":"Update Replenishment Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","settings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Upsert replenishment settings. Omit product_id (or send null) to update the instance-level default; send a product_id to create/update a per-product override.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- product_id: optional integer, must exist in products. Null = instance default\n- target_days_of_supply: required integer 1-365. Days of FBA coverage to target\n- buffer_days: required integer 0-365. Safety buffer added to the planning horizon\n- velocity_window_days: required integer 1-365. Trailing sales window used to compute daily velocity\n- case_pack_qty: optional integer >= 1. Suggestions round DOWN to whole case packs\n- min_shelf_life_days: optional integer >= 0\n- blackout_dates: optional array of dates\n\nAuthentication: Bearer token.\n\n**`case_pack_rounding`** (string, optional) — how suggested quantities round to full cases for products with a `case_pack_qty`: `always_round_down` (default — never exceed the target/cap), `always_round_up` (ship full cases; may overshoot the coverage target but never the origin/supplier stock cap), or `round_nearest`.\n\ncase_pack_rounding accepts: always_round_up, always_round_down, round_nearest, none (send the exact suggested quantity, no case-pack rounding).","body":{"mode":"raw","raw":"{\n  \"product_id\": 101,\n  \"target_days_of_supply\": 21,\n  \"buffer_days\": 3,\n  \"velocity_window_days\": 14,\n  \"case_pack_qty\": 6,\n  \"min_shelf_life_days\": 90,\n  \"blackout_dates\": [\n    \"2026-11-26\",\n    \"2026-12-25\"\n  ],\n  \"case_pack_rounding\": \"always_round_up\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon/{integrationInstance}/replenishment/settings","host":["{{baseUrl}}"],"path":["api","amazon",":integrationInstance","replenishment","settings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"integration_instance_id\": 1,\n    \"product_id\": 101,\n    \"target_days_of_supply\": 21,\n    \"buffer_days\": 3,\n    \"velocity_window_days\": 14,\n    \"case_pack_qty\": 6,\n    \"min_shelf_life_days\": 90,\n    \"blackout_dates\": [\n      \"2026-11-26\",\n      \"2026-12-25\"\n    ],\n    \"created_at\": \"2026-06-11T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-11T10:00:00.000000Z\",\n    \"case_pack_rounding\": \"always_round_down\"\n  },\n  \"message\": \"Replenishment settings saved\"\n}"}]},{"name":"Update Amazon Ads Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/settings","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","settings"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Update per-connection Amazon Ads settings. Currently this toggles whether a spend sync turns ad spend into cost entries (type \"Amazon Advertising\") with per-product cost allocations on mapped SKUs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCost-entry creation is opt-in and disabled by default. When enabled, each Sync Amazon Ads Spend creates/refreshes per-day cost entries and product allocations. When disabled (the default), the spend ledger still updates but has no accounting impact, and a sync removes any cost entries a prior sync created for the synced window.\n\nBody:\n- cost_entry_creation_enabled (boolean, required): turn cost-entry creation on/off.\n\nReturns the updated Amazon Ads connection resource. Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"cost_entry_creation_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/settings","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","settings"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Amazon Ads\",\n    \"region\": \"NA\",\n    \"is_connected\": true,\n    \"is_automatic_sync_enabled\": true,\n    \"sync_status\": \"active\",\n    \"profiles\": [\n      {\n        \"profileId\": 3902568284010101,\n        \"countryCode\": \"US\",\n        \"currencyCode\": \"USD\",\n        \"timezone\": \"America/Los_Angeles\",\n        \"accountInfo\": {\n          \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n          \"id\": \"A1X7T0NB572XNW\",\n          \"type\": \"seller\",\n          \"name\": \"PartUSA\"\n        }\n      }\n    ],\n    \"selected_profile_ids\": [\n      3902568284010101\n    ],\n    \"cost_entry_creation_enabled\": false,\n    \"created_at\": \"2026-06-13T15:02:11.000000Z\",\n    \"updated_at\": \"2026-06-16T01:40:55.000000Z\"\n  }\n}"}]},{"name":"Sync Amazon Ads Spend","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend/sync","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend","sync"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Dispatch an Amazon Ads Sponsored Products spend sync for this advertiser connection. Fire-and-forget: it queues a background job and returns the tracked-job log id so the frontend can follow progress via the tracked job log endpoints. The job is idempotent — re-syncing an overlapping window restates spend rather than double-counting it (Amazon revises attribution within ~14 days).\n\nBody (all optional):\n- profile_ids[]: limit to specific advertiser profile ids (default: the instance's selected profiles, falling back to all)\n- start_date / end_date (Y-m-d): explicit window. Both required together; end_date must be >= start_date. Omit both for the default trailing 14-day window ending yesterday.\n\nRequires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"profile_ids\": [\n    \"3902568284010101\"\n  ],\n  \"start_date\": \"2026-05-30\",\n  \"end_date\": \"2026-06-12\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend/sync","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend","sync"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 88412\n  },\n  \"message\": \"Amazon Ads spend sync started — track progress in the job tray.\"\n}"}]},{"name":"List Amazon Ads Spend Records","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Paginated per-ASIN/SKU Amazon Ads spend ledger for this advertiser connection. Each row carries spend, 7-day attributed sales, clicks, impressions, 7-day purchases, the computed ACoS, and whether the advertised SKU/ASIN mapped to a SKU.io product (is_mapped + product_* cross-link). Uses Spatie QueryBuilder filters/sorts.\n\nAllowed sorts: id, spend, attributed_sales_7d, clicks, impressions, purchases_7d, period_start, period_end, advertised_sku, advertised_asin, created_at, updated_at (default -spend).\n\nRequires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1012,\n      \"integration_instance_id\": 7,\n      \"profile_id\": \"3902568284010101\",\n      \"ad_product\": \"SPONSORED_PRODUCTS\",\n      \"advertised_sku\": \"WIDGET-RED-001\",\n      \"advertised_asin\": \"B07XYZ1234\",\n      \"product_id\": 4521,\n      \"is_mapped\": true,\n      \"product_sku\": \"WIDGET-RED-001\",\n      \"product_name\": \"Red Widget — 10 pack\",\n      \"product_route\": \"/products/4521\",\n      \"period_start\": \"2026-05-30\",\n      \"period_end\": \"2026-06-12\",\n      \"currency_code\": \"USD\",\n      \"spend\": 142.87,\n      \"attributed_sales_7d\": 921.5,\n      \"clicks\": 318,\n      \"impressions\": 20544,\n      \"purchases_7d\": 27,\n      \"acos\": 15.5,\n      \"created_at\": \"2026-06-13T05:00:11.000000Z\",\n      \"updated_at\": \"2026-06-13T05:00:11.000000Z\"\n    },\n    {\n      \"id\": 1013,\n      \"integration_instance_id\": 7,\n      \"profile_id\": \"3902568284010101\",\n      \"ad_product\": \"SPONSORED_PRODUCTS\",\n      \"advertised_sku\": \"OLD-SKU-999\",\n      \"advertised_asin\": \"B09AAA0000\",\n      \"product_id\": null,\n      \"is_mapped\": false,\n      \"product_sku\": null,\n      \"product_name\": null,\n      \"product_route\": null,\n      \"period_start\": \"2026-05-30\",\n      \"period_end\": \"2026-06-12\",\n      \"currency_code\": \"USD\",\n      \"spend\": 58.2,\n      \"attributed_sales_7d\": 0,\n      \"clicks\": 91,\n      \"impressions\": 7321,\n      \"purchases_7d\": 0,\n      \"acos\": null,\n      \"created_at\": \"2026-06-13T05:00:11.000000Z\",\n      \"updated_at\": \"2026-06-13T05:00:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 24,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Amazon Ads Spend Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend/summary","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend","summary"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Aggregate Amazon Ads spend/attribution summary for this advertiser connection over an optional date window + profile — feeds the summary cards. Returns total spend, 7-day attributed sales, ACoS, mapped vs unmapped spend split, the unmapped distinct SKU/ASIN count, and click/impression/purchase totals. The window defaults to a trailing 14-day range ending yesterday (matching the sync job's default pull) when no bounds are given.\n\nRequires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/spend/summary","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","spend","summary"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"period_start\": \"2026-05-30\",\n    \"period_end\": \"2026-06-12\",\n    \"profile_id\": null,\n    \"spend_total\": 1842.55,\n    \"attributed_sales_total\": 11920.4,\n    \"mapped_spend\": 1620.1,\n    \"unmapped_spend\": 222.45,\n    \"clicks_total\": 4120,\n    \"impressions_total\": 285330,\n    \"purchases_total\": 341,\n    \"unmapped_sku_count\": 3,\n    \"acos\": 15.46\n  }\n}"}]},{"name":"List Amazon Ads Connections","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads","host":["{{baseUrl}}"],"path":["api","amazon-ads"]},"description":"List every Amazon Advertising connection on the account. Each connection is a per-seller Login with Amazon authorization for the Amazon Ads API, holding the advertiser profiles discovered for that seller and the subset selected for spend syncing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`is_connected` reflects whether a valid authorization is stored; `region` is the Ads API region the connection was made in (NA, EU, or FE).\n\nConnections are created by authorizing through the SKU.io web app (Settings → Integrations → Amazon Ads); this API manages existing connections.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon-ads","host":["{{baseUrl}}"],"path":["api","amazon-ads"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"name\": \"Amazon Ads\",\n      \"region\": \"NA\",\n      \"is_connected\": true,\n      \"is_automatic_sync_enabled\": true,\n      \"sync_status\": \"active\",\n      \"profiles\": [\n        {\n          \"profileId\": 3902568284010101,\n          \"countryCode\": \"US\",\n          \"currencyCode\": \"USD\",\n          \"timezone\": \"America/Los_Angeles\",\n          \"accountInfo\": {\n            \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n            \"id\": \"A1X7T0NB572XNW\",\n            \"type\": \"seller\",\n            \"name\": \"PartUSA\"\n          }\n        }\n      ],\n      \"selected_profile_ids\": [\n        3902568284010101\n      ],\n      \"cost_entry_creation_enabled\": false,\n      \"created_at\": \"2026-06-13T15:02:11.000000Z\",\n      \"updated_at\": \"2026-06-16T01:40:55.000000Z\"\n    }\n  ]\n}"}]},{"name":"Get Amazon Ads Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Get a single Amazon Advertising connection, including its discovered advertiser profiles, the profile ids selected for syncing, and whether spend syncs create cost entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Amazon Ads\",\n    \"region\": \"NA\",\n    \"is_connected\": true,\n    \"is_automatic_sync_enabled\": true,\n    \"sync_status\": \"active\",\n    \"profiles\": [\n      {\n        \"profileId\": 3902568284010101,\n        \"countryCode\": \"US\",\n        \"currencyCode\": \"USD\",\n        \"timezone\": \"America/Los_Angeles\",\n        \"accountInfo\": {\n          \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n          \"id\": \"A1X7T0NB572XNW\",\n          \"type\": \"seller\",\n          \"name\": \"PartUSA\"\n        }\n      }\n    ],\n    \"selected_profile_ids\": [\n      3902568284010101\n    ],\n    \"cost_entry_creation_enabled\": false,\n    \"created_at\": \"2026-06-13T15:02:11.000000Z\",\n    \"updated_at\": \"2026-06-16T01:40:55.000000Z\"\n  }\n}"}]},{"name":"Delete Amazon Ads Connection","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Delete an Amazon Advertising connection. The stored authorization and profile selection are removed; already-ingested spend records are kept.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 204 No Content on success.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"List Advertiser Profiles","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"List the advertiser profiles stored for this connection along with the profile ids the user has opted into for spend syncing. Profiles are discovered from the Amazon Ads API when the connection is authorized and can be re-fetched with Refresh Advertiser Profiles.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"profiles\": [\n      {\n        \"profileId\": 3902568284010101,\n        \"countryCode\": \"US\",\n        \"currencyCode\": \"USD\",\n        \"timezone\": \"America/Los_Angeles\",\n        \"accountInfo\": {\n          \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n          \"id\": \"A1X7T0NB572XNW\",\n          \"type\": \"seller\",\n          \"name\": \"PartUSA\"\n        }\n      }\n    ],\n    \"selected_profile_ids\": [\n      3902568284010101\n    ]\n  }\n}"}]},{"name":"Update Selected Advertiser Profiles","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Persist which advertiser profiles are selected for spend syncing on this connection. Only selected profiles are pulled during a spend sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `profile_ids` (required, array) — the Amazon profile ids to sync. Send an empty array to clear the selection.\n\nReturns the updated connection.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"profile_ids\": [\n    3902568284010101\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Amazon Ads\",\n    \"region\": \"NA\",\n    \"is_connected\": true,\n    \"is_automatic_sync_enabled\": true,\n    \"sync_status\": \"active\",\n    \"profiles\": [\n      {\n        \"profileId\": 3902568284010101,\n        \"countryCode\": \"US\",\n        \"currencyCode\": \"USD\",\n        \"timezone\": \"America/Los_Angeles\",\n        \"accountInfo\": {\n          \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n          \"id\": \"A1X7T0NB572XNW\",\n          \"type\": \"seller\",\n          \"name\": \"PartUSA\"\n        }\n      }\n    ],\n    \"selected_profile_ids\": [\n      3902568284010101\n    ],\n    \"cost_entry_creation_enabled\": false,\n    \"created_at\": \"2026-06-13T15:02:11.000000Z\",\n    \"updated_at\": \"2026-06-16T01:40:55.000000Z\"\n  }\n}"}]},{"name":"Refresh Advertiser Profiles","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles/refresh","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles","refresh"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]},"description":"Re-fetch the advertiser profiles from the Amazon Ads API and persist them on the connection. Use this when the seller has gained (or lost) access to advertiser profiles since connecting.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nA failed upstream call is reported as a 422 with an actionable message: a rejected authorization (Amazon answers 401/403) prompts a reconnect, any other upstream failure asks to retry.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/amazon-ads/{integrationInstance}/profiles/refresh","host":["{{baseUrl}}"],"path":["api","amazon-ads",":integrationInstance","profiles","refresh"],"variable":[{"key":"integrationInstance","value":"7","description":"Amazon Ads integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"profiles\": [\n      {\n        \"profileId\": 3902568284010101,\n        \"countryCode\": \"US\",\n        \"currencyCode\": \"USD\",\n        \"timezone\": \"America/Los_Angeles\",\n        \"accountInfo\": {\n          \"marketplaceStringId\": \"ATVPDKIKX0DER\",\n          \"id\": \"A1X7T0NB572XNW\",\n          \"type\": \"seller\",\n          \"name\": \"PartUSA\"\n        }\n      }\n    ],\n    \"selected_profile_ids\": [\n      3902568284010101\n    ]\n  }\n}"}]}]},{"name":"Shopify","item":[{"name":"Get OAuth Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/config","host":["{{baseUrl}}"],"path":["api","shopify","config"]},"description":"Returns the Shopify OAuth configuration that tells the frontend which connection mode to render.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse fields:\n- custom_app_mode (bool): when true, per-instance Client ID/Secret are used (custom app). When false, SKU.io's central public app credentials are used.\n- legacy_custom_app_mode (bool): when true, the merchant pastes an Admin API access token directly (no OAuth).\n- scopes (string): comma-separated OAuth scopes requested.\n- redirect_url (string): the OAuth callback URL ({app_url}/shopify/callback).\n\nMode matrix:\n- Public OAuth: custom_app_mode=false, legacy_custom_app_mode=false (no credentials entered; merchant just authorizes).\n- Custom-app OAuth: custom_app_mode=true, legacy_custom_app_mode=false.\n- Legacy custom app: legacy_custom_app_mode=true.\n\nNote: custom_app_mode and legacy_custom_app_mode are resolved per-tenant. A tenant may override either flag (operators set this via the shopify:set-app-mode artisan command); when no override is present the global config default applies. The response shape is identical regardless of how the values resolve, so different tenants may legitimately return different mode values."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/config","host":["{{baseUrl}}"],"path":["api","shopify","config"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"custom_app_mode\": false,\n  \"legacy_custom_app_mode\": false,\n  \"scopes\": \"write_customers,read_customers,write_orders,read_orders,read_all_orders,write_products,read_products,write_inventory,read_inventory,write_fulfillments,read_fulfillments,write_returns,read_returns\",\n  \"redirect_url\": \"https://app.sku.io/shopify/callback\"\n}"}]},{"name":"List Integrations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify","host":["{{baseUrl}}"],"path":["api","shopify"]},"description":"Lists every Shopify integration instance connected to the account. Returns a lightweight summary per instance; use Get Integration for the full configuration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThis endpoint is not paginated - all instances are returned in a single response."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify","host":["{{baseUrl}}"],"path":["api","shopify"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Main Shopify Store\",\n      \"is_automatic_sync_enabled\": true,\n      \"use_location_mapping_for_new_orders\": false,\n      \"created_at\": \"2024-01-05T09:12:00.000000Z\",\n      \"updated_at\": \"2025-06-20T14:03:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"EU Shopify Store\",\n      \"is_automatic_sync_enabled\": false,\n      \"use_location_mapping_for_new_orders\": true,\n      \"created_at\": \"2024-03-11T10:30:00.000000Z\",\n      \"updated_at\": \"2025-06-18T08:41:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Integration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify","host":["{{baseUrl}}"],"path":["api","shopify"]},"description":"Create a new Shopify integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (string, required, unique across integration_instances.name)\n- connection_settings.url (string, required): full store URL, must start with https:// and not end with /. e.g. https://my-store.myshopify.com\n- connection_settings.consumer_key (string, OPTIONAL): only for legacy custom-app (API key) and custom-app OAuth (Client ID) modes. OMIT in public OAuth mode — SKU.io's central credentials are used.\n- connection_settings.consumer_secret (string, OPTIONAL): only for legacy custom-app (Admin API access token) and custom-app OAuth (Secret) modes. OMIT in public OAuth mode.\n- connection_settings.key_id (int, optional), user_id (string, optional), key_permissions (string, optional)\n- integration_settings.start_date (string, required, Y-m-d; must be on/after the inventory start date if configured)\n- integration_settings.store_id (int, required, must exist in stores)\n- integration_settings.auto_link_products (bool), auto_create_products (bool)\n- integration_settings.*_nominal_code_id (int|null): sales, cogs, shipping_revenue, shipping_refund, sales_returns_allowances, fees\n- integration_settings.download_archived_products (bool), download_draft_products (bool), require_mapped_products_for_sales_order (bool)\n- is_automatic_sync_enabled (bool, default false)\n\nBehavior by mode:\n- Public OAuth & Custom-app OAuth: response includes a redirect_url; the frontend then calls GET /api/shopify/{id}/authorization-url and redirects the merchant to Shopify. Init jobs run after the OAuth callback.\n- Legacy custom app: no OAuth; init jobs run immediately and the instance is marked ACTIVE.","body":{"mode":"raw","raw":"{\n  \"name\": \"Main Shopify Store\",\n  \"connection_settings\": {\n    \"url\": \"https://my-store.myshopify.com\",\n    \"consumer_key\": \"8e894995d119436434f0f28e8ec69eb4\",\n    \"consumer_secret\": \"shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 1,\n    \"auto_link_products\": false,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"download_archived_products\": false,\n    \"download_draft_products\": false,\n    \"require_mapped_products_for_sales_order\": false\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify","host":["{{baseUrl}}"],"path":["api","shopify"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Main Shopify Store\",\n    \"integration_id\": 3,\n    \"sync_status\": \"pending\",\n    \"is_automatic_sync_enabled\": true,\n    \"connection_settings\": {\n      \"url\": \"https://my-store.myshopify.com\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 1\n    },\n    \"created_at\": \"2026-06-03T10:15:00.000000Z\",\n    \"updated_at\": \"2026-06-03T10:15:00.000000Z\"\n  },\n  \"redirect_url\": \"https://my-store.myshopify.com/admin/oauth/authorize?client_id=8e894995d119436434f0f28e8ec69eb4&scope=...&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fshopify%2Fcallback&state=acme_12\"\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/authorization-url","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","authorization-url"],"variable":[{"key":"integrationInstance","value":"12","description":"The integration instance ID."}]},"description":"Returns the Shopify OAuth authorization URL for an integration instance. The frontend redirects the merchant's browser to this URL to begin authorization.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- integrationInstance (int, required): the integration instance id.\n\nNotes:\n- Requires connection_settings.url (or legacy shop_url) to be set on the instance.\n- Uses per-instance credentials in custom-app mode, otherwise SKU.io's central public-app Client ID.\n- A tenant-aware state is generated so the central-domain callback can rehydrate tenancy."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/authorization-url","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","authorization-url"],"variable":[{"key":"integrationInstance","value":"12","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://my-store.myshopify.com/admin/oauth/authorize?client_id=8e894995d119436434f0f28e8ec69eb4&scope=write_orders%2Cread_orders%2Cwrite_products%2Cread_products&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fshopify%2Fcallback&state=acme_12\"\n}"}]},{"name":"Get Integration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns the full configuration of a Shopify integration instance, including its linked store and sales channel, integration settings, granular sync controls (which capabilities sync automatically), and whether the sync schedule is paused.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Main Shopify Store\",\n    \"sync_status\": \"active\",\n    \"is_automatic_sync_enabled\": true,\n    \"use_location_mapping_for_new_orders\": false,\n    \"integration_name\": \"shopify\",\n    \"sales_channel_id\": 12,\n    \"store\": {\n      \"id\": 4,\n      \"name\": \"Main Shopify Store\"\n    },\n    \"sync_controls\": {\n      \"orders\": {\n        \"download\": true,\n        \"upload\": true\n      },\n      \"products\": {\n        \"download\": true\n      },\n      \"inventory\": {\n        \"upload\": true\n      },\n      \"fulfillments\": {\n        \"upload\": true\n      }\n    },\n    \"applicable_sync_capabilities\": [\n      \"orders\",\n      \"products\",\n      \"inventory\",\n      \"fulfillments\"\n    ],\n    \"is_sync_schedule_paused\": false,\n    \"integration_settings\": {\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 4,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"shipping_method_field\": \"title\",\n      \"override_shipping_method\": true,\n      \"allow_negative_inventory\": false\n    },\n    \"created_at\": \"2024-01-05T09:12:00.000000Z\",\n    \"updated_at\": \"2025-06-20T14:03:00.000000Z\"\n  }\n}"}]},{"name":"Update Integration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Updates a Shopify integration instance. All fields are optional - send only what you want to change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPATCH is also accepted at this URL. With PATCH, nested connection_settings and integration_settings objects are deep-merged with the stored values (JSON merge semantics), while PUT replaces each settings object you provide. Inventory location arrays are always replaced in full, never merged.\n\nSide effects: changing start_date re-anchors order syncing; changing store_id re-links the sales channel's store; changing the pricing master or inventory settings queues background cache rebuilds; toggling the accounting sync flags re-evaluates which historical transactions sync to accounting.\n\nBody fields:\n- name (string): display name (must stay unique).\n- connection_settings (object): url (https, no trailing slash), consumer_key, consumer_secret (custom-app modes only).\n- integration_settings (object): start_date (Y-m-d, must be on/after the inventory start date), store_id, auto_link_products, auto_create_products, sales/cogs/shipping_revenue/shipping_refund/sales_returns_allowances_nominal_code_id, pricing, inventory, emailCustomers, proforma_marketplace_cost_percentage, proforma_payment_cost_percentage, sync_sales_order_invoices_to_accounting, sync_sales_credit_to_accounting, download_archived_products, download_draft_products, download_unlisted_products, shipping_method_field (title|code), override_shipping_method, fallback_shipping_method_id (id of a shipping method applied when a Shopify order has no resolvable shipping method), pickup_sync (sync_ready_for_pickup, notify_customer_ready_for_pickup, notify_customer_picked_up), settings (nested, e.g. orders.delivery_ship_dates), orders (e.g. hold_and_ship_by_date), returns (return receipt sync), allow_negative_inventory.\n- is_automatic_sync_enabled (boolean).\n- use_location_mapping_for_new_orders (boolean): route new orders to warehouses via location mappings.\n\nintegration_settings.cost_sync.fallback_to_default_cost (boolean): when a product has no average cost, fall back to its default cost for the cost push.","body":{"mode":"raw","raw":"{\n  \"name\": \"Main Shopify Store\",\n  \"is_automatic_sync_enabled\": true,\n  \"use_location_mapping_for_new_orders\": true,\n  \"connection_settings\": {\n    \"url\": \"https://my-store.myshopify.com\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 4,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": 12,\n    \"cogs_nominal_code_id\": 18,\n    \"shipping_revenue_nominal_code_id\": 14,\n    \"shipping_refund_nominal_code_id\": 15,\n    \"sales_returns_allowances_nominal_code_id\": 16,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true,\n    \"download_archived_products\": false,\n    \"download_draft_products\": false,\n    \"download_unlisted_products\": false,\n    \"shipping_method_field\": \"title\",\n    \"override_shipping_method\": true,\n    \"fallback_shipping_method_id\": 5,\n    \"allow_negative_inventory\": false,\n    \"pickup_sync\": {\n      \"sync_ready_for_pickup\": true,\n      \"notify_customer_ready_for_pickup\": false,\n      \"notify_customer_picked_up\": false\n    },\n    \"cost_sync\": {\n      \"fallback_to_default_cost\": true\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Main Shopify Store\",\n    \"sync_status\": \"active\",\n    \"is_automatic_sync_enabled\": true,\n    \"use_location_mapping_for_new_orders\": false,\n    \"integration_name\": \"shopify\",\n    \"sales_channel_id\": 12,\n    \"store\": {\n      \"id\": 4,\n      \"name\": \"Main Shopify Store\"\n    },\n    \"sync_controls\": {\n      \"orders\": {\n        \"download\": true,\n        \"upload\": true\n      },\n      \"products\": {\n        \"download\": true\n      },\n      \"inventory\": {\n        \"upload\": true\n      },\n      \"fulfillments\": {\n        \"upload\": true\n      }\n    },\n    \"applicable_sync_capabilities\": [\n      \"orders\",\n      \"products\",\n      \"inventory\",\n      \"fulfillments\"\n    ],\n    \"is_sync_schedule_paused\": false,\n    \"integration_settings\": {\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 4,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"shipping_method_field\": \"title\",\n      \"override_shipping_method\": true,\n      \"allow_negative_inventory\": false\n    },\n    \"created_at\": \"2024-01-05T09:12:00.000000Z\",\n    \"updated_at\": \"2025-06-20T14:03:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Disconnects a Shopify integration instance. The webhooks SKU.io registered on the shop are removed first, then deletion of the instance and its synced data is queued as a background operation - the endpoint returns immediately with 204 while cleanup continues asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nWarning: this is irreversible. Synced Shopify orders, products, and mappings for the instance are removed."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Auth Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/auth-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","auth-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns the connection settings for an integration instance with secrets masked (only the last 4 characters are visible), plus the current sync status and shop URL. Useful for showing connection state without exposing credentials.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/auth-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","auth-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"connection_settings\": {\n      \"url\": \"https://my-store.myshopify.com\",\n      \"consumer_key\": \"8e894995d119436434f0f28e8ec69eb4\",\n      \"consumer_secret\": \"********************************ab12\"\n    },\n    \"sync_status\": \"active\",\n    \"shop_url\": \"https://my-store.myshopify.com\",\n    \"name\": \"Main Shopify Store\",\n    \"is_automatic_sync_enabled\": true\n  }\n}"}]},{"name":"Show Install (Claim Page)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/install/{claimToken}","host":["{{baseUrl}}"],"path":["api","shopify","install",":claimToken"],"variable":[{"key":"claimToken","value":"5f3a...e91c","description":"Opaque 256-bit claim token from the /connect/shopify?claim= redirect."}]},"description":"PUBLIC (no authentication). Reveals the Shopify store being connected on the claim page after an App Store cold install.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe opaque `claimToken` in the path IS the credential — it is minted after OAuth and redirected to `app.sku.io/connect/shopify?claim=<token>`. This endpoint deliberately exposes only the shop's display identity and lifecycle status; the stashed offline token, scopes, shop email/country, and all internal ids are NEVER returned.\n\nThrottled to 30 req/min to blunt token-guessing.\n\nResponse fields (under `data`):\n- shop_domain (string): the *.myshopify.com domain being connected.\n- shop_name (string): the shop's display name (or a humanized subdomain fallback).\n- status (string): lifecycle status — one of pending_auth, awaiting_claim, claiming, claimed, claim_failed, failed, expired, abandoned.\n\nReturns 404 when the token matches nothing (invalid or already-consumed)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/install/{claimToken}","host":["{{baseUrl}}"],"path":["api","shopify","install",":claimToken"],"variable":[{"key":"claimToken","value":"5f3a...e91c","description":"Opaque 256-bit claim token from the /connect/shopify?claim= redirect."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shop_domain\": \"acme-supplies.myshopify.com\",\n    \"shop_name\": \"Acme Supplies\",\n    \"status\": \"awaiting_claim\"\n  }\n}"}]},{"name":"Claim Install (Attach to Existing Workspace)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/install/{claimToken}/claim","host":["{{baseUrl}}"],"path":["api","shopify","install",":claimToken","claim"],"variable":[{"key":"claimToken","value":"5f3a...e91c","description":"Opaque claim token."}]},"description":"AUTHENTICATED. Attaches a stashed cold install to a workspace the signed-in merchant already belongs to. The merchant MUST already have a SKU.io account — this flow never creates users or tenants.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe bearer user is resolved from auth:sanctum manually (no route middleware), so the claim page stays anonymous until the merchant signs in; a Bearer token is therefore REQUIRED and an anonymous request is rejected with 401.\n\nResolves synchronously and returns 200 with the cross-subdomain tenant-switch handoff, which the claim page uses to drop the merchant onto their tenant, authenticated. A re-install into a tenant that already has an instance for the shop refreshes that instance's token in place (no duplicate).\n\nThrottled to 30 req/min.\n\nRequest fields:\n- tenant_id (string, required): the id of a workspace the signed-in merchant already belongs to; validated against the central tenants table.\n\nResponses:\n- 200 OK: handoff payload — status=claimed, switch_token, target_host, tenant_id, instance_id, landing_path.\n- 401 Unauthorized: no signed-in user (the merchant must sign in first).\n- 404 Not Found: unknown/consumed claim token.\n- 409 Conflict: the store is already being connected (lost the atomic claim race) or already claimed.\n- 410 Gone: the claim link has expired (reinstall from the App Store).\n- 422 Unprocessable: validation error (e.g. unknown tenant_id).","body":{"mode":"raw","raw":"{\n  \"tenant_id\": \"acme\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/install/{claimToken}/claim","host":["{{baseUrl}}"],"path":["api","shopify","install",":claimToken","claim"],"variable":[{"key":"claimToken","value":"5f3a...e91c","description":"Opaque claim token."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"status\": \"claimed\",\n    \"switch_token\": \"eyJ0eXAiOiJ...handoff\",\n    \"target_host\": \"acme.sku.io\",\n    \"tenant_id\": \"acme\",\n    \"instance_id\": 42,\n    \"landing_path\": \"/integrations/shopify/dashboard\"\n  }\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[financial_status]=paid&filter[fulfillment_status]=fulfilled&filter[currency]=USD&filter[source_name]=web&filter[payment_gateway]=shopify_payments&filter[status]=active&filter[has_sku_order]=true&filter[has_unmapped_items]=false&filter[has_non_product_items]=false&filter[cancelled]=false&filter[name.contains]=1001&filter[email.contains]=john&filter[total_price.gte]=50&filter[shopify_created_at.gte]=2024-01-01&filter[shopify_processed_at.lte]=2024-12-31&search_columns=name,email","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, name, email, total_price, created_at, shopify_created_at, shopify_updated_at, shopify_processed_at, financial_status, fulfillment_status, legacy_resource_id, currency, shopify_cancelled_at, billing_name, shipping_name, payment_gateway, sales_order, shipping_method","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search across order name, email, Shopify ID, SKU SO#, SKU line items, shipping method","disabled":true},{"key":"filter[financial_status]","value":"paid","description":"Exact match: pending, authorized, partially_paid, paid, partially_refunded, refunded, voided","disabled":true},{"key":"filter[fulfillment_status]","value":"fulfilled","description":"Exact match: fulfilled, null, partial, restocked","disabled":true},{"key":"filter[currency]","value":"USD","description":"Exact match on currency code","disabled":true},{"key":"filter[source_name]","value":"web","description":"Exact match on source name","disabled":true},{"key":"filter[payment_gateway]","value":"shopify_payments","description":"Filter by payment gateway (via transactions)","disabled":true},{"key":"filter[status]","value":"active","description":"active (non-archived) or archived","disabled":true},{"key":"filter[has_sku_order]","value":"true","description":"true = has linked SKU sales order, false = no SKU order","disabled":true},{"key":"filter[has_unmapped_items]","value":"false","description":"true = has unmapped line items","disabled":true},{"key":"filter[has_non_product_items]","value":"false","description":"true = has non-product line items","disabled":true},{"key":"filter[cancelled]","value":"false","description":"true = cancelled orders only, false = exclude cancelled","disabled":true},{"key":"filter[name.contains]","value":"1001","description":"Advanced text filter on order name","disabled":true},{"key":"filter[email.contains]","value":"john","description":"Advanced text filter on email","disabled":true},{"key":"filter[total_price.gte]","value":"50","description":"Numeric filter: total_price >= value","disabled":true},{"key":"filter[shopify_created_at.gte]","value":"2024-01-01","description":"Datetime filter on shopify_created_at","disabled":true},{"key":"filter[shopify_processed_at.lte]","value":"2024-12-31","description":"Datetime filter on shopify_processed_at","disabled":true},{"key":"search_columns","value":"name,email","description":"Comma-separated columns for targeted search (name, email, legacy_resource_id, etc.)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List Shopify orders for an integration instance with advanced filtering, sorting, and pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nDefault: returns non-archived orders sorted by -id.\n\nSort fields: id, name, email, total_price, created_at, shopify_created_at, shopify_updated_at, shopify_processed_at, financial_status, fulfillment_status, legacy_resource_id, currency, shopify_cancelled_at, billing_name, shipping_name, payment_gateway, sales_order, shipping_method\n\nFilter system uses both simple (filter[field]) and AdvancedFilterBuilder operators (filter[field.op])."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[financial_status]=paid&filter[fulfillment_status]=fulfilled&filter[currency]=USD&filter[source_name]=web&filter[payment_gateway]=shopify_payments&filter[status]=active&filter[has_sku_order]=true&filter[has_unmapped_items]=false&filter[has_non_product_items]=false&filter[cancelled]=false&filter[name.contains]=1001&filter[email.contains]=john&filter[total_price.gte]=50&filter[shopify_created_at.gte]=2024-01-01&filter[shopify_processed_at.lte]=2024-12-31&search_columns=name,email","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, name, email, total_price, created_at, shopify_created_at, shopify_updated_at, shopify_processed_at, financial_status, fulfillment_status, legacy_resource_id, currency, shopify_cancelled_at, billing_name, shipping_name, payment_gateway, sales_order, shipping_method","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search across order name, email, Shopify ID, SKU SO#, SKU line items, shipping method","disabled":true},{"key":"filter[financial_status]","value":"paid","description":"Exact match: pending, authorized, partially_paid, paid, partially_refunded, refunded, voided","disabled":true},{"key":"filter[fulfillment_status]","value":"fulfilled","description":"Exact match: fulfilled, null, partial, restocked","disabled":true},{"key":"filter[currency]","value":"USD","description":"Exact match on currency code","disabled":true},{"key":"filter[source_name]","value":"web","description":"Exact match on source name","disabled":true},{"key":"filter[payment_gateway]","value":"shopify_payments","description":"Filter by payment gateway (via transactions)","disabled":true},{"key":"filter[status]","value":"active","description":"active (non-archived) or archived","disabled":true},{"key":"filter[has_sku_order]","value":"true","description":"true = has linked SKU sales order, false = no SKU order","disabled":true},{"key":"filter[has_unmapped_items]","value":"false","description":"true = has unmapped line items","disabled":true},{"key":"filter[has_non_product_items]","value":"false","description":"true = has non-product line items","disabled":true},{"key":"filter[cancelled]","value":"false","description":"true = cancelled orders only, false = exclude cancelled","disabled":true},{"key":"filter[name.contains]","value":"1001","description":"Advanced text filter on order name","disabled":true},{"key":"filter[email.contains]","value":"john","description":"Advanced text filter on email","disabled":true},{"key":"filter[total_price.gte]","value":"50","description":"Numeric filter: total_price >= value","disabled":true},{"key":"filter[shopify_created_at.gte]","value":"2024-01-01","description":"Datetime filter on shopify_created_at","disabled":true},{"key":"filter[shopify_processed_at.lte]","value":"2024-12-31","description":"Datetime filter on shopify_processed_at","disabled":true},{"key":"search_columns","value":"name,email","description":"Comma-separated columns for targeted search (name, email, legacy_resource_id, etc.)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"name\": \"#1001\",\n      \"email\": \"customer@example.com\",\n      \"financial_status\": \"paid\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"total_price\": \"89.97\",\n      \"currency\": \"USD\",\n      \"legacy_resource_id\": \"5001234567890\",\n      \"source_name\": \"web\",\n      \"shopify_created_at\": \"2024-03-01T09:00:00+00:00\",\n      \"shopify_updated_at\": \"2024-03-02T10:00:00+00:00\",\n      \"shopify_processed_at\": \"2024-03-01T09:05:00+00:00\",\n      \"shopify_cancelled_at\": null,\n      \"billing_name\": \"John Smith\",\n      \"shipping_name\": \"John Smith\",\n      \"shopify_admin_url\": \"https://admin.shopify.com/store/mystore/orders/5001234567890\",\n      \"payment_gateway\": \"shopify_payments\",\n      \"shipping_method\": \"Standard Shipping\",\n      \"source_identifier\": null,\n      \"sku_sales_order_updated_at\": \"2024-03-01T09:10:00+00:00\",\n      \"created_at\": \"2024-03-01T09:00:00+00:00\",\n      \"updated_at\": \"2024-03-02T10:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 10,\n  \"per_page\": 15,\n  \"total\": 145,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Returns a synced Shopify order by its SKU.io row ID, including its line items (with the mapped SKU.io product for each), the linked SKU.io sales order with its fulfillments, computed billing/shipping names, payment gateways, shipping methods, and a direct Shopify admin link.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"integration_instance_id\": 1,\n    \"legacy_resource_id\": \"6001098342\",\n    \"name\": \"#1001\",\n    \"email\": \"jane@example.com\",\n    \"currency\": \"USD\",\n    \"financial_status\": \"paid\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"total_price\": \"59.90\",\n    \"subtotal_price\": \"49.90\",\n    \"total_tax\": \"4.50\",\n    \"total_discounts\": \"0.00\",\n    \"total_shipping_price\": \"5.50\",\n    \"source_name\": \"web\",\n    \"source_identifier\": null,\n    \"billing_name\": \"Jane Doe\",\n    \"shipping_name\": \"Jane Doe\",\n    \"payment_gateway\": \"shopify_payments\",\n    \"shipping_method\": \"Standard Shipping\",\n    \"shopify_admin_url\": \"https://admin.shopify.com/store/my-store/orders/6001098342\",\n    \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\",\n    \"shopify_updated_at\": \"2025-05-22T08:30:00+00:00\",\n    \"sku_sales_order_updated_at\": \"2025-05-22T08:31:00+00:00\",\n    \"sku_sales_order\": {\n      \"id\": 9001,\n      \"number\": \"SO-1001\",\n      \"order_status\": \"completed\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"payment_status\": \"paid\",\n      \"fulfillments\": [\n        {\n          \"id\": 3301,\n          \"status\": \"fulfilled\",\n          \"fulfillment_type\": \"warehouse\",\n          \"tracking_number\": \"1Z999AA10123456784\",\n          \"cost\": null,\n          \"fulfilled_at\": \"2025-05-21T18:00:00.000000Z\",\n          \"submitted_to_sales_channel_at\": \"2025-05-21T18:05:00.000000Z\",\n          \"warehouse\": {\n            \"id\": 2,\n            \"name\": \"Main Warehouse\"\n          },\n          \"shipping_method\": {\n            \"id\": 8,\n            \"name\": \"Ground\"\n          },\n          \"line_items\": [\n            {\n              \"id\": 8801,\n              \"quantity\": 2,\n              \"product_name\": \"Blue T-Shirt (M)\",\n              \"sku\": \"TSHIRT-M-BLUE\"\n            }\n          ]\n        }\n      ]\n    },\n    \"order_items\": [\n      {\n        \"id\": 7001,\n        \"legacy_resource_id\": \"14000123\",\n        \"name\": \"Blue T-Shirt (M)\",\n        \"sku\": \"TSHIRT-M-BLUE\",\n        \"quantity\": 2,\n        \"price\": \"24.95\",\n        \"mapped_product\": {\n          \"id\": 301,\n          \"sku\": \"TSHIRT-M-BLUE\",\n          \"name\": \"Blue T-Shirt (M)\"\n        }\n      }\n    ],\n    \"created_at\": \"2025-05-20T16:07:00+00:00\",\n    \"updated_at\": \"2025-05-22T08:31:00+00:00\"\n  }\n}"}]},{"name":"Delete Single Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Delete a single Shopify order from the local database.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order deleted successfully\"\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get aggregate stats about order sync status. Returns total counts, SKU order coverage, and the sync cursor used for incremental syncs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe sync_cursor_at should be used (not latest_order_date) for incremental refreshes to avoid gaps caused by manual single-order syncs.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_name\": \"#2045\",\n    \"latest_order_date\": \"2024-03-20T14:30:00.000000Z\",\n    \"sync_cursor_at\": \"2024-03-20T12:00:00.000000Z\",\n    \"total_orders\": 2045,\n    \"total_with_sku_order\": 1980,\n    \"total_without_sku_order\": 65,\n    \"last_sync_at\": \"2024-03-20 12:00:00\"\n  }\n}"}]},{"name":"Search Shopify Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/search-shopify","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","search-shopify"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Search for orders directly in the Shopify store via GraphQL API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- search_by: required, in: order_number, order_id, email\n- query: required, string, max:255","body":{"mode":"raw","raw":"{\n  \"search_by\": \"order_number\",\n  \"query\": \"1001\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/search-shopify","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","search-shopify"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"legacy_resource_id\": \"5001234567890\",\n      \"name\": \"#1001\",\n      \"email\": \"customer@example.com\",\n      \"shopify_created_at\": \"2024-03-01T09:00:00Z\",\n      \"shopify_updated_at\": \"2024-03-02T10:00:00Z\",\n      \"financial_status\": \"PAID\",\n      \"fulfillment_status\": \"FULFILLED\",\n      \"total_price\": {\n        \"amount\": \"89.97\",\n        \"currencyCode\": \"USD\"\n      },\n      \"currency\": \"USD\",\n      \"exists_in_database\": true,\n      \"database_id\": 501\n    }\n  ]\n}"}]},{"name":"Get Order Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Get the full ShipHero order detail for the order detail page (by local row id via route-model binding). Returns structured header fields (status, tracking, and `shipping_method` — the requested method/carrier/price from the order's shipping lines), the SKU.io fulfillment cross-link, line items, shipping labels and address, plus the full decoded `json_object`. `has_detailed_data` is false when no raw payload has been cached yet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"integration_instance_id\": 8,\n    \"shiphero_id\": \"T3JkZXI6MTAwNTc0MjM1\",\n    \"order_number\": \"SO-100245\",\n    \"external_url\": \"https://app.shiphero.com/dashboard/orders/details/T3JkZXI6MTAwNTc0MjM1\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"fulfillment_status_label\": \"Fulfilled\",\n    \"fulfillment_status_color\": \"success\",\n    \"order_date\": \"2026-06-10\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipped_at\": \"2026-06-11T14:32:00.000000Z\",\n    \"shipping_method\": {\n      \"method\": \"UPS Ground\",\n      \"carrier\": \"ups\",\n      \"price\": 8.5\n    },\n    \"sku_fulfillment\": {\n      \"id\": 4501,\n      \"link_reference\": \"FUL-100245\",\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4501,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4501\",\n      \"status\": \"fulfilled\",\n      \"sales_order_id\": 245,\n      \"sales_order_number\": \"SO-100245\",\n      \"fulfillment_order_id\": 312\n    },\n    \"line_items\": [\n      {\n        \"sku\": \"WIDGET-01\",\n        \"product_name\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"product_id\": 88\n      }\n    ],\n    \"shipping_labels\": [\n      {\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"carrier\": \"UPS\",\n        \"created_date\": \"2026-06-11T14:32:00+00:00\"\n      }\n    ],\n    \"shipping_address\": {\n      \"first_name\": \"Aaron\",\n      \"last_name\": \"Rubin\",\n      \"address1\": \"120 W 45th St\",\n      \"city\": \"New York\",\n      \"state\": \"NY\",\n      \"zip\": \"10036\",\n      \"country\": \"US\"\n    },\n    \"has_detailed_data\": true,\n    \"json_object\": {\n      \"order_number\": \"SO-100245\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"order_date\": \"2026-06-10T09:15:00+00:00\",\n      \"shipping_lines\": {\n        \"carrier\": \"ups\",\n        \"method\": \"UPS Ground\",\n        \"price\": \"8.50\"\n      },\n      \"shipping_labels\": [\n        {\n          \"tracking_number\": \"1Z999AA10123456784\",\n          \"carrier\": \"UPS\",\n          \"created_date\": \"2026-06-11T14:32:00+00:00\"\n        }\n      ]\n    },\n    \"created_at\": \"2026-06-10T09:15:00.000000Z\",\n    \"updated_at\": \"2026-06-11T14:32:05.000000Z\"\n  }\n}"}]},{"name":"Get Raw Order (REST)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Fetch raw order data from the Shopify REST API for debugging. Data is not persisted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf Shopify can't return the order — order older than 60 days without the read_all_orders scope, or an order deleted on Shopify — the endpoint returns HTTP 200 with `data: null` and an `unavailable_reason` string explaining why. Orders that originated as drafts (source_name = shopify_draft_order) are completed orders and are read from the standard orders endpoint with the read_orders scope.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5001234567890,\n    \"order_number\": 1001,\n    \"name\": \"#1001\",\n    \"financial_status\": \"paid\",\n    \"line_items\": []\n  }\n}"}]},{"name":"Get Raw Order (GraphQL)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/raw-graphql","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","raw-graphql"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Fetch order data from the Shopify GraphQL API (same query used for order sync). Orders that originated as drafts (source_name = shopify_draft_order) are completed orders and are read via the standard order query with the read_orders scope.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf Shopify can't return the order — older than 60 days without read_all_orders, or deleted — the response includes an `unavailable_reason` string and the order node is null.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/raw-graphql","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","raw-graphql"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order\": {\n      \"id\": \"gid://shopify/Order/5001234567890\",\n      \"name\": \"#1001\",\n      \"legacyResourceId\": \"5001234567890\"\n    }\n  },\n  \"extensions\": {},\n  \"errors\": null\n}"}]},{"name":"Get Order Line Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/line-items","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","line-items"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Lazy-load order line items with taxes, discounts, refunds, fulfillment info, and SKU product mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/line-items","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","line-items"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2001,\n      \"legacy_resource_id\": \"9876543210\",\n      \"name\": \"Classic Blue Shirt - Large\",\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"quantity\": 2,\n      \"price\": \"29.99\",\n      \"variant_id\": \"45678901234\",\n      \"taxes\": [],\n      \"discounts\": [],\n      \"refunds\": [],\n      \"fulfillment_lines\": [],\n      \"shopify_product_variant\": {\n        \"id\": 1042,\n        \"sku\": \"SHIRT-BLU-LG\",\n        \"product_listing\": {\n          \"product\": {\n            \"id\": 301,\n            \"sku\": \"SHIRT-BLU-LG\"\n          }\n        }\n      }\n    }\n  ]\n}"}]},{"name":"Get Order Shipping Lines","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/shipping-lines","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","shipping-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Lazy-load order shipping lines with taxes and discounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/shipping-lines","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","shipping-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3001,\n      \"title\": \"Standard Shipping\",\n      \"code\": \"STD\",\n      \"price\": \"9.99\",\n      \"taxes\": [],\n      \"discounts\": []\n    }\n  ]\n}"}]},{"name":"Get Order Refunds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/refunds","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","refunds"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Lazy-load order refunds with line items, shipping lines, and adjustments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/refunds","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","refunds"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": []\n}"}]},{"name":"Get Order Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/fulfillments","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Lazy-load order fulfillments with line items and Shopify location info.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/fulfillments","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"legacy_resource_id\": \"1234567890\",\n      \"name\": \"Fulfillment #1\",\n      \"service\": \"manual\",\n      \"status\": \"success\",\n      \"tracking_company\": \"UPS\",\n      \"tracking_numbers\": [\n        \"1Z999AA1234567890\"\n      ],\n      \"tracking_urls\": [\n        \"https://wwwapps.ups.com/...\"\n      ],\n      \"tracking_number\": \"1Z999AA1234567890\",\n      \"tracking_url\": \"https://wwwapps.ups.com/...\",\n      \"shopify_created_at\": \"2024-03-02T10:00:00+00:00\",\n      \"shopify_updated_at\": \"2024-03-02T10:00:00+00:00\",\n      \"location\": null,\n      \"line_items\": [],\n      \"total_quantity\": 2\n    }\n  ]\n}"}]},{"name":"Get Order Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/transactions","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Lazy-load order transactions with Shopify Payments fees.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/transactions","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4001,\n      \"gateway\": \"shopify_payments\",\n      \"amount\": \"89.97\",\n      \"currency\": \"USD\",\n      \"status\": \"success\",\n      \"kind\": \"sale\",\n      \"fees\": []\n    }\n  ]\n}"}]},{"name":"Get Note Attribute Names","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/note-attribute-names","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","note-attribute-names"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get unique note attribute names (keys) across all orders for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed to populate delivery date field selector.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/note-attribute-names","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","note-attribute-names"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"deliver_by\",\n    \"ship_by\",\n    \"requested_delivery_date\"\n  ]\n}"}]},{"name":"Get Metafield Keys","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/metafield-keys","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","metafield-keys"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get unique metafield keys across all orders for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/metafield-keys","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","metafield-keys"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"custom.delivery_date\",\n    \"custom.priority\"\n  ]\n}"}]},{"name":"Delivery Date Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/delivery-date-preview?deliver_by_date_fields=deliver_by,custom.delivery_date&ship_by_date_calculation_method=shipping_method&per_page=10&matched_only=false&search=","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","delivery-date-preview"],"query":[{"key":"deliver_by_date_fields","value":"deliver_by,custom.delivery_date","description":"Comma-separated note attribute or metafield keys to use for delivery date extraction","disabled":true},{"key":"ship_by_date_calculation_method","value":"shipping_method","description":"in: shipping_method, match_deliver_by_date, none","disabled":true},{"key":"per_page","value":"10","description":"Items per page (max 100)","disabled":true},{"key":"matched_only","value":"false","description":"If true, return only orders that have a matching delivery date field","disabled":true},{"key":"search","value":"","description":"Optional search string","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Preview how delivery date configuration rules would apply to existing orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- deliver_by_date_fields: required, comma-separated field names\n- ship_by_date_calculation_method: required, in: shipping_method, match_deliver_by_date, none\n- search: nullable, max:255\n- per_page: nullable, integer, min:1, max:100"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/delivery-date-preview?deliver_by_date_fields=deliver_by,custom.delivery_date&ship_by_date_calculation_method=shipping_method&per_page=10&matched_only=false&search=","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","delivery-date-preview"],"query":[{"key":"deliver_by_date_fields","value":"deliver_by,custom.delivery_date","description":"Comma-separated note attribute or metafield keys to use for delivery date extraction","disabled":true},{"key":"ship_by_date_calculation_method","value":"shipping_method","description":"in: shipping_method, match_deliver_by_date, none","disabled":true},{"key":"per_page","value":"10","description":"Items per page (max 100)","disabled":true},{"key":"matched_only","value":"false","description":"If true, return only orders that have a matching delivery date field","disabled":true},{"key":"search","value":"","description":"Optional search string","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"name\": \"#1001\",\n      \"deliver_by_date\": \"2024-04-01\",\n      \"ship_by_date\": \"2024-03-29\",\n      \"matched_field\": \"deliver_by\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 12\n}"}]},{"name":"Get Instance Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Paginated Spatie activity history for all Shopify orders belonging to this integration instance, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters:\n- filter[search] - partial match against causer (user) name, event name, or the properties JSON payload.\n\nPagination: standard Laravel paginator (page, per_page; default 15 per page).\n\nOrdering: fixed, newest activity first (id DESC). No sort parameter.\n\nThe order scoping is performed database-side via a subquery, so it is safe for instances with very large order counts."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 48291,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"ShopifyOrder\",\n      \"subject_id\": 10234,\n      \"properties\": {\n        \"attributes\": {\n          \"archived_at\": \"2026-06-01T14:22:09.000000Z\"\n        },\n        \"old\": {\n          \"archived_at\": null\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-01T14:22:09.000000Z\"\n    },\n    {\n      \"id\": 48275,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"ShopifyOrder\",\n      \"subject_id\": 10233,\n      \"properties\": {\n        \"attributes\": {\n          \"name\": \"#1052\",\n          \"financial_status\": \"paid\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-01T13:58:41.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://sku7.test/api/shopify/1/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 84,\n  \"last_page_url\": \"https://sku7.test/api/shopify/1/activity-log?page=84\",\n  \"links\": [],\n  \"next_page_url\": \"https://sku7.test/api/shopify/1/activity-log?page=2\",\n  \"path\": \"https://sku7.test/api/shopify/1/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 1257\n}"}]},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/activity-log?page=1&per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search actor name, event, or change details","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Returns a paginated activity log for a single synced Shopify order - sync events, status changes, and the user or system process that caused each one, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nfilter[search] matches the actor name, the event name, and the recorded change payload. Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/activity-log?page=1&per_page=15&filter[search]=updated","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"filter[search]","value":"updated","description":"Search actor name, event, or change details","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 4451,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"ShopifyOrder\",\n      \"subject_id\": 501,\n      \"properties\": {\n        \"attributes\": {\n          \"fulfillment_status\": \"fulfilled\"\n        },\n        \"old\": {\n          \"fulfillment_status\": \"partial\"\n        }\n      },\n      \"causer\": {\n        \"id\": 3,\n        \"name\": \"Jane Admin\"\n      },\n      \"created_at\": \"2025-05-22T08:30:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/orders/501/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/orders/501/activity-log?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/orders/501/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Refresh Orders (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Start a tracked order refresh from Shopify. Returns a tracked_job_log_id for progress polling.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires at least one Shopify location to be mapped to a warehouse (422 if not configured).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- days: nullable, integer, min:1, max:365\n- updated_at: nullable, date\n- created_at_min: nullable, date","body":{"mode":"raw","raw":"{\n  \"days\": 7,\n  \"updated_at\": null,\n  \"created_at_min\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4430\n  },\n  \"message\": \"Order refresh job has been queued\"\n}"}]},{"name":"Get Refresh Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4430","description":"The tracked job log ID."}]},"description":"Poll the progress of a tracked order refresh job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4430","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4430,\n    \"job_name\": \"Refresh Shopify Orders: My Store\",\n    \"status\": \"processing\",\n    \"progress_current\": 80,\n    \"progress_total\": 200,\n    \"started_at\": \"2024-03-20T14:00:00+00:00\",\n    \"completed_at\": null\n  }\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues a background download of orders from Shopify. The endpoint returns immediately; orders are refreshed asynchronously. For a refresh with progress polling, use Refresh Orders (Tracked) instead.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields (both optional - omit both to use the instance's incremental sync cursor):\n- days (integer): refresh orders updated within the last N days.\n- updated_at (datetime string): refresh orders updated since this timestamp.","body":{"mode":"raw","raw":"{\n  \"days\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, orders will be refreshed shortly.\"\n}"}]},{"name":"Refresh Single Order from Shopify","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Fetches one order live from the Shopify Admin API by its Shopify order ID, updates the local copy synchronously, and returns the refreshed order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- uniqueId (string, required): the Shopify order ID (numeric ID from Shopify, not the SKU.io row ID).\n\nReturns 404 when the order cannot be found in Shopify.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"6001098342\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"integration_instance_id\": 1,\n    \"legacy_resource_id\": \"6001098342\",\n    \"name\": \"#1001\",\n    \"email\": \"jane@example.com\",\n    \"currency\": \"USD\",\n    \"financial_status\": \"paid\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"total_price\": \"59.90\",\n    \"billing_name\": \"Jane Doe\",\n    \"shipping_name\": \"Jane Doe\",\n    \"shopify_admin_url\": \"https://admin.shopify.com/store/my-store/orders/6001098342\",\n    \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\",\n    \"shopify_updated_at\": \"2025-05-22T08:30:00+00:00\",\n    \"created_at\": \"2025-05-20T16:07:00+00:00\",\n    \"updated_at\": \"2025-06-30T11:00:00+00:00\"\n  }\n}"}]},{"name":"Create SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Creates SKU.io sales orders from synced Shopify orders that do not have one yet. A single order is created synchronously; multiple orders are processed asynchronously and the response includes a tracked_job_log_id for polling progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of the Shopify orders to convert. Required unless apply_to_all or create_all_orders is true.\n- apply_to_all / create_all_orders (boolean): convert every eligible order on the instance.\n- filters (object, optional): narrows the order set when converting all.\n\nOrders that are archived, already linked to a sales order, or (when location mapping is enabled) missing fulfillment order data are skipped automatically.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"1 SKU order created successfully\"\n}"}]},{"name":"Update SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Re-applies the latest synced Shopify order data to the linked SKU.io sales orders (statuses, line items, addresses). By default the work is queued in the background; set use_jobs to false to process synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- update_all_orders (boolean, required): update every linked order on the instance.\n- ids (array of integers): SKU.io row IDs of specific Shopify orders to update (used when update_all_orders is false).\n- use_jobs (boolean, default true): process asynchronously (true) or inline (false).","body":{"mode":"raw","raw":"{\n  \"update_all_orders\": false,\n  \"ids\": [\n    501,\n    502\n  ],\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sku.io sales orders successfully updated\"\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archive multiple Shopify orders. Supports filtering with apply_to_all.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- ids: required_without apply_to_all, array of integers\n- apply_to_all: boolean (use filters instead of ids)\n- filters: array","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unarchive multiple Shopify orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders unarchived successfully\",\n  \"unarchived_count\": 2\n}"}]},{"name":"Bulk Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Delete multiple Shopify orders. Single orders deleted synchronously; multiple dispatches a tracked job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete job started\",\n  \"tracked_job_log_id\": 4440,\n  \"total_orders\": 3\n}"}]},{"name":"Bulk Delete SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Bulk delete the linked SKU sales orders (keeps Shopify orders intact). Dispatches a tracked job for large batches.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- ids: required_without apply_to_all, array of integers\n- apply_to_all: boolean\n- filters: array\n- archive_shopify_orders: boolean (archive Shopify orders after deleting SKU orders)","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ],\n  \"archive_shopify_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete job started\",\n  \"tracked_job_log_id\": 4441,\n  \"total_orders\": 2\n}"}]},{"name":"Archive Single Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Archive a single Shopify order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Single Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Unarchive a single Shopify order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Delete SKU Order (Keep Shopify Order)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/sku-order?archive_shopify_order=false","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","sku-order"],"query":[{"key":"archive_shopify_order","value":"false","description":"If true, also archive the Shopify order after deleting the SKU order","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]},"description":"Delete the linked SKU sales order while keeping the Shopify order intact. Optionally archives the Shopify order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 404 if no SKU order is linked.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/orders/{order}/sku-order?archive_shopify_order=false","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","orders",":order","sku-order"],"query":[{"key":"archive_shopify_order","value":"false","description":"If true, also archive the Shopify order after deleting the SKU order","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"501","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully\",\n  \"archived_shopify_order\": false\n}"}]},{"name":"List Shopify Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List synced Shopify fulfillments for an integration instance (paginated).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"legacy_resource_id\": \"1234567890\",\n      \"name\": \"Fulfillment #1\",\n      \"service\": \"manual\",\n      \"status\": \"success\",\n      \"tracking_company\": \"UPS\",\n      \"tracking_numbers\": [\n        \"1Z999AA1234567890\"\n      ],\n      \"tracking_urls\": [\n        \"https://wwwapps.ups.com/...\"\n      ],\n      \"tracking_number\": \"1Z999AA1234567890\",\n      \"tracking_url\": \"https://wwwapps.ups.com/...\",\n      \"shopify_created_at\": \"2024-03-02T10:00:00+00:00\",\n      \"shopify_updated_at\": \"2024-03-02T10:00:00+00:00\",\n      \"location\": null,\n      \"line_items\": [],\n      \"total_quantity\": 2,\n      \"order\": {\n        \"id\": 501,\n        \"name\": \"#1001\",\n        \"legacy_resource_id\": \"5001234567890\",\n        \"sales_order\": {\n          \"id\": 7421,\n          \"sales_order_number\": \"SO-0042\",\n          \"route\": \"/orders/sales-orders/7421\"\n        }\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48\n}"}]},{"name":"List Pending Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/pending?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","pending"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List pending SKU sales order fulfillments waiting to sync to Shopify. Includes mismatch data (unlinked Shopify fulfillments).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/pending?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","pending"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8001,\n      \"fulfillment_number\": \"FF-001\",\n      \"fulfillment_type\": \"standard\",\n      \"status\": \"ready\",\n      \"tracking_number\": \"1Z999AA1234567890\",\n      \"cost\": \"9.99\",\n      \"fulfilled_at\": \"2024-03-20T08:00:00+00:00\",\n      \"created_at\": \"2024-03-20T07:00:00+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 601,\n        \"sales_order_number\": \"SO-2024-001\"\n      },\n      \"shopify_order\": {\n        \"id\": 501,\n        \"name\": \"#1001\",\n        \"legacy_resource_id\": \"5001234567890\"\n      },\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shopify_fulfillment_orders\": [],\n      \"has_mismatch\": false,\n      \"unlinked_shopify_fulfillments\": []\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 5\n}"}]},{"name":"Get Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get fulfillment page stats: pending sync count, mismatch count, and automatic sync schedule info.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_sync_count\": 5,\n    \"mismatch_count\": 2,\n    \"sync_schedule\": {\n      \"interval\": 10,\n      \"unit\": \"minutes\",\n      \"description\": \"Fulfillments are automatically synced every 10 minutes\"\n    }\n  }\n}"}]},{"name":"Submit Single Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8001","description":"The sales order fulfillment ID."}]},"description":"Submit a single SKU sales order fulfillment to Shopify.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIn non-production environments, submission is skipped unless force_submit=true.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- force_submit: boolean (bypass non-production check)","body":{"mode":"raw","raw":"{\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8001","description":"The sales order fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"The fulfillment submitted successfully\"\n}"}]},{"name":"Submit Bulk Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Submit multiple selected SKU fulfillments to Shopify.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- ids: required, array of sales_order_fulfillments IDs\n- force_submit: boolean","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    8001,\n    8002,\n    8003\n  ],\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 3,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"3 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"Submit All Pending Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Submit all pending SKU fulfillments to Shopify in one operation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 5,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"5 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"Submit Fulfillment to Shopify","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Pushes a SKU.io sales order fulfillment (tracking number, carrier, fulfilled items) to Shopify, marking the corresponding Shopify order as fulfilled. The fulfillment is identified in the request body rather than the URL.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- sales_order_fulfillment_id (integer, required): the SKU.io fulfillment to submit; must exist.","body":{"mode":"raw","raw":"{\n  \"sales_order_fulfillment_id\": 3301\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"List Fulfillment Mismatches","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/mismatches?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","mismatches"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List SKU fulfillments that have mismatches — not synced to Shopify but the order has unlinked Shopify fulfillments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/mismatches?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments","mismatches"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8002,\n      \"fulfillment_number\": \"FF-002\",\n      \"tracking_number\": \"1Z999AA1234567891\",\n      \"cost\": \"9.99\",\n      \"status\": \"ready\",\n      \"fulfilled_at\": \"2024-03-18T08:00:00+00:00\",\n      \"carrier\": \"FedEx\",\n      \"warehouse\": {\n        \"id\": 1,\n        \"name\": \"Main Warehouse\"\n      },\n      \"sales_order\": {\n        \"id\": 601,\n        \"sales_order_number\": \"SO-2024-001\"\n      },\n      \"shopify_order\": {\n        \"id\": 501,\n        \"name\": \"#1001\"\n      },\n      \"unlinked_shopify_fulfillments\": [\n        {\n          \"id\": 5002,\n          \"name\": \"Fulfillment #2\",\n          \"tracking_numbers\": [\n            \"1Z999AA1234567891\"\n          ],\n          \"tracking_company\": \"FedEx\",\n          \"status\": \"success\",\n          \"shopify_created_at\": \"2024-03-18T09:00:00+00:00\",\n          \"tracking_matches\": true\n        }\n      ],\n      \"created_at\": \"2024-03-18T07:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2\n}"}]},{"name":"Link Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/link/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","link",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]},"description":"Link a SKU fulfillment to an existing Shopify fulfillment to resolve a mismatch. Use force_link=true if tracking numbers differ.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"force_link\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/link/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","link",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Fulfillments linked successfully\"\n}"}]},{"name":"Update Shopify Fulfillment from SKU","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/update-shopify/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","update-shopify",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]},"description":"Update Shopify fulfillment tracking info from the SKU fulfillment and link them.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/update-shopify/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","update-shopify",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Shopify fulfillment updated and linked successfully\"\n}"}]},{"name":"Delete SKU Create from Shopify","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/create-from-shopify/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","create-from-shopify",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]},"description":"Delete the SKU fulfillment and create a new one from the Shopify fulfillment data. Resolves mismatches where Shopify is the source of truth.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{salesOrderFulfillment}/create-from-shopify/{shopifyFulfillment}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":salesOrderFulfillment","create-from-shopify",":shopifyFulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"salesOrderFulfillment","value":"8002","description":"The sales order fulfillment ID."},{"key":"shopifyFulfillment","value":"5002","description":"The shopify fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"SKU fulfillment replaced with Shopify fulfillment data\"\n}"}]},{"name":"Get Fulfillment Detailed","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{fulfillment}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":fulfillment","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fulfillment","value":"5001","description":"The fulfillment ID."}]},"description":"Get a single Shopify fulfillment with all relationships eager-loaded (order, location, line items + their order line item, and the related fulfillment orders with their location and line items). The SKU-internal sales order fulfillment this Shopify fulfillment is linked to (`sales_order_fulfillment`), including that fulfillment's internal fulfillment order, is included when present.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the fulfillment does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillments/{fulfillment}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillments",":fulfillment","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fulfillment","value":"5001","description":"The fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5001,\n    \"legacy_resource_id\": \"1234567890\",\n    \"name\": \"Fulfillment #1\",\n    \"service\": \"manual\",\n    \"status\": \"success\",\n    \"tracking_company\": \"UPS\",\n    \"tracking_numbers\": [\n      \"1Z999AA1234567890\"\n    ],\n    \"tracking_urls\": [\n      \"https://wwwapps.ups.com/tracking/1Z999AA1234567890\"\n    ],\n    \"tracking_number\": \"1Z999AA1234567890\",\n    \"tracking_url\": \"https://wwwapps.ups.com/tracking/1Z999AA1234567890\",\n    \"shopify_created_at\": \"2024-03-02T10:05:00+00:00\",\n    \"shopify_updated_at\": \"2024-03-02T10:05:00+00:00\",\n    \"location\": {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"address1\": \"123 Commerce St\",\n      \"city\": \"Austin\",\n      \"province\": \"Texas\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"line_items\": [\n      {\n        \"id\": 61001,\n        \"legacy_resource_id\": \"222333444\",\n        \"quantity\": 2,\n        \"order_line_item\": {\n          \"id\": 71001,\n          \"legacy_resource_id\": \"5550001111\",\n          \"variant_id\": \"40123456789\",\n          \"name\": \"Premium Caviar 50g\",\n          \"sku\": \"CAV-50G\",\n          \"quantity\": 2\n        }\n      }\n    ],\n    \"total_quantity\": 2,\n    \"order\": {\n      \"id\": 501,\n      \"name\": \"#1001\",\n      \"legacy_resource_id\": \"5001234567890\",\n      \"sales_order\": {\n        \"id\": 7421,\n        \"sales_order_number\": \"SO-0042\",\n        \"route\": \"/orders/sales-orders/7421\"\n      }\n    },\n    \"fulfillment_orders\": [\n      {\n        \"id\": 8001,\n        \"legacy_resource_id\": \"9876543210\",\n        \"status\": \"closed\",\n        \"shopify_created_at\": \"2024-03-02T10:00:00+00:00\",\n        \"shopify_updated_at\": \"2024-03-02T10:06:00+00:00\",\n        \"location\": {\n          \"id\": 12,\n          \"name\": \"Main Warehouse\",\n          \"address1\": \"123 Commerce St\",\n          \"city\": \"Austin\",\n          \"province\": \"Texas\",\n          \"country\": \"United States\",\n          \"country_code\": \"US\"\n        },\n        \"line_items\": [\n          {\n            \"id\": 41001,\n            \"legacy_resource_id\": \"111222333\",\n            \"total_quantity\": 2,\n            \"remaining_quantity\": 0,\n            \"order_line_item\": {\n              \"id\": 71001,\n              \"legacy_resource_id\": \"5550001111\",\n              \"variant_id\": \"40123456789\",\n              \"name\": \"Premium Caviar 50g\",\n              \"sku\": \"CAV-50G\",\n              \"quantity\": 2\n            }\n          }\n        ],\n        \"total_quantity\": 2\n      }\n    ],\n    \"sales_order_fulfillment\": {\n      \"id\": 19112,\n      \"fulfillment_number\": \"F-1001-1\",\n      \"status\": \"fulfilled\",\n      \"route\": \"/orders/sales-orders/fulfillments/19112\",\n      \"fulfillment_order\": {\n        \"id\": 14098,\n        \"reference\": \"SO-1001.1\",\n        \"status\": \"open\",\n        \"request_status\": \"submitted\",\n        \"route\": \"/orders/fulfillment-orders/14098\"\n      }\n    }\n  }\n}"}]},{"name":"List Fulfillment Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillment-orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillment-orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List synced Shopify fulfillment orders for an integration instance (paginated, default 10 per page).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFilters (Spatie QueryBuilder):\n- filter[search] — free-text across legacy_resource_id, status, order name, location name\n- filter[status] — text operators on the fulfillment order status (e.g. open, in_progress, scheduled, cancelled, on_hold, incomplete, closed)\n- filter[id] — numeric operators on the primary key\n- filter[total_quantity] — numeric operators on the summed line-item total_quantity\n- filter[order_name] — text operators on the related Shopify order name\n- filter[location_name] — text operators on the related location name\n- filter[order_id] — exact match on shopify_order_id\n- filter[shopify_created_at] / filter[shopify_updated_at] — datetime operators\n\nSort (sort=): id, status, shopify_created_at, shopify_updated_at (prefix with - for descending). Default: -id.\n\nPagination: page, per_page.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillment-orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillment-orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 8001,\n      \"legacy_resource_id\": \"9876543210\",\n      \"status\": \"open\",\n      \"shopify_created_at\": \"2024-03-02T10:00:00+00:00\",\n      \"shopify_updated_at\": \"2024-03-02T10:00:00+00:00\",\n      \"location\": {\n        \"id\": 12,\n        \"name\": \"Main Warehouse\",\n        \"address1\": \"123 Commerce St\",\n        \"city\": \"Austin\",\n        \"province\": \"Texas\",\n        \"country\": \"United States\",\n        \"country_code\": \"US\"\n      },\n      \"line_items\": [\n        {\n          \"id\": 41001,\n          \"legacy_resource_id\": \"111222333\",\n          \"total_quantity\": 2,\n          \"remaining_quantity\": 0,\n          \"order_line_item\": null\n        }\n      ],\n      \"total_quantity\": 2,\n      \"order\": {\n        \"id\": 501,\n        \"name\": \"#1001\",\n        \"legacy_resource_id\": \"5001234567890\",\n        \"sales_order\": {\n          \"id\": 7421,\n          \"sales_order_number\": \"SO-0042\",\n          \"route\": \"/orders/sales-orders/7421\"\n        }\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 7,\n  \"per_page\": 10,\n  \"total\": 65\n}"}]},{"name":"Get Fulfillment Order Detailed","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillment-orders/{fulfillmentOrder}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillment-orders",":fulfillmentOrder","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fulfillmentOrder","value":"8001","description":"The fulfillment order ID."}]},"description":"Get a single Shopify fulfillment order with all relationships eager-loaded (order, location, line items + their order line item, and the related fulfillments with their location and line items). Each related fulfillment includes its linked SKU-internal sales order fulfillment (`sales_order_fulfillment`) and that fulfillment's internal fulfillment order when present.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the fulfillment order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/fulfillment-orders/{fulfillmentOrder}/detailed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","fulfillment-orders",":fulfillmentOrder","detailed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"fulfillmentOrder","value":"8001","description":"The fulfillment order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8001,\n    \"legacy_resource_id\": \"9876543210\",\n    \"status\": \"open\",\n    \"shopify_created_at\": \"2024-03-02T10:00:00+00:00\",\n    \"shopify_updated_at\": \"2024-03-02T10:00:00+00:00\",\n    \"location\": {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"address1\": \"123 Commerce St\",\n      \"city\": \"Austin\",\n      \"province\": \"Texas\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\"\n    },\n    \"line_items\": [\n      {\n        \"id\": 41001,\n        \"legacy_resource_id\": \"111222333\",\n        \"total_quantity\": 2,\n        \"remaining_quantity\": 0,\n        \"order_line_item\": {\n          \"id\": 71001,\n          \"legacy_resource_id\": \"5550001111\",\n          \"variant_id\": \"40123456789\",\n          \"name\": \"Premium Caviar 50g\",\n          \"sku\": \"CAV-50G\",\n          \"quantity\": 2\n        }\n      }\n    ],\n    \"total_quantity\": 2,\n    \"order\": {\n      \"id\": 501,\n      \"name\": \"#1001\",\n      \"legacy_resource_id\": \"5001234567890\",\n      \"sales_order\": {\n        \"id\": 7421,\n        \"sales_order_number\": \"SO-0042\",\n        \"route\": \"/orders/sales-orders/7421\"\n      }\n    },\n    \"fulfillments\": [\n      {\n        \"id\": 5001,\n        \"legacy_resource_id\": \"1234567890\",\n        \"name\": \"Fulfillment #1\",\n        \"service\": \"manual\",\n        \"status\": \"success\",\n        \"tracking_company\": \"UPS\",\n        \"tracking_numbers\": [\n          \"1Z999AA1234567890\"\n        ],\n        \"tracking_urls\": [\n          \"https://wwwapps.ups.com/tracking/1Z999AA1234567890\"\n        ],\n        \"tracking_number\": \"1Z999AA1234567890\",\n        \"tracking_url\": \"https://wwwapps.ups.com/tracking/1Z999AA1234567890\",\n        \"shopify_created_at\": \"2024-03-02T10:05:00+00:00\",\n        \"shopify_updated_at\": \"2024-03-02T10:05:00+00:00\",\n        \"location\": {\n          \"id\": 12,\n          \"name\": \"Main Warehouse\",\n          \"address1\": \"123 Commerce St\",\n          \"city\": \"Austin\",\n          \"province\": \"Texas\",\n          \"country\": \"United States\",\n          \"country_code\": \"US\"\n        },\n        \"line_items\": [\n          {\n            \"id\": 61001,\n            \"legacy_resource_id\": \"222333444\",\n            \"quantity\": 2,\n            \"order_line_item\": {\n              \"id\": 71001,\n              \"legacy_resource_id\": \"5550001111\",\n              \"variant_id\": \"40123456789\",\n              \"name\": \"Premium Caviar 50g\",\n              \"sku\": \"CAV-50G\",\n              \"quantity\": 2\n            }\n          }\n        ],\n        \"total_quantity\": 2,\n        \"sales_order_fulfillment\": {\n          \"id\": 19112,\n          \"fulfillment_number\": \"F-1001-1\",\n          \"status\": \"fulfilled\",\n          \"route\": \"/orders/sales-orders/fulfillments/19112\",\n          \"fulfillment_order\": {\n            \"id\": 14098,\n            \"reference\": \"SO-1001.1\",\n            \"status\": \"open\",\n            \"request_status\": \"submitted\",\n            \"route\": \"/orders/fulfillment-orders/14098\"\n          }\n        }\n      }\n    ]\n  }\n}"}]},{"name":"List Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get paginated inventory comparison data showing SKU.io quantities vs Shopify quantities per product/location.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 701,\n      \"product_listing_id\": 201,\n      \"document_id\": 1042,\n      \"listing_sku\": \"SHIRT-BLU-LG\",\n      \"title\": \"Classic Blue Shirt - Large\",\n      \"product\": {\n        \"id\": 301,\n        \"sku\": \"SHIRT-BLU-LG\",\n        \"name\": \"Classic Blue Shirt - Large\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"12345678\",\n      \"location_name\": \"Main Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 50,\n      \"sales_channel_quantity\": 50,\n      \"variance\": 0,\n      \"status\": \"synced\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2024-03-20T12:00:00+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2024-03-20T11:55:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2024-03-20T11:55:00+00:00\",\n      \"created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"updated_at\": \"2024-03-20T12:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 120\n}"}]},{"name":"Get Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get inventory summary statistics: synced count, variance count, needs recalculation count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 120,\n    \"synced\": 100,\n    \"variance\": 15,\n    \"needs_recalculation\": 5\n  }\n}"}]},{"name":"Get Inventory Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get available Shopify locations for inventory filtering.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Main Warehouse\",\n      \"legacy_resource_id\": \"12345678\",\n      \"is_active\": true\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Secondary Location\",\n      \"legacy_resource_id\": \"23456789\",\n      \"is_active\": true\n    }\n  ]\n}"}]},{"name":"Trigger Inventory Recache","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Trigger a job to recache SKU.io inventory quantities. Returns tracked_job_log_id for progress polling.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 4450\n  }\n}"}]},{"name":"Get Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4450","description":"The tracked job log ID."}]},"description":"Poll progress of an inventory recache job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4450","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4450,\n    \"status\": \"completed\",\n    \"progress_current\": 120,\n    \"progress_total\": 120\n  }\n}"}]},{"name":"Trigger Inventory Sync","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Trigger a job to sync SKU.io inventory quantities to Shopify. Returns tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 4451\n  }\n}"}]},{"name":"Get Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4451","description":"The tracked job log ID."}]},"description":"Poll progress of an inventory sync job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4451","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4451,\n    \"status\": \"processing\",\n    \"progress_current\": 60,\n    \"progress_total\": 120\n  }\n}"}]},{"name":"Fetch Live Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Trigger a job to fetch live inventory quantities directly from Shopify. Returns tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetch live inventory job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 4452\n  }\n}"}]},{"name":"Get Fetch Live Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4452","description":"The tracked job log ID."}]},"description":"Poll progress of a fetch-live-inventory job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4452","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4452,\n    \"status\": \"completed\",\n    \"progress_current\": 120,\n    \"progress_total\": 120\n  }\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List webhook events for an integration instance with pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"topic\": \"orders/create\",\n      \"unique_id\": \"shopify-webhook-abc123\",\n      \"processing_status\": \"processed\",\n      \"processing_attempts\": 1,\n      \"last_processing_attempt_at\": \"2024-03-20T10:00:00+00:00\",\n      \"processing_error\": null,\n      \"payload_date\": \"2024-03-20T09:59:00+00:00\",\n      \"created_at\": \"2024-03-20T09:59:30+00:00\",\n      \"processed_at\": \"2024-03-20T10:00:00+00:00\",\n      \"processing_completed_at\": \"2024-03-20T10:00:02+00:00\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"My Shopify Store\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 250\n}"}]},{"name":"Get Webhook Event Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]},"description":"Get full details of a specific webhook event including the raw payload JSON.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 9001,\n    \"integration_instance_id\": 1,\n    \"topic\": \"orders/create\",\n    \"unique_id\": \"shopify-webhook-abc123\",\n    \"processing_status\": \"processed\",\n    \"processing_attempts\": 1,\n    \"last_processing_attempt_at\": \"2024-03-20T10:00:00+00:00\",\n    \"processing_started_at\": \"2024-03-20T09:59:55+00:00\",\n    \"processing_completed_at\": \"2024-03-20T10:00:02+00:00\",\n    \"processing_error\": null,\n    \"payload_date\": \"2024-03-20T09:59:00+00:00\",\n    \"created_at\": \"2024-03-20T09:59:30+00:00\",\n    \"processed_at\": \"2024-03-20T10:00:00+00:00\",\n    \"json_data\": {\n      \"id\": 5001234567890,\n      \"name\": \"#1001\"\n    }\n  }\n}"}]},{"name":"Get Processing Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get webhook event processing statistics: counts by status, failure rates, etc.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 5000,\n    \"pending\": 12,\n    \"processed\": 4950,\n    \"failed\": 38,\n    \"processing\": 0\n  },\n  \"integration_instance\": {\n    \"id\": 1,\n    \"name\": \"My Shopify Store\"\n  }\n}"}]},{"name":"Process Pending Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/process","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Manually trigger processing of pending webhook events for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- topic: nullable, string — in: full topic names (orders/create, products/update, etc.) or short prefixes (orders, products, inventory_items, order_transactions)\n- limit: nullable, integer, min:1, max:100","body":{"mode":"raw","raw":"{\n  \"topic\": \"orders\",\n  \"limit\": 50\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/process","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","process"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed\": 10,\n    \"failed\": 0,\n    \"skipped\": 2\n  },\n  \"message\": \"Processing completed successfully\"\n}"}]},{"name":"Retry Failed Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/retry-failed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","retry-failed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Retry failed webhook events for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- limit: nullable, integer, min:1, max:100","body":{"mode":"raw","raw":"{\n  \"limit\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/retry-failed","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","retry-failed"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed\": 5,\n    \"failed\": 2,\n    \"skipped\": 0\n  },\n  \"message\": \"Retry completed successfully\"\n}"}]},{"name":"Process Event by ID","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}/process","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId","process"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]},"description":"Process a specific pending webhook event by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}/process","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId","process"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"event_id\": 9001,\n    \"status\": \"processed\"\n  },\n  \"message\": \"Event processing completed successfully\"\n}"}]},{"name":"Reprocess Event by ID","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}/reprocess","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId","reprocess"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]},"description":"Reprocess a webhook event including already-processed events (force retry).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/{eventId}/reprocess","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events",":eventId","reprocess"],"variable":[{"key":"eventId","value":"9001","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"event_id\": 9001,\n    \"status\": \"processed\"\n  },\n  \"message\": \"Event reprocessing completed successfully\"\n}"}]},{"name":"Bulk Reprocess Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events","bulk-reprocess"]},"description":"Bulk reprocess multiple webhook events by IDs or by filter.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- event_ids: required_without apply_to_all, array of integers (must exist in shopify_webhook_events)\n- apply_to_all: nullable, boolean\n- filters: nullable, array\n- integration_instance_id: required_if apply_to_all=true, integer","body":{"mode":"raw","raw":"{\n  \"event_ids\": [\n    9001,\n    9002,\n    9003\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events","bulk-reprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed_count\": 3,\n    \"failed_count\": 0\n  },\n  \"message\": \"Bulk reprocessing completed successfully\"\n}"}]},{"name":"Bulk Delete Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events","bulk-delete"]},"description":"Bulk delete webhook events by IDs or by filter. Requires confirmation='YES' to proceed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- event_ids: required_without apply_to_all, array of integers\n- apply_to_all: nullable, boolean\n- filters: nullable, array\n- integration_instance_id: required_if apply_to_all=true\n- confirmation: required, must be 'YES'"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify","webhook-events","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"deleted_count\": 2\n  },\n  \"message\": \"2 webhook event(s) deleted successfully\"\n}"}]},{"name":"Delete All Events for Integration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/delete-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","delete-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Delete ALL webhook events for an integration instance. Requires confirmation='YES'.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- confirmation: required, must be 'YES'"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhook-events/delete-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhook-events","delete-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"deleted_count\": 5000\n  },\n  \"message\": \"5000 webhook event(s) deleted successfully\"\n}"}]},{"name":"List Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders?created_at_min=2023-10-01&created_at_max=2023-12-31&fulfillment_status=any","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2023-10-01","description":"Required. Earliest order creation date (must be before the inventory start date)","disabled":true},{"key":"created_at_max","value":"2023-12-31","description":"Latest order creation date (defaults to the day before the inventory start date)","disabled":true},{"key":"fulfillment_status","value":"any","description":"unfulfilled, partial, fulfilled, or any","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queries the Shopify Admin API live for orders created before the account's inventory start date and returns them with an eligibility assessment for historical import (eligible, already imported, or the reason they cannot be imported). Orders imported this way are flagged as pre-start-date imports and do not affect inventory.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNote: this performs live Shopify API requests and can be slow for wide date ranges.\n\nQuery parameters:\n- created_at_min (date, required): start of the window; must be before the inventory start date.\n- created_at_max (date, optional): end of the window; defaults to the day before the inventory start date; must be before the inventory start date and not before created_at_min.\n- fulfillment_status (string, optional): unfulfilled, partial, fulfilled, or any.\n\nReturns 422 if the inventory start date has not been set or the dates are out of range."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders?created_at_min=2023-10-01&created_at_max=2023-12-31&fulfillment_status=any","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2023-10-01","description":"Required. Earliest order creation date (must be before the inventory start date)","disabled":true},{"key":"created_at_max","value":"2023-12-31","description":"Latest order creation date (defaults to the day before the inventory start date)","disabled":true},{"key":"fulfillment_status","value":"any","description":"unfulfilled, partial, fulfilled, or any","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shopify_order_id\": 6000012345,\n      \"name\": \"#985\",\n      \"email\": \"sam@example.com\",\n      \"created_at\": \"2023-11-02T15:04:05Z\",\n      \"financial_status\": \"paid\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"total_price\": \"120.00\",\n      \"currency\": \"USD\",\n      \"eligible\": true,\n      \"already_imported\": false,\n      \"ineligible_reason\": null\n    }\n  ],\n  \"inventory_start_date\": \"2024-01-01\",\n  \"meta\": {\n    \"total_queried\": 40,\n    \"eligible_count\": 32,\n    \"already_imported_count\": 3\n  }\n}"}]},{"name":"Search Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=985","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. order_number, order_id, or email","disabled":true},{"key":"search_term","value":"985","description":"Required. Value to search for","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Searches the Shopify Admin API live for specific orders created before the inventory start date, by order number, Shopify order ID, or customer email. Returns the same shape and eligibility flags as List Pre-Start-Date Orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- search_by (string, required): order_number, order_id, or email.\n- search_term (string, required, max 255).\n\nReturns 422 if the inventory start date has not been set."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=985","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. order_number, order_id, or email","disabled":true},{"key":"search_term","value":"985","description":"Required. Value to search for","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shopify_order_id\": 6000012345,\n      \"name\": \"#985\",\n      \"email\": \"sam@example.com\",\n      \"created_at\": \"2023-11-02T15:04:05Z\",\n      \"financial_status\": \"paid\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"total_price\": \"120.00\",\n      \"currency\": \"USD\",\n      \"eligible\": true,\n      \"already_imported\": false,\n      \"ineligible_reason\": null\n    }\n  ],\n  \"inventory_start_date\": \"2024-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Imports selected pre-start-date orders from Shopify. Each order is fetched from Shopify individually, so the import runs asynchronously: this endpoint enqueues the work and immediately returns a tracked job id. Poll the tracked jobs API with that id to follow progress and read the final imported/skipped counts. Full order data is downloaded and stored flagged as a pre-start-date import so it stays out of inventory calculations. Orders that already exist locally are flagged instead of being re-imported.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- shopify_order_ids (array of integers, required, 1-10000): Shopify order IDs as returned by the list/search endpoints.\n\nReturns the tracked job id. Returns 422 when the inventory start date is not set or more than 10,000 orders are requested.","body":{"mode":"raw","raw":"{\n  \"shopify_order_ids\": [\n    6000012345,\n    6000012346\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Importing 2 pre-start-date orders.\"\n}"}]},{"name":"Search All Pre-Start-Date Orders (Async)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/search-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","search-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Start a background search for every order created before the inventory start date. Unlike the synchronous browse endpoint, this fetches ALL matching orders with no page cap and returns a tracked job id immediately. Poll the tracked jobs API with that id; when it completes, read the full result set from the results endpoint.\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- created_at_min (date, required): only orders created on or after this date are searched. Must be before the inventory start date.\n- created_at_max (date, optional): upper bound; defaults to the inventory start date.\n- fulfillment_status (string, optional): any | unfulfilled | partial | fulfilled. Defaults to any.","body":{"mode":"raw","raw":"{\n  \"created_at_min\": \"2024-10-01\",\n  \"created_at_max\": \"2024-12-31\",\n  \"fulfillment_status\": \"any\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/search-all","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","search-all"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Searching Shopify for pre-start-date orders.\"\n}"}]},{"name":"Get Pre-Start-Date Order Search Results","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/results/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","results",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4821","description":"The tracked job log ID."}]},"description":"Return the cached result set produced by a completed Search All job. By default the full set is returned in one response; pass page and per_page for server-side pagination. Results are cached for one hour after the search completes.\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- trackedJobLogId (integer): the tracked job id returned by Search All.\n\nQuery params:\n- eligible_only (0/1, optional): return only orders eligible for import.\n- page (integer, optional): page number; when omitted the full set is returned.\n- per_page (integer, optional, max 1000): items per page when page is set.\n\nReturns 404 when the cached results have expired."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/pre-start-date-orders/results/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","pre-start-date-orders","results",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4821","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shopify_order_id\": 6000012345,\n      \"name\": \"#1001\",\n      \"email\": \"customer@example.com\",\n      \"created_at\": \"2024-11-01T10:00:00Z\",\n      \"fulfillment_status\": \"UNFULFILLED\",\n      \"financial_status\": \"PAID\",\n      \"total_price\": \"99.99\",\n      \"currency\": \"USD\",\n      \"fulfillments\": [],\n      \"line_items\": [\n        {\n          \"title\": \"Widget\",\n          \"sku\": \"WID-1\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"49.99\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2025-01-01\",\n  \"meta\": {\n    \"total_queried\": 9197,\n    \"eligible_count\": 9176,\n    \"already_imported_count\": 21,\n    \"has_more\": false\n  }\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products?page=1&per_page=10&sort=-id&filter[search]=shirt&filter[mapped]=true&filter[archived]=false&filter[status]=active&filter[vendor]=Nike&filter[product_type]=apparel&filter[sku]=SKU-001&filter[barcode]=1234567890&filter[price.gte]=10&filter[date_from]=2024-01-01&filter[date_to]=2024-12-31&filter[mapping_status]=unmapped&filter[sku_status]=has_sku&filter[has_sku]=true&filter[vendor.contains]=sport&filter[sku_product.is]=ABC-001","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, sku, barcode, shopify_product_id, shopify_product_title, shopify_variant_title, shopify_variant_id, price, status, shopify_product_created_at, shopify_product_updated_at, shopify_variant_created_at, shopify_variant_updated_at","disabled":true},{"key":"filter[search]","value":"shirt","description":"Full-text search across sku, barcode, shopify_product_title, shopify_variant_title, shopify_variant_id, shopify_product_id, inventory_item_id","disabled":true},{"key":"filter[mapped]","value":"true","description":"Filter by mapping status: true = mapped, false = unmapped","disabled":true},{"key":"filter[archived]","value":"false","description":"Filter archived products: true = archived, false = active (default: false)","disabled":true},{"key":"filter[status]","value":"active","description":"Filter by Shopify product status: active, draft, archived, all","disabled":true},{"key":"filter[vendor]","value":"Nike","description":"Partial match filter on vendor","disabled":true},{"key":"filter[product_type]","value":"apparel","description":"Partial match filter on product_type","disabled":true},{"key":"filter[sku]","value":"SKU-001","description":"Partial match filter on SKU","disabled":true},{"key":"filter[barcode]","value":"1234567890","description":"Partial match filter on barcode","disabled":true},{"key":"filter[price.gte]","value":"10","description":"Numeric filter on price. Suffixes: .gte, .lte, .gt, .lt","disabled":true},{"key":"filter[date_from]","value":"2024-01-01","description":"Filter: shopify_variant_created_at >= this date","disabled":true},{"key":"filter[date_to]","value":"2024-12-31","description":"Filter: shopify_variant_created_at <= this date 23:59:59","disabled":true},{"key":"filter[mapping_status]","value":"unmapped","description":"Legacy: mapped or unmapped","disabled":true},{"key":"filter[sku_status]","value":"has_sku","description":"Legacy: has_sku or empty_sku","disabled":true},{"key":"filter[has_sku]","value":"true","description":"Filter products that have (true) or lack (false) a SKU value","disabled":true},{"key":"filter[vendor.contains]","value":"sport","description":"Advanced text filter on vendor. Operators: .is, .is_not, .contains, .does_not_contain, .starts_with, .ends_with, .is_empty, .is_not_empty, .is_one_of","disabled":true},{"key":"filter[sku_product.is]","value":"ABC-001","description":"Filter by linked SKU product SKU code","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List Shopify products for an integration instance with advanced filtering, sorting, and pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilter System: Uses Spatie QueryBuilder with both simple (filter[field]) and advanced (filter[field.operator]) forms.\n\nDefault: returns non-archived products sorted by -id.\n\nSort fields: id, sku, barcode, shopify_product_id, shopify_product_title, shopify_variant_title, shopify_variant_id, price, status, shopify_product_created_at, shopify_product_updated_at, shopify_variant_created_at, shopify_variant_updated_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products?page=1&per_page=10&sort=-id&filter[search]=shirt&filter[mapped]=true&filter[archived]=false&filter[status]=active&filter[vendor]=Nike&filter[product_type]=apparel&filter[sku]=SKU-001&filter[barcode]=1234567890&filter[price.gte]=10&filter[date_from]=2024-01-01&filter[date_to]=2024-12-31&filter[mapping_status]=unmapped&filter[sku_status]=has_sku&filter[has_sku]=true&filter[vendor.contains]=sport&filter[sku_product.is]=ABC-001","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with - for descending. Allowed: id, sku, barcode, shopify_product_id, shopify_product_title, shopify_variant_title, shopify_variant_id, price, status, shopify_product_created_at, shopify_product_updated_at, shopify_variant_created_at, shopify_variant_updated_at","disabled":true},{"key":"filter[search]","value":"shirt","description":"Full-text search across sku, barcode, shopify_product_title, shopify_variant_title, shopify_variant_id, shopify_product_id, inventory_item_id","disabled":true},{"key":"filter[mapped]","value":"true","description":"Filter by mapping status: true = mapped, false = unmapped","disabled":true},{"key":"filter[archived]","value":"false","description":"Filter archived products: true = archived, false = active (default: false)","disabled":true},{"key":"filter[status]","value":"active","description":"Filter by Shopify product status: active, draft, archived, all","disabled":true},{"key":"filter[vendor]","value":"Nike","description":"Partial match filter on vendor","disabled":true},{"key":"filter[product_type]","value":"apparel","description":"Partial match filter on product_type","disabled":true},{"key":"filter[sku]","value":"SKU-001","description":"Partial match filter on SKU","disabled":true},{"key":"filter[barcode]","value":"1234567890","description":"Partial match filter on barcode","disabled":true},{"key":"filter[price.gte]","value":"10","description":"Numeric filter on price. Suffixes: .gte, .lte, .gt, .lt","disabled":true},{"key":"filter[date_from]","value":"2024-01-01","description":"Filter: shopify_variant_created_at >= this date","disabled":true},{"key":"filter[date_to]","value":"2024-12-31","description":"Filter: shopify_variant_created_at <= this date 23:59:59","disabled":true},{"key":"filter[mapping_status]","value":"unmapped","description":"Legacy: mapped or unmapped","disabled":true},{"key":"filter[sku_status]","value":"has_sku","description":"Legacy: has_sku or empty_sku","disabled":true},{"key":"filter[has_sku]","value":"true","description":"Filter products that have (true) or lack (false) a SKU value","disabled":true},{"key":"filter[vendor.contains]","value":"sport","description":"Advanced text filter on vendor. Operators: .is, .is_not, .contains, .does_not_contain, .starts_with, .ends_with, .is_empty, .is_not_empty, .is_one_of","disabled":true},{"key":"filter[sku_product.is]","value":"ABC-001","description":"Filter by linked SKU product SKU code","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1042,\n      \"shopify_parent_product_id\": 8123456789,\n      \"shopify_variant_id\": 45678901234,\n      \"shopify_product_id\": 8123456789,\n      \"inventory_item_id\": 98765432,\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"shopify_product_title\": \"Classic Blue Shirt\",\n      \"shopify_variant_title\": \"Large\",\n      \"shopify_product_unified_title\": \"Classic Blue Shirt - Large\",\n      \"barcode\": 123456789012,\n      \"price\": \"29.99\",\n      \"status\": \"active\",\n      \"product_type\": \"Apparel\",\n      \"vendor\": \"Acme Clothing\",\n      \"image_url\": \"https://cdn.shopify.com/s/files/1/0001/product.jpg\",\n      \"weight\": 0.5,\n      \"weight_unit\": \"kg\",\n      \"unit_cost\": \"12.50\",\n      \"unit_cost_currency\": \"USD\",\n      \"shopify_product_created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"shopify_product_updated_at\": \"2024-03-20T14:30:00+00:00\",\n      \"shopify_variant_created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"shopify_variant_updated_at\": \"2024-03-20T14:30:00+00:00\",\n      \"shopify_inventory_item_created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"shopify_inventory_item_updated_at\": \"2024-03-20T14:30:00+00:00\",\n      \"archived_at\": null,\n      \"removed_from_shopify\": false,\n      \"sync_source\": \"webhook\",\n      \"last_sync_source\": \"webhook\",\n      \"created_at\": \"2024-01-15T10:00:00+00:00\",\n      \"updated_at\": \"2024-03-20T14:30:00+00:00\",\n      \"sku_product\": {\n        \"id\": 301,\n        \"sku\": \"SHIRT-BLU-LG\",\n        \"name\": \"Classic Blue Shirt - Large\",\n        \"barcode\": 123456789012,\n        \"price\": \"29.99\",\n        \"type\": \"product\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get aggregate stats about product sync status for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns total product count, mapped/unmapped counts, last sync timestamp, and latest product info.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Classic Blue Shirt - Large\",\n    \"latest_product_date\": \"2024-03-20T14:30:00.000000Z\",\n    \"total_products\": 1250,\n    \"mapped_products\": 1100,\n    \"unmapped_products\": 150,\n    \"last_synced_at\": \"2024-03-20 14:30:00\"\n  }\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"101","description":"The product ID."}]},"description":"Returns a synced Shopify product variant by its SKU.io row ID, including the mapped SKU.io product (if linked), the Shopify inventory item with per-location inventory levels, and SKU.io's cached quantities per Shopify location.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"101","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 1,\n    \"shopify_product_id\": \"8500001111\",\n    \"shopify_parent_product_id\": 55,\n    \"shopify_variant_id\": \"45123456789\",\n    \"inventory_item_id\": \"48111222333\",\n    \"sku\": \"TSHIRT-M-BLUE\",\n    \"shopify_product_title\": \"Blue T-Shirt\",\n    \"shopify_variant_title\": \"M\",\n    \"shopify_product_unified_title\": \"Blue T-Shirt - M\",\n    \"barcode\": 123456789012,\n    \"price\": \"24.95\",\n    \"status\": \"active\",\n    \"product_type\": \"Apparel\",\n    \"vendor\": \"Acme Apparel\",\n    \"image_url\": \"https://cdn.shopify.com/s/files/1/0001/products/blue-tshirt.jpg\",\n    \"weight\": 0.2,\n    \"weight_unit\": \"kg\",\n    \"unit_cost\": \"8.50\",\n    \"unit_cost_currency\": \"USD\",\n    \"product_listing_id\": 501,\n    \"mapped_sku\": \"TSHIRT-M-BLUE\",\n    \"mapped_at\": \"2025-04-01T10:00:00.000000Z\",\n    \"product\": {\n      \"id\": 301,\n      \"name\": \"Blue T-Shirt (M)\",\n      \"sku\": \"TSHIRT-M-BLUE\",\n      \"listing_id\": 501,\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      }\n    },\n    \"subscription_offering\": null,\n    \"inventory_item\": {\n      \"id\": 61,\n      \"inventory_item_id\": \"48111222333\",\n      \"weight_value\": 0.2,\n      \"weight_unit\": \"kg\",\n      \"unit_cost_amount\": \"8.50\",\n      \"unit_cost_currency_code\": \"USD\",\n      \"shopify_created_at\": \"2024-02-01T09:00:00+00:00\",\n      \"shopify_updated_at\": \"2025-06-01T10:00:00+00:00\",\n      \"inventory_levels\": [\n        {\n          \"id\": 71,\n          \"inventory_item_id\": \"48111222333\",\n          \"location_id\": \"74469278\",\n          \"location_name\": \"Main Warehouse\",\n          \"location_is_active\": true\n        }\n      ]\n    },\n    \"inventory_caches\": [\n      {\n        \"id\": 81,\n        \"sales_channel_location_id\": \"74469278\",\n        \"location_name\": \"Main Warehouse\",\n        \"location_is_active\": true,\n        \"sku_quantity\": 42,\n        \"is_sku_recalculation_needed\": false\n      }\n    ],\n    \"archived_at\": null,\n    \"removed_from_shopify\": false,\n    \"sync_source\": \"webhook\",\n    \"last_sync_source\": \"webhook\",\n    \"shopify_product_created_at\": \"2024-02-01T09:00:00+00:00\",\n    \"shopify_product_updated_at\": \"2025-06-01T10:00:00+00:00\",\n    \"created_at\": \"2024-02-01T09:05:00+00:00\",\n    \"updated_at\": \"2025-06-01T10:02:00+00:00\"\n  }\n}"}]},{"name":"Smart Match","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Find matching SKU products for a Shopify product using SKU, barcode, and fuzzy matching.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns exact_match (by SKU), barcode_match, and up to 5 similar_matches (fuzzy).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 301,\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"name\": \"Classic Blue Shirt - Large\",\n      \"barcode\": 123456789012,\n      \"price\": \"29.99\",\n      \"type\": \"product\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 305,\n        \"sku\": \"SHIRT-BLU-MD\",\n        \"name\": \"Classic Blue Shirt - Medium\",\n        \"barcode\": 123456789013,\n        \"price\": \"29.99\",\n        \"type\": \"product\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Map Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Map a Shopify product variant to a SKU product (or subscription offering).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf the product is already mapped, updates the existing mapping (remap). Dispatches a job to map any unresolved sales order lines matching this listing.\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- product_id: required_without subscription_offering_id, integer, must exist in products\n- subscription_offering_id: required_without product_id, integer, must exist in subscription_offerings","body":{"mode":"raw","raw":"{\n  \"product_id\": 301\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"sku\": \"SHIRT-BLU-LG\",\n    \"shopify_product_unified_title\": \"Classic Blue Shirt - Large\",\n    \"sku_product\": {\n      \"id\": 301,\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"name\": \"Classic Blue Shirt - Large\",\n      \"barcode\": 123456789012,\n      \"price\": \"29.99\",\n      \"type\": \"product\"\n    }\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Remove the mapping between a Shopify product and its SKU product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nDeletes the product listing record. Returns 422 if the product is not currently mapped.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"sku\": \"SHIRT-BLU-LG\",\n    \"sku_product\": null\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Create SKU Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Create a new SKU product from a Shopify product and map it. If a SKU product with the same SKU already exists, links to it instead.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the product is already mapped.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"sku\": \"SHIRT-BLU-LG\",\n    \"sku_product\": {\n      \"id\": 310,\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"name\": \"Classic Blue Shirt - Large\"\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Archive Single Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Archive a single Shopify product (sets archived_at timestamp).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"archived_at\": \"2024-03-20T14:30:00+00:00\"\n  },\n  \"message\": \"Product archived successfully.\"\n}"}]},{"name":"Unarchive Single Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Unarchive a single Shopify product (clears archived_at timestamp).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"archived_at\": null\n  },\n  \"message\": \"Product unarchived successfully.\"\n}"}]},{"name":"Get Raw Product from Shopify","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Fetch the raw Shopify REST API response for a product. Used for debugging and transparency.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe data is not persisted — it reflects the live Shopify state.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8123456789,\n    \"title\": \"Classic Blue Shirt\",\n    \"status\": \"active\",\n    \"vendor\": \"Acme Clothing\",\n    \"product_type\": \"Apparel\",\n    \"variants\": [\n      {\n        \"id\": 45678901234,\n        \"title\": \"Large\",\n        \"sku\": \"SHIRT-BLU-LG\",\n        \"price\": \"29.99\",\n        \"barcode\": 123456789012,\n        \"inventory_item_id\": 98765432\n      }\n    ]\n  }\n}"}]},{"name":"Get Raw Product (GraphQL)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/raw-graphql","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","raw-graphql"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Fetch product data from the Shopify GraphQL API (the same query used for product sync), including variants, inventory items and inventory levels. The data is not persisted — it reflects the live Shopify state.\n\nIf Shopify can't return the product — deleted, or the app is missing the required access scope — the response includes an `unavailable_reason` string and the product node is null.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/raw-graphql","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","raw-graphql"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"legacyResourceId\": \"8123456789\",\n      \"title\": \"Classic Blue Shirt\",\n      \"status\": \"ACTIVE\",\n      \"productType\": \"Apparel\",\n      \"vendor\": \"Acme Clothing\",\n      \"variants\": {\n        \"edges\": [\n          {\n            \"node\": {\n              \"legacyResourceId\": \"45678901234\",\n              \"title\": \"Large\",\n              \"sku\": \"SHIRT-BLU-LG\",\n              \"barcode\": 123456789012,\n              \"price\": \"29.99\",\n              \"image\": {\n                \"url\": \"https://cdn.shopify.com/s/files/1/products/blue-shirt-lg.jpg\"\n              }\n            }\n          }\n        ]\n      }\n    }\n  },\n  \"extensions\": {\n    \"cost\": {\n      \"requestedQueryCost\": 12,\n      \"actualQueryCost\": 8\n    }\n  },\n  \"errors\": null\n}"}]},{"name":"Get Orders for Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]},"description":"Get paginated Shopify orders that contain this product variant (matched by variant_id).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed for lazy loading order history in the product detail view.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1042","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"name\": \"#1001\",\n      \"financial_status\": \"paid\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"total_price\": \"89.97\",\n      \"currency\": \"USD\",\n      \"shopify_created_at\": \"2024-03-01T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 25,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Search Shopify Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/search-shopify","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","search-shopify"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Search for products directly in the Shopify store via GraphQL API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearch by SKU, title, or product_id. Returns results including whether each product already exists in the local database.\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- search_by: required, in: sku, title, product_id\n- query: required, string, max:255","body":{"mode":"raw","raw":"{\n  \"search_by\": \"sku\",\n  \"query\": \"SHIRT-BLU\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/search-shopify","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","search-shopify"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"legacy_resource_id\": \"45678901234\",\n      \"product_id\": \"8123456789\",\n      \"title\": \"Classic Blue Shirt - Large\",\n      \"sku\": \"SHIRT-BLU-LG\",\n      \"barcode\": 123456789012,\n      \"price\": \"29.99\",\n      \"status\": \"ACTIVE\",\n      \"product_type\": \"Apparel\",\n      \"vendor\": \"Acme Clothing\",\n      \"shopify_created_at\": \"2024-01-15T10:00:00Z\",\n      \"shopify_updated_at\": \"2024-03-20T14:30:00Z\",\n      \"exists_in_database\": true,\n      \"database_id\": 1042\n    }\n  ]\n}"}]},{"name":"Refresh Single Product from Shopify","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-product","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Fetch and sync a single Shopify product (all variants) from Shopify by its parent product ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe product_id is the Shopify parent product legacyResourceId. The optional variant_id narrows the returned result to a specific variant.\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- product_id: required, string (Shopify legacy resource ID)\n- variant_id: nullable, string (Shopify variant legacy resource ID)","body":{"mode":"raw","raw":"{\n  \"product_id\": \"8123456789\",\n  \"variant_id\": \"45678901234\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-product","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-product"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"sku\": \"SHIRT-BLU-LG\",\n    \"shopify_product_unified_title\": \"Classic Blue Shirt - Large\",\n    \"status\": \"active\",\n    \"price\": \"29.99\"\n  },\n  \"message\": \"Product synced successfully.\"\n}"}]},{"name":"Refresh Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Start a tracked product refresh job from Shopify. Returns a tracked_job_log_id to poll for progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- days: nullable, integer, min:1, max:365 — fetch products updated in last N days\n- updated_at: nullable, date — fetch products updated since this date","body":{"mode":"raw","raw":"{\n  \"days\": 7,\n  \"updated_at\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4421\n  },\n  \"message\": \"Product refresh job has been queued\"\n}"}]},{"name":"Get Refresh Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4421","description":"The tracked job log ID."}]},"description":"Poll the progress of a tracked product refresh job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4421","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4421,\n    \"job_name\": \"Refresh Shopify Products: My Store\",\n    \"status\": \"processing\",\n    \"progress_current\": 150,\n    \"progress_total\": 500,\n    \"started_at\": \"2024-03-20T14:00:00+00:00\",\n    \"completed_at\": null\n  }\n}"}]},{"name":"Refresh from Shopify (Enhanced)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Enhanced product refresh from Shopify with mode control. Dispatches a background job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- mode: sometimes, in: incremental, full, date_range\n- date_type: required_if mode=date_range, in: updated_at, created_at\n- date_from: required_if mode=date_range, date\n- date_to: required_if mode=date_range, date\n- include_archived: sometimes, boolean\n- product_ids: sometimes, array of Shopify product IDs","body":{"mode":"raw","raw":"{\n  \"mode\": \"incremental\",\n  \"date_type\": null,\n  \"date_from\": null,\n  \"date_to\": null,\n  \"include_archived\": false,\n  \"product_ids\": []\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh-sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh-sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product refresh initiated. Products will be synced shortly.\"\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues a background download of the product catalog from Shopify. The endpoint returns immediately with no payload; products are refreshed asynchronously. For a refresh with progress polling, use Refresh Products (Tracked) instead.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Sync Inventory to Shopify","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Pushes SKU.io inventory levels to Shopify for mapped products. With no body, all mapped listings on the instance are synced; pass ids to limit the push to specific products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers, optional): SKU.io row IDs of the Shopify products to sync.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"Bulk Operation","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Execute a bulk operation on Shopify products synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- action: required, in: map, unmap, create, remap, archive, unarchive, delete, refresh\n- selection.type: required, in: selected, visible, filtered\n- selection.ids: required_if type=selected, array of integers\n- selection.filters: sometimes, array of filter key-value pairs\n- options.match_by: sometimes, in: sku, barcode (for map/remap)\n- options.create_if_no_match: sometimes, boolean (for map action)\n- options.field_mappings: sometimes, array of {shopify_field, sku_field}","body":{"mode":"raw","raw":"{\n  \"action\": \"map\",\n  \"selection\": {\n    \"type\": \"selected\",\n    \"ids\": [\n      1042,\n      1043,\n      1044\n    ]\n  },\n  \"options\": {\n    \"match_by\": \"sku\",\n    \"create_if_no_match\": false\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processed\": 3,\n    \"failed\": 0,\n    \"skipped\": 0,\n    \"mapped_count\": 3\n  },\n  \"message\": \"Bulk map completed. Processed: 3, Failed: 0, Skipped: 0\"\n}"}]},{"name":"Bulk Operation (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Start a tracked bulk operation on Shopify products. Returns a tracked_job_log_id for progress polling.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSame validation as /products/bulk but dispatches a background job. Poll /products/bulk-progress/:id for status.\n\nAuthentication: Requires Bearer token.\n\nActions: map, unmap, create, remap, archive, unarchive, delete","body":{"mode":"raw","raw":"{\n  \"action\": \"create\",\n  \"selection\": {\n    \"type\": \"filtered\",\n    \"filters\": {\n      \"mapped\": false,\n      \"status\": \"active\"\n    }\n  },\n  \"options\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4425\n  },\n  \"message\": \"Bulk operation job has been queued\"\n}"}]},{"name":"Get Bulk Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4425","description":"The tracked job log ID."}]},"description":"Poll the progress of a tracked bulk product operation job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4425","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4425,\n    \"job_name\": \"Bulk Product Operation: My Store\",\n    \"status\": \"completed\",\n    \"progress_current\": 250,\n    \"progress_total\": 250,\n    \"started_at\": \"2024-03-20T14:00:00+00:00\",\n    \"completed_at\": \"2024-03-20T14:05:00+00:00\"\n  }\n}"}]},{"name":"Bulk Archive","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archive multiple Shopify products by their IDs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- ids: required, array, min:1\n- ids.*: integer","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1042,\n    1043,\n    1044\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"archived_count\": 3\n  },\n  \"message\": \"3 products archived successfully.\"\n}"}]},{"name":"Bulk Delete","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Delete multiple Shopify products from the local database (does not delete in Shopify).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- ids: required, array, min:1\n- ids.*: integer","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1042,\n    1043\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted_count\": 2\n  },\n  \"message\": \"2 products deleted successfully.\"\n}"}]},{"name":"Map Products to SKU Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Links Shopify product variants to SKU.io products in bulk by SKU. Each entry pairs a Shopify variant ID with a SKU.io product SKU; passing mapped_sku as null (or an empty string) unmaps the variant. Mappings are applied synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- mapping (array, required, min 1): objects with sales_channel_listing_id (string, required - the Shopify variant ID), mapped_sku (string or null - the SKU.io product SKU to link, null to unmap), product_listing_id (integer, optional - existing listing to update), and subscription_offering_id (integer, optional - map to a subscription offering instead of a product).","body":{"mode":"raw","raw":"{\n  \"mapping\": [\n    {\n      \"sales_channel_listing_id\": \"45123456789\",\n      \"mapped_sku\": \"TSHIRT-M-BLUE\"\n    },\n    {\n      \"sales_channel_listing_id\": \"45123456790\",\n      \"mapped_sku\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\"\n}"}]},{"name":"Create SKU Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues creation of SKU.io products from synced Shopify products, using the supplied field mappings to populate product fields. The endpoint returns immediately; products are created in the background.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- create_all_products (boolean, required): create from every eligible Shopify product on the instance.\n- ids (array of integers): SKU.io row IDs of specific Shopify products. Required when create_all_products is false and no filters are given.\n- mappings (array, optional): field mapping rows (listing_field, sku_field, parsers) to persist and use for this creation.\n- filters (string, optional): serialized filter set used to resolve the product IDs server-side.\n- initial_mapping (boolean, default false).\n\nReturns 400 when a selected Shopify product has no resolvable SKU.","body":{"mode":"raw","raw":"{\n  \"create_all_products\": false,\n  \"ids\": [\n    101,\n    102,\n    103\n  ],\n  \"mappings\": [\n    {\n      \"listing_field\": \"sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be created shortly.\"\n}"}]},{"name":"Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archives the given synced Shopify products in SKU.io (hides them from active listings; nothing is changed in Shopify). Use Check Archiveable Products first to see which products can be archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of Shopify products on this instance. Required unless mode is \"all\".\n- mode (string, optional): \"all\" targets every product on the instance and ignores ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Restores previously archived Shopify products in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of Shopify products on this instance. Required unless mode is \"all\".\n- mode (string, optional): \"all\" targets every product on the instance and ignores ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products unarchived successfully.\"\n}"}]},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Checks which of the given Shopify products can be archived. Products that appear on synced Shopify orders cannot be archived; the response lists each product with a boolean and the blocking reason (false when archiveable).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of Shopify products on this instance. Required unless mode is \"all\".\n- mode (string, optional): \"all\" targets every product on the instance and ignores ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"archiveable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 102,\n      \"archiveable\": false,\n      \"reason\": \"Sales Channel Product has Sales Channel Orders\"\n    }\n  ]\n}"}]},{"name":"Delete Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Deletes the local synced copies of the given Shopify products from SKU.io, including their product mappings/listings. The products are not deleted from Shopify - a later product refresh may re-import them if they still exist there.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of Shopify products on this instance. Required unless mode is \"all\".\n- mode (string, optional): \"all\" targets every product on the instance and ignores ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products deleted successfully.\"\n}"}]},{"name":"Check Deleteable Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Checks which of the given Shopify products can be deleted from SKU.io. The response lists each product with a boolean and the blocking reason (false when deleteable).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- ids (array of integers): SKU.io row IDs of Shopify products on this instance. Required unless mode is \"all\".\n- mode (string, optional): \"all\" targets every product on the instance and ignores ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"deleteable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 102,\n      \"deleteable\": true,\n      \"reason\": false\n    }\n  ]\n}"}]},{"name":"Download Bulk Mapping CSV Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/download","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","download"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Download a CSV template pre-filled with Shopify product data and current mappings. Users fill in the map_to_sku column and upload back.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse is a CSV file download (Content-Type: text/csv).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- scope: required, in: selected, unmapped, all\n- ids: required_if scope=selected, array of integers\n- filters: sometimes, array (supports mapping_status key)","body":{"mode":"raw","raw":"{\n  \"scope\": \"unmapped\",\n  \"ids\": [],\n  \"filters\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/download","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","download"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"shopify_product_id,shopify_sku,shopify_title,barcode,price,map_to_sku\n1042,SHIRT-BLU-LG,Classic Blue Shirt - Large,0123456789012,29.99,\n1043,SHIRT-RED-SM,Classic Red Shirt - Small,0123456789013,29.99,"}]},{"name":"Validate Bulk Mapping CSV","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/validate","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","validate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Validate an uploaded CSV mapping file. Returns validation results including valid mappings and invalid rows.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest: multipart/form-data\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- file: required, file, mimes: csv/txt, max: 10240 (10MB)\n\nCSV must have columns: shopify_product_id, map_to_sku","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/validate","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","validate"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"valid_count\": 45,\n    \"invalid_rows\": [\n      {\n        \"row_number\": 5,\n        \"shopify_product_id\": \"9999\",\n        \"map_to_sku\": \"NONEXISTENT\",\n        \"error\": \"No SKU product found with code: NONEXISTENT\"\n      }\n    ],\n    \"skipped_count\": 3,\n    \"mappings\": [\n      {\n        \"shopify_product_id\": 1042,\n        \"sku_product_id\": 301\n      }\n    ]\n  }\n}"}]},{"name":"Apply Bulk Mapping CSV","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/apply","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","apply"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Apply validated CSV mappings — creates or updates product listings for each mapping pair.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nValidation:\n- mappings: required, array, min:1\n- mappings.*.shopify_product_id: required, integer\n- mappings.*.sku_product_id: required, integer, exists in products table","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"shopify_product_id\": 1042,\n      \"sku_product_id\": 301\n    },\n    {\n      \"shopify_product_id\": 1043,\n      \"sku_product_id\": 302\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/bulk-mapping-csv/apply","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","bulk-mapping-csv","apply"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_count\": 44,\n    \"failed_count\": 1\n  },\n  \"message\": \"Applied 44 mappings successfully.\"\n}"}]},{"name":"Import Product Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues a background import of product mappings from a previously uploaded CSV file (referenced by its stored name from the file upload step). Rows are keyed by the Shopify variant ID column and link each variant to a SKU.io product. The endpoint returns immediately.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- original_name (string, required): the original client-side file name.\n- stored_name (string, required): the server-side stored file name returned by the upload step.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"shopify-mappings.csv\",\n  \"stored_name\": \"d41d8cd98f00b204e9800998ecf8427e.csv\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, mappings will be imported shortly.\"\n}"}]},{"name":"Preview Revenue Conversion","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion/preview","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]},"description":"Preview the impact of retroactively converting this product's historical sales-order lines (scoped to **this Shopify integration instance**) into revenue financial lines. Read-only — nothing is changed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns counts, total revenue that would move, and warning counts for fulfilled and returned/credited lines.\n\n**Requires Bearer token.**\n\n**Errors:**\n- 403: product does not belong to the given integration instance"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion/preview","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders\": 12,\n    \"lines\": 15,\n    \"revenue_total\": 1124.5,\n    \"fulfilled_lines\": 9,\n    \"credited_lines\": 1,\n    \"blocked_returns\": 2,\n    \"is_noop\": false\n  }\n}"}]},{"name":"Get Affected Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion/affected-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion","affected-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]},"description":"Paginated list of sales orders that would be affected by a revenue-line conversion for this product (scoped to this Shopify integration instance). Powers the conversion wizard's impact step.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row links to the sales order detail page via `link_route`.\n\n**Requires Bearer token.**\n\n**Errors:**\n- 403: product does not belong to the given integration instance"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion/affected-orders","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion","affected-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"sales_order_number\": \"SO-10231\",\n      \"order_date\": \"2024-11-04T00:00:00.000000Z\",\n      \"converted_lines_count\": 1,\n      \"link_reference\": \"SO-10231\",\n      \"link_type_label\": \"Sales Order\",\n      \"link_route\": \"/orders/sales-orders/4821\"\n    },\n    {\n      \"id\": 4805,\n      \"sales_order_number\": \"SO-10219\",\n      \"order_date\": \"2024-11-02T00:00:00.000000Z\",\n      \"converted_lines_count\": 2,\n      \"link_reference\": \"SO-10219\",\n      \"link_type_label\": \"Sales Order\",\n      \"link_route\": \"/orders/sales-orders/4805\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 10,\n  \"total\": 12,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Convert Product Lines to Revenue","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]},"description":"Flag this product as a revenue line and retroactively convert its historical sales-order lines (scoped to this Shopify integration instance) into revenue financial lines via a tracked background job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job creates an equivalent revenue financial line for each affected sales-order line, deletes the line (reversing fulfillment/allocations/inventory/credits via the model cascade), then rebuilds the line + daily financial caches and the accounting batch summaries (and any linked QBO journals).\n\n**Request body:**\n- `financial_line_type_id` (integer, **required**) — must be a REVENUE-classified financial line type. The product's `default_financial_line_type_id` is set to this value.\n- `date_from` (date, optional, Y-m-d) — only convert orders on/after this date.\n- `date_to` (date, optional, Y-m-d) — only convert orders on/before this date.\n- `sales_order_ids` (int[], optional) — convert ONLY these sales orders (the 'pick specific orders' mode). Omit to convert all matching.\n- `confirm` (boolean, **required**) — must be `true`.\n\nReturns the `tracked_job_log_id` so progress can be followed via the tracked job log endpoints.\n\n**Requires Bearer token.**\n\n**Errors:**\n- 403: product does not belong to the given integration instance\n- 422: product is not mapped to a SKU product, or `financial_line_type_id` is not a revenue type, or `confirm` not accepted","body":{"mode":"raw","raw":"{\n  \"financial_line_type_id\": 7,\n  \"date_from\": \"2024-01-01\",\n  \"date_to\": \"2024-12-31\",\n  \"sales_order_ids\": [\n    4821,\n    4805\n  ],\n  \"confirm\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/products/{product}/revenue-conversion","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","products",":product","revenue-conversion"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"product","value":"1","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 3391\n  },\n  \"message\": \"Revenue line conversion started — track progress in the job tray.\"\n}"}]},{"name":"Sync Costs to Shopify","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Push each mapped listing's average cost to the Shopify variant's \"Cost per item\" field. Runs asynchronously; poll Get Cost Sync Progress with the returned tracked_job_log_id.\n\nCosts are pushed in the store's currency (converted from your base currency using your configured exchange rate). Products with no average cost are skipped, never zeroed. Bundles push the sum of component costs; a bundle is skipped when any component has no cost. Values already matching Shopify are skipped.\n\nRequires the \"Push costs\" sync capability to be enabled for the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Cost sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 9134\n  }\n}"}]},{"name":"Get Cost Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"9134","description":"The tracked job log ID."}]},"description":"Get the progress and results of a cost sync run. The results object reports pushed, skipped_unchanged, skipped_no_cost, skipped_bundle_component, skipped_currency, failed counts and an errors list.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"9134","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9134,\n    \"job_name\": \"Sync Costs to Shopify: My Store\",\n    \"status\": \"completed\",\n    \"progress_percentage\": 100,\n    \"messages\": \"Pushed 1204 costs to Shopify (310 unchanged, 12 without cost, 4 bundle-skipped, 0 currency-skipped, 2 failed)\",\n    \"results\": {\n      \"pushed\": 1204,\n      \"skipped_unchanged\": 310,\n      \"skipped_no_cost\": 12,\n      \"skipped_bundle_component\": 4,\n      \"skipped_currency\": 0,\n      \"failed\": 2,\n      \"has_failures\": true,\n      \"errors\": [\n        \"SHIRT-BLU-LG: Variant not found on Shopify\"\n      ],\n      \"completed_at\": \"2026-07-17T06:02:14+00:00\"\n    },\n    \"created_at\": \"2026-07-17T06:00:00+00:00\",\n    \"updated_at\": \"2026-07-17T06:02:14+00:00\"\n  }\n}"}]},{"name":"Get Last Cost Sync","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/last-sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","last-sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Get the most recent cost sync run for this instance (any status), or null when costs have never been synced. The response also includes a currency object (base_currency, store_currency, store_currency_rate, has_rate, differs) describing the base-vs-store currency conversion applied when pushing costs.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/costs/last-sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","costs","last-sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9134,\n    \"job_name\": \"Sync Costs to Shopify: My Store\",\n    \"status\": \"completed\",\n    \"progress_percentage\": 100,\n    \"messages\": \"Pushed 1204 costs to Shopify (310 unchanged, 12 without cost, 4 bundle-skipped, 0 currency-skipped, 2 failed)\",\n    \"results\": {\n      \"pushed\": 1204,\n      \"skipped_unchanged\": 310,\n      \"skipped_no_cost\": 12,\n      \"skipped_bundle_component\": 4,\n      \"skipped_currency\": 0,\n      \"failed\": 2,\n      \"has_failures\": true,\n      \"errors\": [\n        \"SHIRT-BLU-LG: Variant not found on Shopify\"\n      ],\n      \"completed_at\": \"2026-07-17T06:02:14+00:00\"\n    },\n    \"created_at\": \"2026-07-17T06:00:00+00:00\",\n    \"updated_at\": \"2026-07-17T06:02:14+00:00\"\n  },\n  \"currency\": {\n    \"base_currency\": \"USD\",\n    \"store_currency\": \"GBP\",\n    \"store_currency_rate\": 1.27,\n    \"has_rate\": true,\n    \"differs\": true\n  }\n}"}]},{"name":"List Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/customers?page=1&per_page=15&sort=-id&filter[search]=jane&filter[email.contains]=example.com","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","customers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, email, first_name, last_name, shopify_created_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"jane","description":"Search email, name, phone, and address fields","disabled":true},{"key":"filter[email.contains]","value":"example.com","description":"Example operator filter on email","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns a paginated list of Shopify customers synced for the integration instance, including their default address and total synced order count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: id, legacy_resource_id, email, first_name, last_name, phone, full_name, city, province, country_code, shopify_created_at, created_at, updated_at. filter[search] matches email, first name, last name, phone, and address city/province/country.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric/date). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, email, first_name, last_name, shopify_created_at, created_at, updated_at (prefix with - for descending; default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/customers?page=1&per_page=15&sort=-id&filter[search]=jane&filter[email.contains]=example.com","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","customers"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, email, first_name, last_name, shopify_created_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"jane","description":"Search email, name, phone, and address fields","disabled":true},{"key":"filter[email.contains]","value":"example.com","description":"Example operator filter on email","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 44,\n      \"legacy_resource_id\": \"7300112233\",\n      \"email\": \"jane@example.com\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"full_name\": \"Jane Doe\",\n      \"phone\": \"+1 415 555 0100\",\n      \"orders_count\": 6,\n      \"default_address\": {\n        \"id\": 91,\n        \"city\": \"San Francisco\",\n        \"province\": \"California\",\n        \"province_code\": \"CA\",\n        \"country\": \"United States\",\n        \"country_code\": \"US\",\n        \"zip\": \"94105\"\n      },\n      \"location\": \"San Francisco, CA, US\",\n      \"shopify_created_at\": \"2024-02-10T18:22:00+00:00\",\n      \"shopify_updated_at\": \"2025-06-01T07:15:00+00:00\",\n      \"created_at\": \"2024-02-10T18:25:00+00:00\",\n      \"updated_at\": \"2025-06-01T07:16:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/customers?page=1\",\n  \"from\": 1,\n  \"last_page\": 8,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/customers?page=8\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/customers?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/customers\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 112\n}"}]},{"name":"List Refunds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/refunds?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[order_name]=#1001","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","refunds"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, legacy_resource_id, note, shopify_created_at, shopify_processed_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search refund ID, order number, or note","disabled":true},{"key":"filter[order_name]","value":"#1001","description":"Filter by order number","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns a paginated list of Shopify refunds synced for the integration instance, with the parent order summary and refund line item totals (quantity, subtotal, tax, and total refunded including adjustments).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: id, legacy_resource_id, note, order_name, shopify_created_at, shopify_processed_at, created_at, updated_at. filter[search] matches the refund ID, order number, and note.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric/date). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, legacy_resource_id, note, shopify_created_at, shopify_processed_at, created_at, updated_at (default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/refunds?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[order_name]=#1001","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","refunds"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, legacy_resource_id, note, shopify_created_at, shopify_processed_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search refund ID, order number, or note","disabled":true},{"key":"filter[order_name]","value":"#1001","description":"Filter by order number","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 21,\n      \"legacy_resource_id\": \"902211334\",\n      \"note\": \"Damaged in transit\",\n      \"order\": {\n        \"id\": 501,\n        \"legacy_resource_id\": \"6001098342\",\n        \"name\": \"#1001\",\n        \"email\": \"jane@example.com\",\n        \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\"\n      },\n      \"line_items_count\": 1,\n      \"total_quantity_refunded\": 1,\n      \"total_subtotal\": 24.95,\n      \"total_tax\": 2.18,\n      \"total_refunded\": 27.13,\n      \"adjustments_count\": 0,\n      \"shopify_created_at\": \"2025-05-25T10:00:00+00:00\",\n      \"shopify_processed_at\": \"2025-05-25T10:00:05+00:00\",\n      \"created_at\": \"2025-05-25T10:02:00+00:00\",\n      \"updated_at\": \"2025-05-25T10:02:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/refunds?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/refunds?page=3\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/refunds?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/refunds\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 34\n}"}]},{"name":"List Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/returns?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[status]=OPEN","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","returns"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, name, status, shopify_created_at, shopify_updated_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search return number or order number","disabled":true},{"key":"filter[status]","value":"OPEN","description":"Filter by return status (e.g. OPEN, CLOSED)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns a paginated list of Shopify returns synced for the integration instance, with the parent order summary, return line item counts, and the linked SKU.io RMA when one has been created.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: id, name, status, order_name, shopify_created_at, shopify_updated_at, created_at, updated_at. filter[search] matches the return number and order number.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric/date). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, name, status, shopify_created_at, shopify_updated_at, created_at, updated_at (default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/returns?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[status]=OPEN","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","returns"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, name, status, shopify_created_at, shopify_updated_at, created_at, updated_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search return number or order number","disabled":true},{"key":"filter[status]","value":"OPEN","description":"Filter by return status (e.g. OPEN, CLOSED)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9,\n      \"legacy_resource_id\": \"4477001\",\n      \"name\": \"#1001-R1\",\n      \"status\": \"OPEN\",\n      \"order\": {\n        \"id\": 501,\n        \"legacy_resource_id\": \"6001098342\",\n        \"name\": \"#1001\",\n        \"email\": \"jane@example.com\",\n        \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\"\n      },\n      \"line_items_count\": 1,\n      \"total_items_returned\": 1,\n      \"rma\": {\n        \"id\": 301,\n        \"rma_number\": \"RMA-301\",\n        \"status\": \"open\"\n      },\n      \"alert\": null,\n      \"shopify_created_at\": \"2025-05-28T09:00:00+00:00\",\n      \"shopify_updated_at\": \"2025-05-28T09:00:00+00:00\",\n      \"closed_at\": null,\n      \"created_at\": \"2025-05-28T09:02:00+00:00\",\n      \"updated_at\": \"2025-05-28T09:02:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/returns?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/returns?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/returns\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 12,\n  \"total\": 12\n}"}]},{"name":"List Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/transactions?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[kind]=sale&filter[status]=success","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","transactions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, amount, kind, status, formatted_gateway, currency, shopify_created_at, shopify_processed_at, created_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search order number or gateway","disabled":true},{"key":"filter[kind]","value":"sale","description":"Filter by transaction kind: authorization, capture, sale, void, refund","disabled":true},{"key":"filter[status]","value":"success","description":"Filter by status: pending, failure, success, error","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns a paginated list of Shopify payment transactions synced for the integration instance, with the parent order summary and aggregated processing fee totals (converted to the shop currency).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: kind (authorization, capture, sale, void, refund), status (pending, failure, success, error), formatted_gateway, currency, amount, shopify_created_at, created_at. filter[search] matches the order number and gateway.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric/date). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, amount, kind, status, formatted_gateway, currency, shopify_created_at, shopify_processed_at, created_at (default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/transactions?page=1&per_page=15&sort=-id&filter[search]=#1001&filter[kind]=sale&filter[status]=success","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","transactions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Allowed: id, amount, kind, status, formatted_gateway, currency, shopify_created_at, shopify_processed_at, created_at","disabled":true},{"key":"filter[search]","value":"#1001","description":"Search order number or gateway","disabled":true},{"key":"filter[kind]","value":"sale","description":"Filter by transaction kind: authorization, capture, sale, void, refund","disabled":true},{"key":"filter[status]","value":"success","description":"Filter by status: pending, failure, success, error","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 77,\n      \"legacy_resource_id\": \"5800223344\",\n      \"kind\": \"sale\",\n      \"status\": \"success\",\n      \"amount\": \"59.90\",\n      \"presentment_amount\": \"59.90\",\n      \"presentment_currency\": \"USD\",\n      \"has_currency_conversion\": false,\n      \"gateway\": \"shopify_payments\",\n      \"formatted_gateway\": \"Shopify Payments\",\n      \"currency\": \"USD\",\n      \"order\": {\n        \"id\": 501,\n        \"legacy_resource_id\": \"6001098342\",\n        \"name\": \"#1001\",\n        \"email\": \"jane@example.com\",\n        \"currency\": \"USD\",\n        \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\"\n      },\n      \"fees_count\": 1,\n      \"total_fees\": 2.04,\n      \"total_fee_tax\": 0,\n      \"shopify_created_at\": \"2025-05-20T16:05:10+00:00\",\n      \"shopify_processed_at\": \"2025-05-20T16:05:10+00:00\",\n      \"created_at\": \"2025-05-20T16:07:00+00:00\",\n      \"updated_at\": \"2025-05-20T16:07:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/transactions?page=1\",\n  \"from\": 1,\n  \"last_page\": 17,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/transactions?page=17\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/transactions?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/transactions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 250\n}"}]},{"name":"Get Transaction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/transactions/{transaction}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","transactions",":transaction"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"transaction","value":"77","description":"The transaction ID."}]},"description":"Returns full details of a single Shopify payment transaction: amounts in shop and presentment currency with the implied exchange rate, the raw gateway receipt, the parent order's financial summary with a Shopify admin link, and each processing fee with its rate breakdown.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 403 if the transaction does not belong to the given integration instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/transactions/{transaction}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","transactions",":transaction"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"transaction","value":"77","description":"The transaction ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 77,\n    \"legacy_resource_id\": \"5800223344\",\n    \"kind\": \"sale\",\n    \"status\": \"success\",\n    \"amount\": \"59.90\",\n    \"presentment_amount\": \"59.90\",\n    \"presentment_currency\": \"USD\",\n    \"implied_exchange_rate\": null,\n    \"has_currency_conversion\": false,\n    \"gateway\": \"shopify_payments\",\n    \"formatted_gateway\": \"Shopify Payments\",\n    \"receipt_json\": {\n      \"payment_id\": \"pi_3NxYz\",\n      \"risk_level\": \"normal\"\n    },\n    \"shopify_created_at\": \"2025-05-20T16:05:10+00:00\",\n    \"shopify_processed_at\": \"2025-05-20T16:05:10+00:00\",\n    \"created_at\": \"2025-05-20T16:07:00+00:00\",\n    \"updated_at\": \"2025-05-20T16:07:00+00:00\",\n    \"order\": {\n      \"id\": 501,\n      \"legacy_resource_id\": \"6001098342\",\n      \"name\": \"#1001\",\n      \"email\": \"jane@example.com\",\n      \"phone\": null,\n      \"currency\": \"USD\",\n      \"financial_status\": \"paid\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"total_price\": \"59.90\",\n      \"subtotal_price\": \"49.90\",\n      \"total_tax\": \"4.50\",\n      \"total_discounts\": \"0.00\",\n      \"total_shipping_price\": \"5.50\",\n      \"shopify_created_at\": \"2025-05-20T16:05:00+00:00\",\n      \"shopify_admin_url\": \"https://admin.shopify.com/store/my-store/orders/6001098342\"\n    },\n    \"currency\": \"USD\",\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"Main Shopify Store\",\n      \"myshopify_domain\": \"my-store.myshopify.com\"\n    },\n    \"fees\": [\n      {\n        \"id\": 5,\n        \"legacy_resource_id\": \"9911223\",\n        \"amount\": \"2.04\",\n        \"tax_amount\": \"0.00\",\n        \"flat_fee\": \"0.30\",\n        \"flat_fee_name\": \"USD Flat Fee\",\n        \"rate\": \"0.029\",\n        \"rate_name\": \"Card Rate\",\n        \"type\": \"payment\",\n        \"created_at\": \"2025-05-20T16:07:00+00:00\",\n        \"updated_at\": \"2025-05-20T16:07:00+00:00\"\n      }\n    ],\n    \"fees_count\": 1,\n    \"total_fees_presentment\": 2.04,\n    \"total_fees\": 2.04,\n    \"total_fee_tax\": 0\n  }\n}"}]},{"name":"List Available Mapping Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","shopify","mappings","available-fields"]},"description":"Returns the vocabulary of fields that can be used when configuring field mappings: every mappable Shopify product field and every mappable SKU.io product field, each with a label, data type, description, and group. Use these field names in the mappings you send to Update Field Mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThis endpoint is account-wide and does not require an integration instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","shopify","mappings","available-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shopify_fields\": {\n      \"shopify_product_id\": {\n        \"name\": \"shopify_product_id\",\n        \"label\": \"Shopify Product ID\",\n        \"type\": \"integer\",\n        \"description\": \"Unique Shopify product identifier\",\n        \"group\": \"Identifiers\"\n      },\n      \"shopify_variant_id\": {\n        \"name\": \"shopify_variant_id\",\n        \"label\": \"Shopify Variant ID\",\n        \"type\": \"integer\",\n        \"description\": \"Unique Shopify variant identifier\",\n        \"group\": \"Identifiers\"\n      },\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Variant SKU as entered in Shopify\",\n        \"group\": \"Product Details\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\",\n        \"description\": \"Variant barcode (UPC/EAN/ISBN)\",\n        \"group\": \"Product Details\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"decimal\",\n        \"description\": \"Variant price\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product SKU\",\n        \"group\": \"Product\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Name\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product name\",\n        \"group\": \"Product\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product barcode\",\n        \"group\": \"Product\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"decimal\",\n        \"description\": \"SKU.io default sell price\",\n        \"group\": \"Pricing\"\n      }\n    }\n  }\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns the field mapping configuration for an integration instance: the built-in default mappings, any custom overrides, and the effective mappings (defaults merged with overrides) that are actually applied when products are linked or created. Also includes the available field catalogs for building an editor.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Main Shopify Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"shopify_product_title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"barcode\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": []\n      }\n    ],\n    \"available_shopify_fields\": {\n      \"shopify_product_id\": {\n        \"name\": \"shopify_product_id\",\n        \"label\": \"Shopify Product ID\",\n        \"type\": \"integer\",\n        \"description\": \"Unique Shopify product identifier\",\n        \"group\": \"Identifiers\"\n      },\n      \"shopify_variant_id\": {\n        \"name\": \"shopify_variant_id\",\n        \"label\": \"Shopify Variant ID\",\n        \"type\": \"integer\",\n        \"description\": \"Unique Shopify variant identifier\",\n        \"group\": \"Identifiers\"\n      },\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Variant SKU as entered in Shopify\",\n        \"group\": \"Product Details\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\",\n        \"description\": \"Variant barcode (UPC/EAN/ISBN)\",\n        \"group\": \"Product Details\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"decimal\",\n        \"description\": \"Variant price\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product SKU\",\n        \"group\": \"Product\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Name\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product name\",\n        \"group\": \"Product\"\n      },\n      \"barcode\": {\n        \"name\": \"barcode\",\n        \"label\": \"Barcode\",\n        \"type\": \"string\",\n        \"description\": \"SKU.io product barcode\",\n        \"group\": \"Product\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"decimal\",\n        \"description\": \"SKU.io default sell price\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"shopify_product_title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"barcode\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"shopify_product_title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"barcode\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": []\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Replaces the custom field mappings for an integration instance. Each mapping pairs a Shopify field (listing_field) with a SKU.io field (sku_field) and an optional list of value parsers. Field names must come from List Available Mapping Fields.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- mappings (array, required): objects with listing_field (string, required), sku_field (string, required), and parsers (array, required - may be empty).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"shopify_product_title\",\n      \"sku_field\": \"name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"barcode\",\n      \"sku_field\": \"barcode\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Main Shopify Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"shopify_product_title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"barcode\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"shopify_product_title\",\n        \"sku_field\": \"name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"barcode\",\n        \"sku_field\": \"barcode\",\n        \"parsers\": []\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"Map Products to Existing SKUs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/map-to-existing-skus","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","map-to-existing-skus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues a background operation that links Shopify products to existing SKU.io products using the configured field mappings. No new products are created - only matches to products that already exist. The endpoint returns immediately with status \"queued\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody - exactly one selection strategy is required:\n- ids (array of integers, max 1000): specific Shopify product IDs (SKU.io row IDs).\n- process_all (boolean): process every eligible product on the instance.\n- filters (object): server-side selection, e.g. {\"unmapped_only\": true, \"created_after\": \"2024-01-01\"}.\n\nReturns 400 if no strategy is given, if more than 1000 ids are sent, or if no field mappings are configured yet.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/map-to-existing-skus","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","map-to-existing-skus"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"message\": \"Processing 3 specific products - check queue status for progress\",\n    \"status\": \"queued\",\n    \"selection_summary\": {\n      \"selection_type\": \"specific_products\",\n      \"product_count\": 3,\n      \"product_ids\": [\n        101,\n        102,\n        103\n      ]\n    }\n  }\n}"}]},{"name":"Create Products from Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/create-products-from-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","create-products-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queues a background operation that creates new SKU.io products from unmapped Shopify products, populating fields according to the configured field mappings. The endpoint returns immediately with status \"queued\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody - exactly one selection strategy is required:\n- ids (array of integers, max 1000): specific Shopify product IDs (SKU.io row IDs).\n- process_all (boolean): process every eligible product on the instance.\n- filters (object): server-side selection, e.g. {\"unmapped_only\": true, \"created_after\": \"2024-01-01\"}.\n\nReturns 400 if no strategy is given, if more than 1000 ids are sent, or if no field mappings are configured yet.","body":{"mode":"raw","raw":"{\n  \"filters\": {\n    \"unmapped_only\": true,\n    \"created_after\": \"2024-01-01\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/create-products-from-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","create-products-from-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"message\": \"Processing filtered products - check queue status for progress\",\n    \"status\": \"queued\",\n    \"selection_summary\": {\n      \"selection_type\": \"filtered_products\",\n      \"filters\": {\n        \"unmapped_only\": true,\n        \"created_after\": \"2024-01-01\"\n      }\n    }\n  }\n}"}]},{"name":"Download Product Mappings (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/product-mappings/csv/download","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","product-mappings","csv","download"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Downloads every product mapping for the instance as a CSV file for bulk editing. Columns: shopify_variant_id, shopify_product_title, shopify_variant_title, price, shopify_sku, mapped_sku. Edit the mapped_sku column and re-upload via Upload Product Mappings (CSV); clearing mapped_sku unmaps the product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe response is a text/csv file download, not JSON. Returns 404 when the instance has no product mappings."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/product-mappings/csv/download","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","product-mappings","csv","download"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"shopify_variant_id,shopify_product_title,shopify_variant_title,price,shopify_sku,mapped_sku\n45123456789,Blue T-Shirt,M,24.95,TSHIRT-M-BLUE,TSHIRT-M-BLUE\n45123456790,Blue T-Shirt,L,24.95,TSHIRT-L-BLUE,TSHIRT-L-BLUE\n"}]},{"name":"Upload Product Mappings (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/product-mappings/csv/upload","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","product-mappings","csv","upload"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Uploads a product mappings CSV (multipart/form-data) and applies it synchronously. Each row is keyed by shopify_variant_id (required). A non-empty mapped_sku links the Shopify product to that SKU.io product (creating or updating the listing); an empty mapped_sku removes the existing mapping. Optional listing_sku and price columns override the stored listing values.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nForm fields:\n- file (file, required): CSV file, max 2MB, .csv or .txt.\n\nAll rows are validated before anything is applied - if any row fails (unknown variant ID, unknown SKU), the whole upload is rejected with 422 and per-line errors.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/product-mappings/csv/upload","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","product-mappings","csv","upload"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Main Shopify Store\",\n    \"total_processed\": 25,\n    \"created_count\": 10,\n    \"updated_count\": 12,\n    \"deleted_count\": 3\n  },\n  \"message\": \"Product mappings processed successfully from CSV\"\n}"}]},{"name":"List Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns the shop's locations. Note: this performs a live request to the Shopify Admin API on every call (it is not served from the local database), so responses reflect Shopify's current state and count against Shopify API limits.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"locations\": [\n      {\n        \"id\": \"gid://shopify/Location/74469278\",\n        \"legacyResourceId\": \"74469278\",\n        \"name\": \"Main Warehouse\",\n        \"isActive\": true,\n        \"address\": {\n          \"address1\": \"500 Industrial Way\",\n          \"city\": \"Reno\",\n          \"provinceCode\": \"NV\",\n          \"countryCode\": \"US\",\n          \"zip\": \"89502\"\n        }\n      },\n      {\n        \"id\": \"gid://shopify/Location/74469279\",\n        \"legacyResourceId\": \"74469279\",\n        \"name\": \"Retail Store\",\n        \"isActive\": true,\n        \"address\": {\n          \"address1\": \"12 Market St\",\n          \"city\": \"San Francisco\",\n          \"provinceCode\": \"CA\",\n          \"countryCode\": \"US\",\n          \"zip\": \"94105\"\n        }\n      }\n    ],\n    \"success\": true\n  }\n}"}]},{"name":"Refresh Locations","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Fetches the shop's locations live from the Shopify Admin API and returns them. Use this to re-pull locations after adding or renaming one in Shopify before assigning warehouse mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/locations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"locations\": [\n      {\n        \"id\": \"gid://shopify/Location/74469278\",\n        \"legacyResourceId\": \"74469278\",\n        \"name\": \"Main Warehouse\",\n        \"isActive\": true,\n        \"address\": {\n          \"address1\": \"500 Industrial Way\",\n          \"city\": \"Reno\",\n          \"provinceCode\": \"NV\",\n          \"countryCode\": \"US\",\n          \"zip\": \"89502\"\n        }\n      },\n      {\n        \"id\": \"gid://shopify/Location/74469279\",\n        \"legacyResourceId\": \"74469279\",\n        \"name\": \"Retail Store\",\n        \"isActive\": true,\n        \"address\": {\n          \"address1\": \"12 Market St\",\n          \"city\": \"San Francisco\",\n          \"provinceCode\": \"CA\",\n          \"countryCode\": \"US\",\n          \"zip\": \"94105\"\n        }\n      }\n    ],\n    \"success\": true\n  }\n}"}]},{"name":"List Warehouse Location Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/warehouse-location-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","warehouse-location-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Lists every synced Shopify location with its current SKU.io warehouse mapping (warehouse_id is null for unmapped locations) plus full location address details. The meta block summarizes how many locations are mapped vs unmapped. These mappings drive fulfillment routing when use_location_mapping_for_new_orders is enabled on the integration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/warehouse-location-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","warehouse-location-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"shopify_location_id\": 74469278,\n      \"name\": \"Main Warehouse\",\n      \"is_active\": true,\n      \"warehouse_id\": 2,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"address1\": \"500 Industrial Way\",\n      \"address2\": null,\n      \"city\": \"Reno\",\n      \"province\": \"Nevada\",\n      \"province_code\": \"NV\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\",\n      \"zip\": \"89502\",\n      \"phone\": \"+1 775 555 0101\",\n      \"shopify_created_at\": \"2023-08-01T10:00:00+00:00\",\n      \"shopify_updated_at\": \"2025-05-01T09:30:00+00:00\"\n    },\n    {\n      \"shopify_location_id\": 74469279,\n      \"name\": \"Retail Store\",\n      \"is_active\": true,\n      \"warehouse_id\": null,\n      \"warehouse_name\": null,\n      \"address1\": \"12 Market St\",\n      \"address2\": null,\n      \"city\": \"San Francisco\",\n      \"province\": \"California\",\n      \"province_code\": \"CA\",\n      \"country\": \"United States\",\n      \"country_code\": \"US\",\n      \"zip\": \"94105\",\n      \"phone\": null,\n      \"shopify_created_at\": \"2023-09-14T15:20:00+00:00\",\n      \"shopify_updated_at\": \"2025-04-11T12:00:00+00:00\"\n    }\n  ],\n  \"meta\": {\n    \"total_locations\": 2,\n    \"mapped_count\": 1,\n    \"unmapped_count\": 1\n  }\n}"}]},{"name":"Bulk Update Warehouse Location Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/warehouse-location-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","warehouse-location-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Sets or clears the SKU.io warehouse assigned to one or more Shopify locations in a single call. Send warehouse_id as null to clear a mapping. Each mapping is applied independently - the response reports per-location success or failure plus an overall summary.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- mappings (array, required, min 1): objects with shopify_location_id (integer, required - the Shopify location's numeric ID) and warehouse_id (integer or null - must be an existing warehouse).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"shopify_location_id\": 74469278,\n      \"warehouse_id\": 2\n    },\n    {\n      \"shopify_location_id\": 74469279,\n      \"warehouse_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/warehouse-location-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","warehouse-location-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Updated 2 mapping(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"shopify_location_id\": 74469278,\n        \"location_name\": \"Main Warehouse\",\n        \"success\": true,\n        \"warehouse_id\": 2\n      },\n      {\n        \"shopify_location_id\": 74469279,\n        \"location_name\": \"Retail Store\",\n        \"success\": true,\n        \"warehouse_id\": null\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"successful\": 2,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings?shipping_method_field=title","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings"],"query":[{"key":"shipping_method_field","value":"title","description":"Optional override of the stored setting for previewing: title or code","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Lists the distinct shipping method values found on the instance's synced Shopify orders together with their current SKU.io shipping method mapping (unmapped entries have a null shipping_method_id). The response also includes all active SKU.io shipping methods for building a mapping editor, and a meta summary of mapped vs unmapped counts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nThe values are read from the field selected by the instance's shipping_method_field setting (title or code); pass the shipping_method_field query parameter to preview the list using the other field without saving the setting."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings?shipping_method_field=title","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings"],"query":[{"key":"shipping_method_field","value":"title","description":"Optional override of the stored setting for previewing: title or code","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 31,\n        \"sales_channel_method\": \"Express Shipping\",\n        \"shipping_method_id\": 7,\n        \"shipping_method_name\": \"UPS Next Day Air\"\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"Standard Shipping\",\n        \"shipping_method_id\": null,\n        \"shipping_method_name\": null\n      }\n    ],\n    \"available_shipping_methods\": [\n      {\n        \"id\": 7,\n        \"name\": \"Next Day Air\",\n        \"full_name\": \"UPS Next Day Air\"\n      },\n      {\n        \"id\": 8,\n        \"name\": \"Ground\",\n        \"full_name\": \"UPS Ground\"\n      }\n    ],\n    \"shipping_method_field\": \"title\"\n  },\n  \"meta\": {\n    \"sales_channel_id\": 12,\n    \"total_mappings\": 2,\n    \"mapped_count\": 1,\n    \"unmapped_count\": 1\n  }\n}"}]},{"name":"Bulk Update Shipping Method Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Creates, updates, or removes shipping method mappings in bulk. Providing shipping_method_id maps the Shopify shipping method value to that SKU.io shipping method (upsert); sending null removes any existing mapping for that value. Each entry is processed independently with per-entry results.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- mappings (array, required, min 1): objects with sales_channel_method (string, required - the shipping method value as it appears on Shopify orders), shipping_method_id (integer or null - must be an existing SKU.io shipping method), and id (integer, optional - existing mapping ID, informational).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_method\": \"Standard Shipping\",\n      \"shipping_method_id\": 8\n    },\n    {\n      \"sales_channel_method\": \"Economy\",\n      \"shipping_method_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Updated 2 mapping(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"id\": 32,\n        \"sales_channel_method\": \"Standard Shipping\",\n        \"success\": true,\n        \"shipping_method_id\": 8,\n        \"action\": \"mapped\"\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"Economy\",\n        \"success\": true,\n        \"shipping_method_id\": null,\n        \"action\": \"unmapped\"\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"successful\": 2,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"Delete Shipping Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings/{mappingId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings",":mappingId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"mappingId","value":"31","description":"The mapping ID."}]},"description":"Removes a shipping method mapping by its ID. Orders imported afterwards with that Shopify shipping method value fall back to the default shipping method behavior.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shipping-method-mappings/{mappingId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shipping-method-mappings",":mappingId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"mappingId","value":"31","description":"The mapping ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Shipping method mapping for 'Express Shipping' deleted successfully\"\n}"}]},{"name":"List Payment Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Lists the distinct payment gateways found on the instance's synced Shopify order transactions together with their current SKU.io payment type mapping (unmapped entries have a null payment_type_id). Also returns all active SKU.io payment types and a meta summary of mapped vs unmapped counts. These mappings control which payment type is assigned to payments imported from Shopify.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 11,\n        \"sales_channel_method\": \"shopify_payments\",\n        \"formatted_gateway\": \"Shopify Payments\",\n        \"payment_type_id\": 3,\n        \"payment_type_name\": \"Credit Card\"\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"paypal\",\n        \"formatted_gateway\": \"PayPal\",\n        \"payment_type_id\": null,\n        \"payment_type_name\": null\n      }\n    ],\n    \"available_payment_types\": [\n      {\n        \"id\": 3,\n        \"name\": \"Credit Card\"\n      },\n      {\n        \"id\": 4,\n        \"name\": \"PayPal\"\n      }\n    ]\n  },\n  \"meta\": {\n    \"sales_channel_id\": 12,\n    \"total_mappings\": 2,\n    \"mapped_count\": 1,\n    \"unmapped_count\": 1\n  }\n}"}]},{"name":"Bulk Update Payment Method Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Creates, updates, or removes payment method mappings in bulk. Providing payment_type_id maps the Shopify gateway to that SKU.io payment type (upsert); sending null removes any existing mapping for that gateway. Each entry is processed independently with per-entry results.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody fields:\n- mappings (array, required, min 1): objects with sales_channel_method (string, required - the gateway identifier from Shopify transactions, e.g. shopify_payments), payment_type_id (integer or null - must be an existing SKU.io payment type), and id (integer, optional - existing mapping ID, informational).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_method\": \"paypal\",\n      \"payment_type_id\": 4\n    },\n    {\n      \"sales_channel_method\": \"gift_card\",\n      \"payment_type_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings","bulk-update"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Updated 2 mapping(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"id\": 12,\n        \"sales_channel_method\": \"paypal\",\n        \"success\": true,\n        \"payment_type_id\": 4,\n        \"action\": \"mapped\"\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"gift_card\",\n        \"success\": true,\n        \"payment_type_id\": null,\n        \"action\": \"unmapped\"\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"successful\": 2,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"Delete Payment Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings/{mappingId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings",":mappingId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"mappingId","value":"11","description":"The mapping ID."}]},"description":"Removes a payment method mapping by its ID. Payments imported afterwards with that gateway fall back to the default payment type behavior.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payment-method-mappings/{mappingId}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payment-method-mappings",":mappingId"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"mappingId","value":"11","description":"The mapping ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Payment method mapping for 'shopify_payments' deleted successfully\"\n}"}]},{"name":"List Webhook Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Lists every webhook topic SKU.io can subscribe to on the connected shop, with its human-readable label and description, the callback URL SKU.io registers, whether the subscription is currently enabled, and the Shopify webhook ID when active.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"configurations\": [\n      {\n        \"topic\": \"orders/create\",\n        \"label\": \"Orders Create\",\n        \"description\": \"Fires when a new order is created in Shopify\",\n        \"callback_url\": \"https://acme.sku.io/api/shopify/webhook/orders-create/wt_9f8e7d6c\",\n        \"is_enabled\": true,\n        \"shopify_webhook_id\": \"988771122\",\n        \"created_at\": \"2025-05-01T12:00:00.000000Z\"\n      },\n      {\n        \"topic\": \"orders/updated\",\n        \"label\": \"Orders Updated\",\n        \"description\": \"Fires when an order is updated in Shopify\",\n        \"callback_url\": \"https://acme.sku.io/api/shopify/webhook/orders-updated/wt_9f8e7d6c\",\n        \"is_enabled\": false,\n        \"shopify_webhook_id\": null,\n        \"created_at\": null\n      }\n    ]\n  }\n}"}]},{"name":"Enable Webhook Topic","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations/{topic}/enable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations",":topic","enable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"topic","value":"orders---create","description":"Webhook topic with / encoded as ---"}]},"description":"Registers a webhook subscription for the given topic on the connected shop (live call to the Shopify Admin API). If the subscription already exists the call succeeds without creating a duplicate.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath parameter: topic uses triple dashes in place of slashes, e.g. orders---create for the orders/create topic."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations/{topic}/enable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations",":topic","enable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"topic","value":"orders---create","description":"Webhook topic with / encoded as ---"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook enabled successfully\",\n    \"webhook\": {\n      \"id\": 15,\n      \"topic\": \"orders/create\",\n      \"shopify_webhook_id\": \"988771122\"\n    },\n    \"created\": true\n  },\n  \"message\": \"Webhook enabled successfully\"\n}"}]},{"name":"Disable Webhook Topic","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations/{topic}/disable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations",":topic","disable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"topic","value":"orders---create","description":"Webhook topic with / encoded as ---"}]},"description":"Removes the webhook subscription for the given topic from the connected shop (live call to the Shopify Admin API). Succeeds even if the subscription was already removed on the Shopify side.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nPath parameter: topic uses triple dashes in place of slashes, e.g. orders---create for the orders/create topic."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/webhooks/configurations/{topic}/disable","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","webhooks","configurations",":topic","disable"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"topic","value":"orders---create","description":"Webhook topic with / encoded as ---"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook disabled successfully\",\n    \"deleted\": true\n  },\n  \"message\": \"Webhook disabled successfully\"\n}"}]},{"name":"List Access Scopes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/access-scopes","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","access-scopes"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]},"description":"List the OAuth access scopes granted to this Shopify app installation, sorted alphabetically by handle. Sourced from the Shopify Admin GraphQL `currentAppInstallation.accessScopes` field.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 500 when the underlying Shopify GraphQL call returns errors."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/access-scopes","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","access-scopes"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"scopes\": [\n      {\n        \"handle\": \"read_orders\",\n        \"description\": \"Access to view orders\"\n      },\n      {\n        \"handle\": \"read_products\",\n        \"description\": \"Access to view products and variants\"\n      },\n      {\n        \"handle\": \"read_returns\",\n        \"description\": \"Access to view returns\"\n      }\n    ],\n    \"total\": 3\n  }\n}"}]},{"name":"Get Shop Plan","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shop-plan","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shop-plan"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]},"description":"Fetch the shop plan from Shopify and return whether the store has Customer PII access via GraphQL. Basic/Starter plans do not have PII access — when false, customer email/addresses are excluded from order syncs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 500 if the Shopify GraphQL call fails."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/shop-plan","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","shop-plan"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"shop_name\": \"My Store\",\n    \"plan\": \"Shopify Plus\",\n    \"is_partner_development\": false,\n    \"is_shopify_plus\": true,\n    \"has_customer_pii_access\": true\n  }\n}"}]},{"name":"Set Returns Access","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/returns-access","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","returns-access"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]},"description":"Toggle whether the Shopify GraphQL `returns` field should be queried when this integration instance syncs orders. Set to `false` when the app installation lacks the `read_returns` permission scope — Shopify rejects the field with \"Access denied for returns field\" otherwise. The system also auto-flips this to `false` the first time that error is observed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- has_returns_access (required, boolean): true to include returns in order syncs, false to exclude them.","body":{"mode":"raw","raw":"{\n  \"has_returns_access\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/returns-access","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","returns-access"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"has_returns_access\": false\n  }\n}"}]},{"name":"Resume Customer PII Access","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/customer-pii-access/resume","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","customer-pii-access","resume"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]},"description":"Clear the customer PII access blocked state for this Shopify integration instance and re-enable automatic order syncing. Call this after the Shopify store administrator has granted the app access to protected customer data (Shopify Partner Dashboard -> API access -> Protected customer data). The blocked state is set automatically when Shopify rejects an orders query with \"This app is not approved to use the [field] field\" (protected customer data), which also disables automatic sync - orders without customer PII are unusable in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo request body. Returns the updated flags:\n- customer_pii_access_blocked (boolean): false after resuming\n- is_automatic_sync_enabled (boolean): true after resuming"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/customer-pii-access/resume","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","customer-pii-access","resume"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"customer_pii_access_blocked\": false,\n    \"is_automatic_sync_enabled\": true\n  }\n}"}]},{"name":"Resume Invalid Access Token","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/access-token/resume","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","access-token","resume"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]},"description":"Clear the invalid access token state for this Shopify integration instance and re-enable automatic syncing. Call this after the Shopify app has been reauthorized and a fresh access token has been issued (e.g. the app was reinstalled or the token was rotated). The invalid state is set automatically when Shopify rejects an API call with 401 \"Invalid API key or access token (unrecognized login or wrong password)\", which also disables automatic sync to stop the failed-job retry storm.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nNo request body. Returns the updated flags:\n- access_token_invalid (boolean): false after resuming\n- is_automatic_sync_enabled (boolean): true after resuming"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/access-token/resume","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","access-token","resume"],"variable":[{"key":"integrationInstance","value":"42","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"access_token_invalid\": false,\n    \"is_automatic_sync_enabled\": true\n  }\n}"}]},{"name":"List Payouts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns a paginated list of Shopify Payments payouts synced for the integration instance. Each payout includes the settlement amount, a normalized summary split of charges, refunds, and adjustments (gross and fee portions), the accounting status, and the number of balance-transaction lines.\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: status, currency, accounting_status (text), amount (numeric), payout_date (date), created_at (datetime). filter[search] matches the payout ID and currency.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric), and is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, days_ago, past_days (date/datetime). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: id, legacy_resource_id, payout_date, amount, status, accounting_status (prefix with - for descending; default -payout_date). Pagination defaults to 10 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 12,\n      \"legacy_resource_id\": \"87642309854\",\n      \"payout_date\": \"2026-07-10\",\n      \"status\": \"paid\",\n      \"currency\": \"USD\",\n      \"amount\": 1842.55,\n      \"summary\": {\n        \"charges_gross\": 2010.4,\n        \"charges_fee\": 58.3,\n        \"refunds_gross\": -95,\n        \"refunds_fee\": -2.85,\n        \"adjustments_gross\": -11.7,\n        \"adjustments_fee\": 0\n      },\n      \"accounting_status\": \"pending\",\n      \"balance_transaction_count\": 46,\n      \"shopify_created_at\": \"2026-07-10T04:02:11+00:00\",\n      \"created_at\": \"2026-07-10T06:15:42+00:00\",\n      \"updated_at\": \"2026-07-11T06:15:40+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payouts?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payouts?page=3\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payouts?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/payouts\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 27\n}"}]},{"name":"Get Payout Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/filter-options","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns the available filter values for the payouts list: every payout status and accounting status the system recognises, plus the settlement currencies present in the synced payouts for the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/filter-options","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"statuses\": [\n      \"scheduled\",\n      \"in_transit\",\n      \"paid\",\n      \"failed\",\n      \"canceled\"\n    ],\n    \"accounting_statuses\": [\n      \"pending\",\n      \"ready\",\n      \"posted\",\n      \"held\",\n      \"error\"\n    ],\n    \"currencies\": [\n      \"CAD\",\n      \"USD\"\n    ]\n  }\n}"}]},{"name":"Sync Payouts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Queues a background sync that imports Shopify Payments payouts and their transaction lines from eBay for the integration instance. Returns a tracked_job_log_id that can be used to monitor the progress of the sync.\n\nThe request body is optional. With no body, the sync runs the default incremental (cursor-based) window. Supply mode to control the range: latest (incremental, default), from_start_date (from the instance start date to now), date_range (bounded by date_from/date_to), or all (full backfill). date_from and date_to are Y-m-d dates and apply when mode is date_range (date_to must be on or after date_from).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4431\n  },\n  \"message\": \"Payout sync job has been queued\"\n}"}]},{"name":"Get Payout","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/{payout}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts",":payout"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payout","value":"12","description":"Payout ID"}]},"description":"Returns the full detail of a single payout, including the raw Shopify summary breakdown, receipt totals, and every balance-transaction line with its linked local order and payment transaction where resolved. Returns 403 if the payout does not belong to the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payouts/{payout}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payouts",":payout"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payout","value":"12","description":"Payout ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"legacy_resource_id\": \"87642309854\",\n    \"payout_date\": \"2026-07-10\",\n    \"status\": \"paid\",\n    \"currency\": \"USD\",\n    \"amount\": 1842.55,\n    \"summary\": {\n      \"charges_gross\": 2010.4,\n      \"charges_fee\": 58.3,\n      \"refunds_gross\": -95,\n      \"refunds_fee\": -2.85,\n      \"adjustments_gross\": -11.7,\n      \"adjustments_fee\": 0\n    },\n    \"summary_json\": {\n      \"charges_gross\": 2010.4,\n      \"charges_fee\": 58.3,\n      \"refunds_fee_gross\": -95,\n      \"refunds_fee\": -2.85,\n      \"adjustments_gross\": -11.7,\n      \"adjustments_fee\": 0\n    },\n    \"accounting_status\": \"pending\",\n    \"base_currency_rate\": null,\n    \"receipt_json\": null,\n    \"shopify_created_at\": \"2026-07-10T04:02:11+00:00\",\n    \"shopify_updated_at\": \"2026-07-10T09:30:00+00:00\",\n    \"created_at\": \"2026-07-10T06:15:42+00:00\",\n    \"updated_at\": \"2026-07-11T06:15:40+00:00\",\n    \"balance_transactions\": [\n      {\n        \"id\": 501,\n        \"legacy_resource_id\": \"99120833411\",\n        \"shopify_payout_id\": 12,\n        \"type\": \"charge\",\n        \"financial_code\": \"charge: sale\",\n        \"amount\": 129.99,\n        \"fee\": 4.07,\n        \"net\": 125.92,\n        \"source_type\": \"charge\",\n        \"source_order_id\": \"6531194880233\",\n        \"adjustment_reason\": null,\n        \"shopify_order_transaction_id\": 3120,\n        \"shopify_order_id\": 845,\n        \"order_transaction\": {\n          \"id\": 3120,\n          \"legacy_resource_id\": 7714120990001,\n          \"kind\": \"sale\",\n          \"status\": \"success\",\n          \"amount\": 129.99,\n          \"gateway\": \"shopify_payments\"\n        },\n        \"order\": {\n          \"id\": 845,\n          \"legacy_resource_id\": 6531194880233,\n          \"name\": \"#1284\",\n          \"currency\": \"USD\"\n        },\n        \"created_at\": \"2026-07-10T06:15:43+00:00\",\n        \"updated_at\": \"2026-07-10T06:15:43+00:00\"\n      },\n      {\n        \"id\": 502,\n        \"legacy_resource_id\": \"99120833412\",\n        \"shopify_payout_id\": 12,\n        \"type\": \"adjustment\",\n        \"financial_code\": \"adjustment: chargeback\",\n        \"amount\": -95,\n        \"fee\": 15,\n        \"net\": -110,\n        \"source_type\": \"dispute\",\n        \"source_order_id\": null,\n        \"adjustment_reason\": \"chargeback\",\n        \"shopify_order_transaction_id\": null,\n        \"shopify_order_id\": null,\n        \"created_at\": \"2026-07-10T06:15:43+00:00\",\n        \"updated_at\": \"2026-07-10T06:15:43+00:00\"\n      }\n    ],\n    \"balance_transaction_count\": 2,\n    \"integration_instance\": {\n      \"id\": 1,\n      \"name\": \"My Shopify Store\",\n      \"myshopify_domain\": \"my-store.myshopify.com\"\n    }\n  }\n}"}]},{"name":"List Balance Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/balance-transactions","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","balance-transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns a paginated list of Shopify Payments balance transaction lines across every payout synced for the integration instance — the line-level detail behind the payout summaries. Each line includes its type, financial code, amount, fee, net, source type, source order ID, adjustment reason, and cross-link blocks for the parent payout and (when matched) the Shopify order.\n\nAuthentication: Requires Bearer token.\n\nFilters: filter[search] matches the internal ID, balance transaction ID, source order ID, financial code, type, or linked Shopify order (Shopify order ID or internal order ID). filter[financial_code], filter[type], filter[shopify_payout_id], and filter[id] are exact-match filters.\n\nAllowed sorts: id, amount, created_at (prefix with - for descending; default -id). Pagination defaults to 15 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/balance-transactions","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","balance-transactions"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 4402,\n      \"legacy_resource_id\": \"774829001\",\n      \"shopify_payout_id\": 31,\n      \"type\": \"charge\",\n      \"financial_code\": \"charge: charge\",\n      \"amount\": 128.4,\n      \"fee\": 4.02,\n      \"net\": 124.38,\n      \"source_type\": \"charge\",\n      \"source_order_id\": \"5231098442\",\n      \"adjustment_reason\": null,\n      \"shopify_order_transaction_id\": 660123,\n      \"shopify_order_id\": 8890,\n      \"payout\": {\n        \"shopify_payout_id\": 31,\n        \"legacy_resource_id\": \"88123456\",\n        \"payout_date\": \"2026-07-12\",\n        \"link_reference\": \"88123456\",\n        \"link_type_label\": \"Shopify Payout\",\n        \"link_id\": 31,\n        \"link_route\": \"/integrations/shopify/finance/payout/31\"\n      },\n      \"order\": {\n        \"id\": 8890,\n        \"legacy_resource_id\": \"5231098442\",\n        \"name\": \"#1042\",\n        \"currency\": \"USD\",\n        \"link_reference\": \"#1042\",\n        \"link_type_label\": \"Shopify Order\",\n        \"link_id\": 8890,\n        \"link_route\": \"/integrations/shopify/orders/8890\"\n      },\n      \"created_at\": \"2026-07-12T05:41:20+00:00\",\n      \"updated_at\": \"2026-07-12T05:41:20+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/balance-transactions?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/balance-transactions?page=4\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/balance-transactions?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/balance-transactions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 53\n}"}]},{"name":"Get Balance Transaction Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/balance-transactions/filter-options","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","balance-transactions","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns the distinct filter values present in the synced balance transactions for the integration instance: every balance-transaction type and every financial code, so a client can populate the balance-transaction filters.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/balance-transactions/filter-options","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","balance-transactions","filter-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"types\": [\n      \"adjustment\",\n      \"charge\",\n      \"dispute\",\n      \"fee\",\n      \"refund\"\n    ],\n    \"financial_codes\": [\n      \"adjustment: adjustment\",\n      \"charge: charge\",\n      \"refund: refund\"\n    ]\n  }\n}"}]},{"name":"List Global Payout Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups"]},"description":"Returns every global (workspace-wide) payout mapping group, ordered by sort order. Global groups apply to all Shopify integration instances unless an instance defines its own groups. If no global groups exist yet, the two defaults (Shopify Sales as an invoice group and Shopify Fees as a bill group) are created and returned.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_instance_id\": null,\n      \"name\": \"Shopify Sales\",\n      \"document_type\": \"invoice\",\n      \"sort_order\": 0,\n      \"mappings_count\": 9,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"integration_instance_id\": null,\n      \"name\": \"Shopify Fees\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 1,\n      \"mappings_count\": 4,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Global Payout Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups"]},"description":"Creates a global payout mapping group that applies to every Shopify integration instance. Type mappings assigned to the group are combined into a single financial document of the group's document type when a payout is posted.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Marketplace Fees\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 3,\n  \"integration_instance_id\": null,\n  \"name\": \"Marketplace Fees\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2,\n  \"created_at\": \"2026-07-17T11:20:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:20:00.000000Z\"\n}"}]},{"name":"Reorder Global Payout Mapping Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups","reorder"]},"description":"Reorders the global payout mapping groups. Pass the full list of global group IDs in the desired order; each group's sort order is updated to match its position in the list.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): mapping group IDs in the desired display order. Each ID must reference an existing payout mapping group.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    2,\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups","reorder"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Groups reordered successfully.\"\n}"}]},{"name":"Update Global Payout Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Updates the name, document type, or sort order of a global payout mapping group.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Shopify Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"integration_instance_id\": null,\n  \"name\": \"Shopify Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0,\n  \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:45:00.000000Z\"\n}"}]},{"name":"Delete Global Payout Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Deletes a global payout mapping group. Type mappings that referenced the group are kept but left without a group assignment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Payout Mapping Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns the payout mapping groups visible to the integration instance: the instance's own groups first, followed by the global groups. If no global groups exist yet, the two defaults (Shopify Sales as an invoice group and Shopify Fees as a bill group) are created first.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"integration_instance_id\": 1,\n      \"name\": \"US Store Adjustments\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 0,\n      \"mappings_count\": 2,\n      \"created_at\": \"2026-07-17T10:12:00.000000Z\",\n      \"updated_at\": \"2026-07-17T10:12:00.000000Z\"\n    },\n    {\n      \"id\": 1,\n      \"integration_instance_id\": null,\n      \"name\": \"Shopify Sales\",\n      \"document_type\": \"invoice\",\n      \"sort_order\": 0,\n      \"mappings_count\": 9,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"integration_instance_id\": null,\n      \"name\": \"Shopify Fees\",\n      \"document_type\": \"bill\",\n      \"sort_order\": 1,\n      \"mappings_count\": 4,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Payout Mapping Group","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Creates a payout mapping group scoped to the integration instance. Instance groups are listed ahead of the global defaults and can be used to separate the instance's payout lines into their own financial documents.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Marketplace Fees\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 6,\n  \"integration_instance_id\": 1,\n  \"name\": \"Marketplace Fees\",\n  \"document_type\": \"bill\",\n  \"sort_order\": 2,\n  \"created_at\": \"2026-07-17T11:20:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:20:00.000000Z\"\n}"}]},{"name":"Reorder Payout Mapping Groups","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Reorders the payout mapping groups scoped to the integration instance. Pass the full list of the instance's group IDs in the desired order; each group's sort order is updated to match its position in the list. Global groups are not affected.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): mapping group IDs in the desired display order. Each ID must reference an existing payout mapping group.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    6,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/reorder","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups","reorder"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Groups reordered successfully.\"\n}"}]},{"name":"Update Payout Mapping Group","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Updates the name, document type, or sort order of a payout mapping group scoped to the integration instance.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- name (required, string, max 255): display name for the group.\n- document_type (required, string): financial document the group posts to; one of invoice, bill.\n- sort_order (optional, integer, min 0): position of the group in ordered listings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Shopify Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 5,\n  \"integration_instance_id\": 1,\n  \"name\": \"Shopify Sales - US\",\n  \"document_type\": \"invoice\",\n  \"sort_order\": 0,\n  \"created_at\": \"2026-07-17T10:12:00.000000Z\",\n  \"updated_at\": \"2026-07-17T11:45:00.000000Z\"\n}"}]},{"name":"Delete Payout Mapping Group","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]},"description":"Deletes a payout mapping group scoped to the integration instance. Type mappings that referenced the group are kept but left without a group assignment.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-mapping-groups/{payoutMappingGroup}","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-mapping-groups",":payoutMappingGroup"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"},{"key":"payoutMappingGroup","value":"5","description":"Payout mapping group ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Payout Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns the resolved payout type mappings for the integration instance: per-instance override rows plus the global default rows they have not overridden. Each row maps a financial code (a normalized type / source / reason combination from Shopify Payments balance transactions) to a general-ledger account and an optional mapping group; is_override indicates an instance-specific row. Before listing, any financial codes newly seen in the instance's synced balance transactions are registered as unmapped global rows so they can be configured.\n\nAuthentication: Requires Bearer token.\n\nFilterable columns: type, source_type, reason, financial_code, typical_amount_sign, mapping_status (mapped/unmapped), group_status (assigned/unassigned) (text), created_at, updated_at (datetime). filter[search] matches type, source type, reason, and financial code.\n\nFiltering: pass filter[column]=value for an exact match, or filter[column.operator]=value with operators such as contains, does_not_contain, is, is_not, is_one_of, starts_with, ends_with, is_empty, is_not_empty (text), greater_than, less_than, greater_than_or_equal, less_than_or_equal, between (numeric), and is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, days_ago, past_days (date/datetime). Complex AND/OR trees can be sent as a base64-encoded JSON tree in the filter_groups parameter.\n\nAllowed sorts: type, source_type, financial_code, created_at (prefix with - for descending; default financial_code). Pagination defaults to 10 per page."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 7,\n      \"integration_instance_id\": 1,\n      \"type\": \"charge\",\n      \"source_type\": \"charge\",\n      \"reason\": null,\n      \"financial_code\": \"charge: sale\",\n      \"typical_amount_sign\": \"positive\",\n      \"shopify_payout_mapping_group_id\": 1,\n      \"nominalCode\": {\n        \"id\": 210,\n        \"code\": \"4000\",\n        \"name\": \"Sales Revenue\"\n      },\n      \"mappingGroup\": {\n        \"id\": 1,\n        \"name\": \"Shopify Sales\",\n        \"document_type\": \"invoice\"\n      },\n      \"is_override\": true,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:05:00.000000Z\"\n    },\n    {\n      \"id\": 3,\n      \"integration_instance_id\": null,\n      \"type\": \"fee\",\n      \"source_type\": \"shopify_payments\",\n      \"reason\": null,\n      \"financial_code\": \"fee: shopify_payments\",\n      \"typical_amount_sign\": \"negative\",\n      \"shopify_payout_mapping_group_id\": null,\n      \"nominalCode\": null,\n      \"mappingGroup\": null,\n      \"is_override\": false,\n      \"created_at\": \"2026-07-17T09:00:00.000000Z\",\n      \"updated_at\": \"2026-07-17T09:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payout-type-mappings?page=1\",\n  \"from\": 1,\n  \"last_page\": 2,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payout-type-mappings?page=2\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shopify/1/payout-type-mappings?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shopify/1/payout-type-mappings\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 14\n}"}]},{"name":"Update Payout Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Updates individual payout type mappings, assigning or clearing the general-ledger account and mapping group of each. Fields omitted from a mapping entry are left unchanged; pass null to clear an assignment.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- mappings (required, array, min 1): mapping updates to apply.\n- mappings[].id (required, integer): ID of an existing payout type mapping.\n- mappings[].nominal_code_id (optional, nullable, integer): general-ledger account to assign; must reference an existing account. Pass null to clear.\n- mappings[].shopify_payout_mapping_group_id (optional, nullable, integer): payout mapping group to assign; must reference an existing group. Pass null to clear.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"id\": 7,\n      \"nominal_code_id\": 210,\n      \"shopify_payout_mapping_group_id\": 1\n    },\n    {\n      \"id\": 3,\n      \"nominal_code_id\": 305\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Payout type mappings updated successfully.\"\n}"}]},{"name":"Bulk Assign Payout Type Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Assigns a general-ledger account and/or a mapping group to several payout type mappings at once. At least one of nominal_code_id or shopify_payout_mapping_group_id must be provided; pass null to clear that assignment on all selected mappings. Only mappings scoped to the integration instance are updated - global rows are not modified.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- ids (required, array of integers, min 1): payout type mapping IDs to update. Each ID must reference an existing payout type mapping.\n- nominal_code_id (optional, nullable, integer): general-ledger account to assign to all selected mappings; must reference an existing account.\n- shopify_payout_mapping_group_id (optional, nullable, integer): payout mapping group to assign to all selected mappings; must reference an existing group.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3,\n    7,\n    9\n  ],\n  \"nominal_code_id\": 210,\n  \"shopify_payout_mapping_group_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-type-mappings/bulk-assign","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-type-mappings","bulk-assign"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated\": 3\n  },\n  \"message\": \"3 type mapping(s) updated successfully.\"\n}"}]},{"name":"Get Payout Finance Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Returns the resolved payout finance settings for the integration instance: the fallback revenue and expense accounts used for unmapped payout lines, the clearing account payouts settle against, the accounting sync mode (per_order or per_payout; default per_order), and the optional payout accounting start date before which payouts are not posted. Fallback and clearing accounts fall back to the workspace-wide values when the instance has none of its own.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}"}]},{"name":"Update Payout Finance Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]},"description":"Updates the payout finance settings for the integration instance. All fields are optional; omitted fields keep their current values, and nullable fields can be set to null to clear them. Returns the resolved settings after the update.\n\nAuthentication: Requires Bearer token.\n\nRequest body:\n- fallback_revenue_nominal_code_id (optional, nullable, integer): account for unmapped revenue lines; must reference an existing general-ledger account.\n- fallback_expense_nominal_code_id (optional, nullable, integer): account for unmapped expense lines; must reference an existing general-ledger account.\n- clearing_nominal_code_id (optional, nullable, integer): clearing account that payout documents settle against; must reference an existing general-ledger account.\n- accounting_sync_mode (optional, string): one of per_order, per_payout.\n- payout_accounting_start_date (optional, nullable, date): payouts dated before this are not posted to accounting.","body":{"mode":"raw","raw":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shopify/{integrationInstance}/payout-finance-settings","host":["{{baseUrl}}"],"path":["api","shopify",":integrationInstance","payout-finance-settings"],"variable":[{"key":"integrationInstance","value":"1","description":"Shopify integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"fallback_revenue_nominal_code_id\": 220,\n  \"fallback_expense_nominal_code_id\": 310,\n  \"clearing_nominal_code_id\": 145,\n  \"accounting_sync_mode\": \"per_payout\",\n  \"payout_accounting_start_date\": \"2026-07-01\"\n}"}]}]},{"name":"WooCommerce","item":[{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce","host":["{{baseUrl}}"],"path":["api","woo-commerce"]},"description":"List all WooCommerce integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce","host":["{{baseUrl}}"],"path":["api","woo-commerce"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My WooCommerce Store\",\n      \"integration_id\": 7,\n      \"integration_name\": \"WooCommerce\",\n      \"store\": {\n        \"id\": 2,\n        \"name\": \"Main Store\"\n      },\n      \"is_automatic_sync_enabled\": true,\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce","host":["{{baseUrl}}"],"path":["api","woo-commerce"]},"description":"Create a new WooCommerce integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAfter creation, the response includes a redirect_url for OAuth authorization with WooCommerce.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- name (string, required) — Unique name for the integration instance\n- integration_id (integer, required) — ID of the WooCommerce integration record\n- connection_settings (object, optional) — WooCommerce API keys\n  - key_id (integer) — WooCommerce key ID\n  - user_id (string) — WooCommerce user ID\n  - consumer_key (string) — WooCommerce consumer key\n  - consumer_secret (string) — WooCommerce consumer secret\n  - key_permissions (string) — Key permissions (e.g. 'read_write')\n- integration_settings (object, required) — Store configuration\n  - url (string, required) — Store URL, must start with 'https://' and not end with '/'\n  - start_date (string, required) — Date to begin syncing orders from\n  - store_id (integer, required) — SKU.io store ID\n  - auto_link_products (boolean, required) — Auto-link WooCommerce products to SKU.io products\n  - auto_create_products (boolean, required) — Auto-create SKU.io products for unlinked WooCommerce products\n  - sales_nominal_code_id (integer, optional) — Nominal code for sales revenue\n  - cogs_nominal_code_id (integer, optional) — Nominal code for COGS\n  - shipping_revenue_nominal_code_id (integer, optional) — Nominal code for shipping revenue\n  - shipping_refund_nominal_code_id (integer, optional) — Nominal code for shipping refunds\n  - sales_returns_allowances_nominal_code_id (integer, optional) — Nominal code for returns\n  - sync_sales_order_invoices_to_accounting (boolean, optional, default: true)\n  - sync_sales_credit_to_accounting (boolean, optional, default: true)\n  - batch_period_sales_order_fulfillments (string, optional) — Batch period override for fulfillments\n  - batch_period_customer_returns (string, optional) — Batch period override for returns\n  - proforma_marketplace_cost_percentage (float, optional)\n  - proforma_payment_cost_percentage (float, optional)\n- is_automatic_sync_enabled (boolean, optional, default: false)","body":{"mode":"raw","raw":"{\n  \"name\": \"My WooCommerce Store\",\n  \"integration_id\": 7,\n  \"connection_settings\": {\n    \"key_id\": 123,\n    \"user_id\": \"wc_user_abc\",\n    \"consumer_key\": \"ck_abc123\",\n    \"consumer_secret\": \"cs_abc123\",\n    \"key_permissions\": \"read_write\"\n  },\n  \"integration_settings\": {\n    \"url\": \"https://mystore.com\",\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 2,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce","host":["{{baseUrl}}"],"path":["api","woo-commerce"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My WooCommerce Store\",\n    \"integration_id\": 7,\n    \"integration_name\": \"WooCommerce\",\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  },\n  \"redirect_url\": \"https://mystore.com/wc-auth/v1/authorize?app_name=SKU.io&scope=read_write&user_id=42&return_url=https%3A%2F%2Fapp.sku.io%2F&callback_url=https%3A%2F%2Fapp.sku.io%2Fapi%2Fwoo-commerce%2Fcallback\"\n}"}]},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Show a single WooCommerce integration instance with loaded integration and store relations.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My WooCommerce Store\",\n    \"integration_id\": 7,\n    \"integration_name\": \"WooCommerce\",\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"connection_settings\": {\n      \"key_id\": 123,\n      \"user_id\": \"wc_user_abc\",\n      \"consumer_key\": \"ck_***\",\n      \"consumer_secret\": \"cs_***\",\n      \"key_permissions\": \"read_write\"\n    },\n    \"integration_settings\": {\n      \"url\": \"https://mystore.com\",\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 2,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Update a WooCommerce integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPATCH requests perform a deep merge with existing settings. PUT requests replace all provided fields.\n\nAuthentication: Requires Bearer token.\n\nRequest Body (all optional):\n- name (string) — New name (must be unique)\n- connection_settings (object) — Updated WooCommerce API credentials\n- integration_settings (object) — Updated integration settings (same fields as store)\n- is_automatic_sync_enabled (boolean)","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated WooCommerce Store\",\n  \"integration_settings\": {\n    \"url\": \"https://mystore.com\",\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 2,\n    \"auto_link_products\": true,\n    \"auto_create_products\": true,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated WooCommerce Store\",\n    \"integration_id\": 7,\n    \"integration_name\": \"WooCommerce\",\n    \"store\": {\n      \"id\": 2,\n      \"name\": \"Main Store\"\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Update WooCommerce Integration","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration_instance identifier"}]},"description":"Update the settings of a WooCommerce integration instance. All fields are optional - only the fields you send are changed, and `integration_settings` is deep-merged with the existing settings on PATCH.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nTop-level fields:\n- name (string): Display name for the integration instance.\n- is_automatic_sync_enabled (boolean): Master switch for automatic background syncing.\n- connection_settings (object): WooCommerce REST API credentials - user_id, consumer_key, consumer_secret, key_permissions.\n- integration_settings (object): Store configuration.\n\nintegration_settings fields:\n- url (string): Store URL. Must start with https:// and must not end with a slash.\n- start_date (date): Earliest order date to sync. Must be on or after the SKU.io inventory start date.\n- store_id (integer): SKU.io store the sales channel belongs to.\n- auto_link_products (boolean): Automatically link WooCommerce products to SKU.io products by SKU.\n- auto_create_products (boolean): Automatically create SKU.io products for unmatched listings.\n- sales_nominal_code_id, cogs_nominal_code_id, shipping_revenue_nominal_code_id, shipping_refund_nominal_code_id, sales_returns_allowances_nominal_code_id (integer|null): Accounting nominal code assignments.\n- pricing (object): Price sync settings.\n- inventory (object): Inventory sync settings (locations, selected warehouses). Sent arrays fully replace the stored ones.\n- proforma_marketplace_cost_percentage, proforma_payment_cost_percentage (number|null): Estimated cost percentages for proforma profit calculations.\n- sync_sales_order_invoices_to_accounting, sync_sales_credit_to_accounting (boolean): Accounting sync toggles.\n- batch_period_sales_order_fulfillments, batch_period_customer_returns (string|null): Per-channel accounting batch period overrides.\n\nRoute name: woo-commerce.update","body":{"mode":"raw","raw":"{\n  \"name\": \"My WooCommerce Store\",\n  \"is_automatic_sync_enabled\": true,\n  \"integration_settings\": {\n    \"url\": \"https://store.example.com\",\n    \"start_date\": \"2026-01-01\",\n    \"store_id\": 3,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": 12,\n    \"cogs_nominal_code_id\": 18,\n    \"shipping_revenue_nominal_code_id\": 21,\n    \"shipping_refund_nominal_code_id\": 22,\n    \"sales_returns_allowances_nominal_code_id\": 23,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration_instance identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My WooCommerce Store\",\n    \"integration_id\": 9,\n    \"is_automatic_sync_enabled\": true,\n    \"integration_settings\": {\n      \"url\": \"https://store.example.com\",\n      \"start_date\": \"2026-01-01\",\n      \"store_id\": 3,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sales_nominal_code_id\": 12,\n      \"cogs_nominal_code_id\": 18,\n      \"shipping_revenue_nominal_code_id\": 21,\n      \"shipping_refund_nominal_code_id\": 22,\n      \"sales_returns_allowances_nominal_code_id\": 23,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true\n    },\n    \"integration_name\": \"WooCommerce\",\n    \"sales_channel_id\": 4,\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Main Store\"\n    },\n    \"created_at\": \"2026-01-05T10:00:00.000000Z\",\n    \"updated_at\": \"2026-07-01T08:15:22.000000Z\"\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Delete a WooCommerce integration instance. This dispatches a background job to clean up all associated data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","get-authorization-url"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get the WooCommerce OAuth authorization URL for a given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUse this URL to redirect the user to WooCommerce to authorize the API keys.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","get-authorization-url"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://mystore.com/wc-auth/v1/authorize?app_name=SKU.io&scope=read_write&user_id=42&return_url=https%3A%2F%2Fapp.sku.io%2F&callback_url=https%3A%2F%2Fapp.sku.io%2Fapi%2Fwoo-commerce%2Fcallback\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List WooCommerce products (one row per sellable unit — parent products and variations unified) for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuick Filters:\n- filter[search] (string, optional) — matches sku, unified_title, or id\n- filter[status] (string, optional) — exact status: publish, draft, pending, private ('all' is a no-op)\n- filter[mapping_status] (string, optional) — 'mapped' or 'unmapped' (linked to a SKU.io product or not)\n- filter[archived] (string, optional) — 'true' (archived only) or 'false' (active only)\n\nAdvanced Filters (filter_groups):\nBase64-encoded JSON tree with and/or conjunctions and nested groups.\n- Text columns: status, product_type, sku, stock_status — operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_one_of, is_not_one_of, is_empty, is_not_empty\n- Numeric columns: price — operators: is, is_not, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_one_of, is_empty, is_not_empty\n- Boolean columns: mapped — operator: is with value true/false\nUnregistered filter columns return HTTP 400.\n\nSorting: sort=field or sort=-field (descending). Allowed sorts: id, woo_commerce_product_id, sku, unified_title, woo_commerce_parent_product_id, woo_commerce_variation_id, woo_commerce_unique_id, parent_sku, variation_name, price, regular_price, sale_price, manage_stock, stock_quantity, weight, product_type, slug, status, created_at, updated_at. Default: -id.\n\nPagination: page (default 1), per_page (default 10). Standard paginator response with data, current_page, last_page, per_page, total, from, to."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 501,\n      \"integration_instance_id\": 1,\n      \"woo_commerce_parent_product_id\": 33,\n      \"woo_commerce_product_id\": 9001,\n      \"woo_commerce_variation_id\": 0,\n      \"woo_commerce_unique_id\": 9001,\n      \"parent_product_name\": \"Blue Widget\",\n      \"parent_sku\": \"BW-001\",\n      \"variation_name\": null,\n      \"unified_title\": \"Blue Widget\",\n      \"sku\": \"BW-001\",\n      \"price\": \"29.99\",\n      \"regular_price\": \"34.99\",\n      \"sale_price\": null,\n      \"manage_stock\": true,\n      \"stock_quantity\": 42,\n      \"stock_status\": \"instock\",\n      \"weight\": \"0.50\",\n      \"image_url\": \"https://store.example.com/wp-content/uploads/blue-widget.jpg\",\n      \"product_type\": \"simple\",\n      \"status\": \"publish\",\n      \"slug\": \"blue-widget\",\n      \"archived_at\": null,\n      \"created_at\": \"2026-01-10T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-01T08:30:00.000000Z\",\n      \"product_listing_id\": 88,\n      \"product\": {\n        \"id\": 12,\n        \"name\": \"Blue Widget\",\n        \"sku\": \"BW-001\",\n        \"default_financial_line_type_id\": 3,\n        \"default_financial_line_type\": {\n          \"id\": 3,\n          \"name\": \"Product Sales\",\n          \"classification\": \"revenue\"\n        },\n        \"listing_id\": 88\n      },\n      \"subscription_offering\": null,\n      \"mapped_at\": \"2026-01-10T10:00:00.000000Z\",\n      \"mapped_sku\": \"BW-001\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/woo-commerce/1/products?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"https://example.sku.io/api/woo-commerce/1/products?page=5\",\n  \"next_page_url\": \"https://example.sku.io/api/woo-commerce/1/products?page=2\",\n  \"path\": \"https://example.sku.io/api/woo-commerce/1/products\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 45\n}"}]},{"name":"Show Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]},"description":"Get a single WooCommerce product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"integration_instance_id\": 1,\n    \"product_listing_id\": 88,\n    \"product\": {\n      \"id\": 12,\n      \"name\": \"Blue Widget\",\n      \"sku\": \"BW-001\",\n      \"listing_id\": 88\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2024-01-10T10:00:00.000000Z\",\n    \"mapped_sku\": \"BW-001\",\n    \"json_object\": {\n      \"id\": 9001,\n      \"name\": \"Blue Widget\",\n      \"sku\": \"BW-001\",\n      \"status\": \"publish\",\n      \"price\": \"29.99\",\n      \"description\": \"A high-quality blue widget.\",\n      \"categories\": [\n        {\n          \"id\": 5,\n          \"name\": \"Widgets\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Update Product","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]},"description":"Update a WooCommerce product record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"integration_instance_id\": 1\n  }\n}"}]},{"name":"Delete Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]},"description":"Delete a single WooCommerce product record from SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"product","value":"501","description":"WooCommerce product local DB ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Create SKU Products from WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","create-sku-products"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a job to create SKU.io products from the selected WooCommerce products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array of integers, optional) — IDs of WooCommerce products to create SKU products from. Omit if create_all_products is true or filters are provided.\n- create_all_products (boolean, optional) — If true, create SKU products for all unlinked WooCommerce products\n- mappings (array, optional) — Column mapping configuration for the import\n- filters (object, optional) — list view filters to determine which products to include\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ],\n  \"create_all_products\": false,\n  \"mappings\": [\n    {\n      \"column\": \"sku\",\n      \"mapped_to\": \"sku\"\n    },\n    {\n      \"column\": \"name\",\n      \"mapped_to\": \"name\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","create-sku-products"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be created shortly.\"\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","refresh"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job to refresh all WooCommerce products from the store API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","refresh"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be refreshed shortly.\"\n}"}]},{"name":"Refresh Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","refresh-tracked"],"variable":[{"key":"integration_instance","value":"","description":"The integration_instance identifier"}]},"description":"Dispatch a tracked background job to re-fetch products from WooCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional):\n- mode (string): One of since_latest, full_catalog, date_range. Defaults to full_catalog.\n- latestDate (string|null): ISO8601 timestamp used as modified_after when mode is since_latest.\n- dateFrom (date|null): YYYY-MM-DD start date for date_range mode.\n- dateTo (date|null): Reserved for future use.\n- dateMethod (string|null): One of created or updated. When date_range is selected with dateMethod=created the WC `after` filter is used; with dateMethod=updated (default) the WC `modified_after` filter is used.\n\nReturns a tracked_job_log_id that can be used to monitor job progress via the tracked job log endpoints.\n\nRoute name: woo-commerce.products.refresh-tracked","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"latestDate\": \"2026-05-01T00:00:00Z\",\n  \"dateFrom\": null,\n  \"dateTo\": null,\n  \"dateMethod\": \"updated\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","refresh-tracked"],"variable":[{"key":"integration_instance","value":"","description":"The integration_instance identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Product refresh job has been queued\"\n}"}]},{"name":"Map Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Map WooCommerce products to SKU.io products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- mappings (array, required) — Collection of WooCommerce-to-SKU product mappings\n  - sales_channel_product_id (integer) — WooCommerce product local DB ID\n  - sku_product_id (integer) — SKU.io product ID to link to","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_product_id\": 501,\n      \"sku_product_id\": 12\n    },\n    {\n      \"sales_channel_product_id\": 502,\n      \"sku_product_id\": 15\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\"\n}"}]},{"name":"Smart Match Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID"}]},"description":"Find suggested SKU product matches for a single WooCommerce listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMatching strategy:\n- exact_match: SKU product whose sku == woo_commerce_product.sku\n- barcode_match: always null (WooCommerce products do not expose a barcode field)\n- similar_matches: up to 5 fuzzy matches by unified_title / sku tokens\n\nArchived SKU products are excluded. Used by the listing detail page mapping modal.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 200,\n      \"sku\": \"WOO-WIDGET-L\",\n      \"name\": \"Widget Large\",\n      \"barcode\": 12345678905,\n      \"price\": 19.99,\n      \"type\": \"simple\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 201,\n        \"sku\": \"WOO-WIDGET-M\",\n        \"name\": \"Widget Medium\",\n        \"barcode\": 12345678912,\n        \"price\": 14.99,\n        \"type\": \"simple\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Raw Product from WooCommerce","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID (internal)"}]},"description":"Fetch the raw WooCommerce REST API response for a single product, live from /wp-json/wc/v3/products/{id}. Powers the \"Load Raw Data from WooCommerce\" button on the listing detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe data is not persisted — it reflects the live WooCommerce state. Uses the upstream WooCommerce product ID (woo_commerce_product_id) for the API call.\n\nReturns 403 if the product doesn't belong to the given integration instance. Returns 500 if WooCommerce's API call fails (e.g. integration not fully configured).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID (internal)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": 906,\n      \"name\": \"Glass Pour-Over Carafe\",\n      \"slug\": \"glass-pour-over-carafe\",\n      \"permalink\": \"https://shop.example.com/product/glass-pour-over-carafe\",\n      \"type\": \"simple\",\n      \"status\": \"publish\",\n      \"sku\": \"WC-CARAFE-GLASS\",\n      \"price\": \"24.00\",\n      \"regular_price\": \"24.00\",\n      \"stock_status\": \"instock\",\n      \"stock_quantity\": 45\n    }\n  }\n}"}]},{"name":"Create SKU Product from WooCommerce Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID"}]},"description":"Create a new SKU product from a WooCommerce listing's data and map it. If a SKU product with the same SKU already exists, the existing one is linked instead of creating a duplicate (response includes linked_existing=true).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis handles product creation, pricing, and listing.\n\nReturns 422 if the WooCommerce product is already mapped — unmap it first.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"1","description":"WooCommerce product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"WOO-WIDGET-L\",\n    \"unified_title\": \"Widget Large\",\n    \"productListing\": {\n      \"id\": 42,\n      \"product_id\": 200\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Export Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/export","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Export WooCommerce products as a file download (CSV or Excel).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse is a binary file download, not JSON."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/export","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary file content>"}]},{"name":"Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","archive"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Archive WooCommerce products (hide from active list without deleting).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, required) — IDs of WooCommerce products to archive (must belong to this integration instance)\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","archive"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","unarchive"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Unarchive previously archived WooCommerce products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, required) — IDs of WooCommerce products to unarchive\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","unarchive"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","archiveable"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Check which products from the provided list can be archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, required) — IDs of WooCommerce products to check","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502,\n    503\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","archiveable"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    501,\n    502\n  ]\n}"}]},{"name":"Delete Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/delete","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","delete"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Permanently delete WooCommerce products from SKU.io (does not delete from WooCommerce).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, required) — IDs of WooCommerce products to delete","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/delete","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","delete"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products deleted successfully.\"\n}"}]},{"name":"Check Deleteable Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","deleteable"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Check which products from the provided list can be deleted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, required) — IDs of WooCommerce products to check","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","deleteable"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    501\n  ]\n}"}]},{"name":"Import Product Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","import-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job to import product field mappings for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- mappings (array, required) — Array of column mapping configurations\n  - column (string) — Source column from WooCommerce\n  - mapped_to (string) — Target field in SKU.io","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"column\": \"sku\",\n      \"mapped_to\": \"sku\"\n    },\n    {\n      \"column\": \"name\",\n      \"mapped_to\": \"name\"\n    },\n    {\n      \"column\": \"price\",\n      \"mapped_to\": \"price\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","import-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, mappings will be imported shortly.\"\n}"}]},{"name":"Sync Inventory to WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","sync-inventory"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Push current SKU.io inventory quantities to WooCommerce for selected products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array, optional) — Specific WooCommerce product IDs to sync. If omitted, syncs all products.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    501,\n    502\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","products","sync-inventory"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List WooCommerce orders for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuick Filters:\n- filter[search] (string, optional) — matches order number or WooCommerce order ID\n- filter[order_status] (string, optional) — exact status: pending, processing, on-hold, completed, cancelled, refunded, failed ('all' is a no-op)\n- filter[archived_status] (string, optional) — 'active' (default) or 'archived'\n- filter[has_sku_order] (string, optional) — 'true' for orders linked to a SKU.io sales order, 'false' for unlinked\n\nAdvanced Filters (filter_groups):\nBase64-encoded JSON tree with and/or conjunctions and nested groups.\n- Text columns: number — operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_one_of, is_not_one_of, is_empty, is_not_empty\n- Numeric columns: total, total_tax — operators: is, is_not, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_one_of, is_empty, is_not_empty\n- Date columns: date_created_gmt, created_at, updated_at — operators: is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, past_days, days_ago, is_empty, is_not_empty\nUnregistered filter columns return HTTP 400.\n\nSorting: sort=field or sort=-field (descending). Allowed sorts: id, woo_commerce_id, number, status, currency, date_created_gmt, total, total_tax, created_at, updated_at. Default: -id.\n\nPagination: page (default 1), per_page (default 10). Standard paginator response with data, current_page, last_page, per_page, total, from, to."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 601,\n      \"integration_instance_id\": 1,\n      \"woo_commerce_id\": \"10001\",\n      \"number\": \"10001\",\n      \"status\": \"processing\",\n      \"error_log\": null,\n      \"currency\": \"USD\",\n      \"date_completed_gmt\": null,\n      \"date_modified_gmt\": \"2026-06-01T09:15:00.000000Z\",\n      \"date_created_gmt\": \"2026-06-01T09:00:00.000000Z\",\n      \"total\": \"49.99\",\n      \"total_tax\": \"4.10\",\n      \"archived_at\": null,\n      \"pre_start_date_import\": false,\n      \"created_at\": \"2026-06-01T09:05:00.000000Z\",\n      \"updated_at\": \"2026-06-01T09:15:00.000000Z\",\n      \"sku_sales_order\": {\n        \"id\": 1234,\n        \"number\": \"SO-2026-001\",\n        \"order_status\": \"open\",\n        \"fulfillment_status\": \"unfulfilled\",\n        \"payment_status\": \"paid\"\n      },\n      \"last_synced_at\": \"2026-06-01T09:15:00+00:00\",\n      \"json_object\": {\n        \"id\": 10001,\n        \"number\": \"10001\",\n        \"status\": \"processing\",\n        \"currency\": \"USD\",\n        \"total\": \"49.99\",\n        \"total_tax\": \"4.10\",\n        \"billing\": {\n          \"first_name\": \"Jane\",\n          \"last_name\": \"Smith\",\n          \"email\": \"jane@example.com\"\n        }\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/woo-commerce/1/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"https://example.sku.io/api/woo-commerce/1/orders?page=12\",\n  \"next_page_url\": \"https://example.sku.io/api/woo-commerce/1/orders?page=2\",\n  \"path\": \"https://example.sku.io/api/woo-commerce/1/orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 120\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]},"description":"Get a single WooCommerce order with order items loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 601,\n    \"integration_instance_id\": 1,\n    \"sku_sales_order\": {\n      \"id\": 1234,\n      \"number\": \"SO-2024-001\"\n    },\n    \"json_object\": {\n      \"id\": 10001,\n      \"number\": \"10001\",\n      \"status\": \"processing\",\n      \"total\": \"49.99\",\n      \"line_items\": [\n        {\n          \"id\": 1,\n          \"name\": \"Blue Widget\",\n          \"quantity\": 2,\n          \"price\": \"19.99\",\n          \"sku\": \"BW-001\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Update Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]},"description":"Update a WooCommerce order record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 601\n  }\n}"}]},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]},"description":"Delete a WooCommerce order record from SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"601","description":"WooCommerce order local DB ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Create SKU Orders from WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","create-sku-orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Create SKU.io sales orders from selected WooCommerce orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array of integers, optional) — WooCommerce order local DB IDs to convert. Omit if create_all_orders is true or filters are provided.\n- create_all_orders (boolean, optional) — If true, creates SKU orders for all eligible WooCommerce orders\n- filters (object, optional) — list view filters to determine which orders to process\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    601,\n    602\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","create-sku-orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sku.io sales orders successfully created\"\n}"}]},{"name":"Update SKU Orders from WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","update-sku-orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Update SKU.io sales orders from WooCommerce order data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- ids (array of integers, optional) — WooCommerce order IDs whose linked SKU orders should be updated\n- update_all_orders (boolean, optional) — If true, update all eligible orders\n- use_jobs (boolean, optional) — If true, process updates asynchronously via jobs\n- filters (object, optional) — list view filters to determine scope","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    601,\n    602\n  ],\n  \"update_all_orders\": false,\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","update-sku-orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sku.io sales orders successfully updated\"\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","refresh"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job to refresh all orders from the WooCommerce API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","refresh"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, orders will be refreshed shortly.\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Refresh a single WooCommerce order by its unique WooCommerce order ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- uniqueId (string, required) — The WooCommerce order ID (from json_object.id)","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"10001\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 601,\n    \"integration_instance_id\": 1,\n    \"sku_sales_order\": null,\n    \"json_object\": {\n      \"id\": 10001,\n      \"status\": \"completed\",\n      \"total\": \"49.99\"\n    }\n  }\n}"}]},{"name":"Export Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/export","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Export WooCommerce orders as a file download.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse is a binary file download, not JSON."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/orders/export","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","orders","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"<binary file content>"}]},{"name":"Fulfill Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/fulfill","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","fulfill"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Submit fulfillments to WooCommerce for the specified orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis endpoint marks orders as completed in WooCommerce and submits tracking information if available.\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- order_ids (array of integers, required) — WooCommerce order local DB IDs to fulfill","body":{"mode":"raw","raw":"{\n  \"order_ids\": [\n    601,\n    602\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integration_instance}/fulfill","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integration_instance","fulfill"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillments submitted successfully.\"\n}"}]},{"name":"Get Integration Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get the paginated activity history recorded against the orders synced for a WooCommerce integration instance - status changes, sync events, and edits, with the user who caused each change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.activity-log"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WooCommerceOrder\",\n      \"subject_id\": 4512,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"completed\"\n        },\n        \"old\": {\n          \"status\": \"processing\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:25:00.000000Z\",\n      \"batch_uuid\": null\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/woo-commerce/1/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"{{base_url}}/api/woo-commerce/1/activity-log?page=3\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/woo-commerce/1/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/woo-commerce/1/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 42\n}"}]},{"name":"Get Cached Reports","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/reports","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","reports"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get the most recently cached WooCommerce reports for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns null data if no reports have been fetched yet. Trigger a refresh to fetch reports from WooCommerce."}},{"name":"Refresh Reports","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/reports/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","reports","refresh"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Dispatch a background job to re-fetch WooCommerce reports for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously on the salesOrderProcessing queue. Call GET /reports to retrieve results after the job completes."}},{"name":"List WooCommerce Refunds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/refunds?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","refunds"],"query":[{"key":"page","value":"1","description":"Page number for pagination.","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a paginated list of WooCommerce order refunds for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Refresh WooCommerce Refunds","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/refunds/refresh","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","refunds","refresh"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Dispatch a tracked background job to re-fetch all order refunds from WooCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns a tracked_job_log_id that can be used to monitor job progress via the tracked job log endpoints."}},{"name":"Refresh Orders from WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Start a background refresh that downloads orders from WooCommerce into SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe `mode` field controls which orders are fetched:\n- `latest` (default) - orders modified since the most recent local order\n- `from_start_date` - orders created since the integration's configured start date\n- `date_range` - orders created on or after `date_from` (`date_to` is accepted but not currently applied)\n- `all` - every order in the store\n\nThe job runs asynchronously. The response includes a `tracked_job_log_id` you can use to poll job progress.\n\nRoute name: woo-commerce.orders.refresh-tracked","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-01-01\",\n  \"date_to\": \"2026-01-31\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5120\n  },\n  \"message\": \"Order refresh job has been queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Latest Order Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get a summary of the most recently synced WooCommerce order plus counts of how many local WooCommerce orders exist and how many are linked to SKU.io sales orders. Useful for deciding whether a refresh is needed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"1189\",\n    \"latest_order_date\": \"2026-06-14T09:21:33.000000Z\",\n    \"latest_order_status\": \"processing\",\n    \"total_orders\": 1240,\n    \"with_sku_order\": 1180,\n    \"without_sku_order\": 60\n  }\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Archive multiple WooCommerce orders by their local IDs. Orders that are already archived are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.bulk-archive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513,\n    4514\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Restore multiple archived WooCommerce orders by their local IDs. Orders that are already active are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.bulk-unarchive","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders unarchived successfully\",\n  \"unarchived_count\": 2\n}"}]},{"name":"Archive Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Archive a single WooCommerce order. Archived orders are hidden from active listings but remain stored and can be restored later.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.archive","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Order","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Restore a single archived WooCommerce order to the active list.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.unarchive","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Get the paginated activity history for a single WooCommerce order - status changes, sync events, and edits, with the user who caused each change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.activity-log"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 88213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WooCommerceOrder\",\n      \"subject_id\": 4512,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"completed\"\n        },\n        \"old\": {\n          \"status\": \"processing\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:25:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/woo-commerce/1/orders/4512/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/woo-commerce/1/orders/4512/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/woo-commerce/1/orders/4512/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/woo-commerce/1/orders/4512/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 6\n}"}]},{"name":"Get Order Notes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/notes","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","notes"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Fetch the notes for a single order live from the WooCommerce store - both system status notes and customer-facing notes. The response is the raw WooCommerce order notes payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.notes"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/notes","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","notes"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 281,\n      \"author\": \"system\",\n      \"date_created\": \"2026-06-14T09:21:35\",\n      \"date_created_gmt\": \"2026-06-14T09:21:35\",\n      \"note\": \"Order status changed from Pending payment to Processing.\",\n      \"customer_note\": false\n    },\n    {\n      \"id\": 282,\n      \"author\": \"store-admin\",\n      \"date_created\": \"2026-06-15T08:00:12\",\n      \"date_created_gmt\": \"2026-06-15T08:00:12\",\n      \"note\": \"Shipped via UPS Ground, tracking emailed to customer.\",\n      \"customer_note\": true\n    }\n  ]\n}"}]},{"name":"Get Raw Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Fetch the raw order payload for a single order directly from the WooCommerce REST API (live request, not the locally cached copy).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.raw"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order\": {\n      \"id\": 1189,\n      \"number\": \"1189\",\n      \"status\": \"processing\",\n      \"currency\": \"USD\",\n      \"total\": \"49.98\",\n      \"total_tax\": \"4.12\",\n      \"date_created_gmt\": \"2026-06-14T09:21:33\",\n      \"date_modified_gmt\": \"2026-06-15T10:02:11\",\n      \"billing\": {\n        \"first_name\": \"Jane\",\n        \"last_name\": \"Smith\",\n        \"email\": \"jane@example.com\"\n      },\n      \"line_items\": [\n        {\n          \"id\": 77,\n          \"name\": \"Stainless Water Bottle 750ml\",\n          \"product_id\": 42,\n          \"sku\": \"WB-750-SS\",\n          \"quantity\": 2,\n          \"price\": 24.99,\n          \"total\": \"49.98\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Delete Linked SKU.io Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]},"description":"Delete the SKU.io sales order linked to a WooCommerce order, keeping the WooCommerce order record intact. Pass `archive_order=true` to also archive the WooCommerce order afterwards.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.delete-sku-order"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"order","value":"4512","description":"Local WooCommerce order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully and WooCommerce order archived\",\n  \"archived_order\": true\n}"}]},{"name":"Bulk Delete Linked SKU.io Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Delete the SKU.io sales orders linked to the given WooCommerce orders, keeping the WooCommerce order records intact. Set `archive_orders` to true to also archive the WooCommerce orders after their linked sales orders are removed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.bulk-delete-sku-orders","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ],\n  \"archive_orders\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 SKU order(s) deleted successfully and WooCommerce orders archived\",\n  \"deleted_count\": 2\n}"}]},{"name":"Bulk Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Permanently delete multiple local WooCommerce order records by their local IDs. This removes the local copies only - orders in the WooCommerce store are not affected. Linked SKU.io sales orders are not deleted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.orders.bulk-delete","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    4512,\n    4513\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 order(s) deleted successfully\",\n  \"deleted_count\": 2\n}"}]},{"name":"List Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Earliest order creation date (must be before the inventory start date).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Query the WooCommerce store live for orders created before your SKU.io inventory start date, so historical orders can be selectively imported without affecting inventory.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach returned order carries an `eligible` flag with an `eligibility_reason` (cancelled, refunded, failed, and trashed orders are not eligible) and an `already_imported` flag for orders that already exist locally.\n\nBoth dates must be before the inventory start date. Returns up to 1,000 matching orders per query.\n\nRoute name: woo-commerce.pre-start-date-orders.query"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Earliest order creation date (must be before the inventory start date).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"woo_commerce_order_id\": 1189,\n      \"name\": \"#1189\",\n      \"email\": \"jane@example.com\",\n      \"created_at\": \"2025-11-03T15:22:10\",\n      \"status\": \"completed\",\n      \"total_price\": \"49.98\",\n      \"currency\": \"USD\",\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Water Bottle 750ml\",\n          \"sku\": \"WB-750-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"24.99\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Search Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=1189","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. Field to search by: order_number, order_id, or email.","disabled":true},{"key":"search_term","value":"1189","description":"Required. Value to search for (max 255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Search the WooCommerce store for specific pre-start-date orders by order number, order ID, or customer email. Returns the same response format as the list endpoint, including eligibility and already-imported flags.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.pre-start-date-orders.search"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders/search?search_by=order_number&search_term=1189","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_number","description":"Required. Field to search by: order_number, order_id, or email.","disabled":true},{"key":"search_term","value":"1189","description":"Required. Value to search for (max 255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"woo_commerce_order_id\": 1189,\n      \"name\": \"#1189\",\n      \"email\": \"jane@example.com\",\n      \"created_at\": \"2025-11-03T15:22:10\",\n      \"status\": \"completed\",\n      \"total_price\": \"49.98\",\n      \"currency\": \"USD\",\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Water Bottle 750ml\",\n          \"sku\": \"WB-750-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": \"24.99\",\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Import selected pre-start-date orders from WooCommerce by their WooCommerce order IDs. Full order data is downloaded and stored flagged as a pre-start-date import so it does not affect inventory. Orders that already exist locally are marked instead of duplicated, and cancelled orders are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBecause each order is fetched individually from WooCommerce, the import runs asynchronously as a queued background job. The request returns immediately with a tracked job log id that can be polled to follow the import's progress.\n\n**Requires the inventory start date to be set** — returns 422 otherwise.\n\n**Path Parameters:**\n- `integrationInstance` - The WooCommerce integration instance ID\n\n**Request Body:**\n- `woo_commerce_order_ids` (required, array of integers, 1-10,000 entries) — WooCommerce order IDs to import.\n\n**Response:**\n- `data.tracked_job_log_id` - id of the tracked job log; poll it to follow import progress\n- `message` - human-readable confirmation of how many orders are being imported\n\nRoute name: woo-commerce.pre-start-date-orders.import","body":{"mode":"raw","raw":"{\n  \"woo_commerce_order_ids\": [\n    1189,\n    1190\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Importing 2 pre-start-date orders.\"\n}"}]},{"name":"Search WooCommerce Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/search-woocommerce","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","search-woocommerce"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Search products on the remote WooCommerce store. Used by the Refresh modal's Search Specific Product tab to locate a product and offer a one-click download.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- search_by (string, required): One of sku, title, product_id.\n- query (string, required): Search term, max 255 chars.\n\nRoute name: woo-commerce.products.search-woocommerce","body":{"mode":"raw","raw":"{\n  \"search_by\": \"sku\",\n  \"query\": \"ACME-001\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/search-woocommerce","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","search-woocommerce"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"42\",\n      \"productId\": \"42\",\n      \"title\": \"Acme Widget\",\n      \"sku\": \"ACME-001\",\n      \"status\": \"publish\",\n      \"existsInDatabase\": true,\n      \"databaseId\": 17,\n      \"variantCount\": 3\n    }\n  ]\n}"}]},{"name":"Refresh Single Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/refresh-product","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","refresh-product"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Fetch a single product (and its variations) from WooCommerce and persist it locally. Used by the Refresh modal's Search Specific Product tab download button.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- product_id (string, required): WooCommerce parent product ID.\n\nRoute name: woo-commerce.products.refresh-product","body":{"mode":"raw","raw":"{\n  \"product_id\": \"42\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/refresh-product","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","refresh-product"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product refreshed successfully.\"\n}"}]},{"name":"Get WooCommerce Products Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","latest-sync-info"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Return summary information about the locally-cached WooCommerce products for a single integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed by the Refresh Products modal on the application UI listings page to display the latest synced product title, last sync date, and mapping counts.\n\nRoute name: woo-commerce.products.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","products","latest-sync-info"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Acme Widget - Blue\",\n    \"latest_product_date\": \"2026-05-24T14:32:11.000000Z\",\n    \"total_products\": 1245,\n    \"mapped_products\": 1100,\n    \"unmapped_products\": 145\n  }\n}"}]},{"name":"Map Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]},"description":"Map a WooCommerce product to an existing SKU.io product by creating (or updating) its product listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAfter mapping, a background job is dispatched to link any unmapped sales order lines that match the new listing.\n\nRoute name: woo-commerce.products.map-single","body":{"mode":"raw","raw":"{\n  \"product_id\": 55\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"woo_commerce_parent_product_id\": 42,\n    \"woo_commerce_product_id\": 42,\n    \"woo_commerce_variation_id\": 0,\n    \"woo_commerce_unique_id\": 42,\n    \"parent_product_name\": \"Stainless Water Bottle\",\n    \"parent_sku\": \"WB-750\",\n    \"variation_name\": null,\n    \"unified_title\": \"Stainless Water Bottle 750ml\",\n    \"sku\": \"WB-750-SS\",\n    \"price\": 24.95,\n    \"regular_price\": 24.95,\n    \"sale_price\": null,\n    \"manage_stock\": true,\n    \"stock_quantity\": 132,\n    \"stock_status\": \"instock\",\n    \"product_type\": \"simple\",\n    \"status\": \"publish\",\n    \"image_url\": \"https://store.example.com/wp-content/uploads/wb-750.jpg\",\n    \"product_listing_id\": 977,\n    \"product\": {\n      \"id\": 55,\n      \"name\": \"Stainless Water Bottle 750ml\",\n      \"sku\": \"WB-750-SS\",\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 977\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"mapped_sku\": \"WB-750-SS\",\n    \"created_at\": \"2026-02-11T08:30:00.000000Z\",\n    \"updated_at\": \"2026-07-01T09:00:00.000000Z\"\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]},"description":"Remove the mapping between a WooCommerce product and its SKU.io product by deleting the product listing. The WooCommerce product and the SKU.io product both remain.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.products.unmap-single"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 231,\n    \"integration_instance_id\": 1,\n    \"woo_commerce_parent_product_id\": 42,\n    \"woo_commerce_product_id\": 42,\n    \"woo_commerce_variation_id\": 0,\n    \"woo_commerce_unique_id\": 42,\n    \"parent_product_name\": \"Stainless Water Bottle\",\n    \"parent_sku\": \"WB-750\",\n    \"variation_name\": null,\n    \"unified_title\": \"Stainless Water Bottle 750ml\",\n    \"sku\": \"WB-750-SS\",\n    \"price\": 24.95,\n    \"regular_price\": 24.95,\n    \"sale_price\": null,\n    \"manage_stock\": true,\n    \"stock_quantity\": 132,\n    \"stock_status\": \"instock\",\n    \"product_type\": \"simple\",\n    \"status\": \"publish\",\n    \"image_url\": \"https://store.example.com/wp-content/uploads/wb-750.jpg\",\n    \"product_listing_id\": null,\n    \"product\": null,\n    \"subscription_offering\": null,\n    \"mapped_at\": null,\n    \"mapped_sku\": null,\n    \"created_at\": \"2026-02-11T08:30:00.000000Z\",\n    \"updated_at\": \"2026-07-01T09:00:00.000000Z\"\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"List Orders for Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]},"description":"Get a paginated list of WooCommerce orders that contain a given product, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.products.orders"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"product","value":"231","description":"Local WooCommerce product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4512,\n      \"integration_instance_id\": 1,\n      \"woo_commerce_id\": \"1189\",\n      \"number\": \"1189\",\n      \"status\": \"processing\",\n      \"currency\": \"USD\",\n      \"total\": \"49.98\",\n      \"total_tax\": \"4.12\",\n      \"date_created_gmt\": \"2026-06-14T09:21:33.000000Z\",\n      \"date_modified_gmt\": \"2026-06-15T10:02:11.000000Z\",\n      \"date_completed_gmt\": null,\n      \"pre_start_date_import\": false,\n      \"archived_at\": null,\n      \"sku_sales_order\": {\n        \"id\": 887,\n        \"number\": \"SO-1042\",\n        \"order_status\": \"PROCESSING\",\n        \"fulfillment_status\": \"UNFULFILLED\",\n        \"payment_status\": \"PAID\"\n      },\n      \"last_synced_at\": \"2026-06-15T10:02:11+00:00\",\n      \"created_at\": \"2026-06-14T09:22:00.000000Z\",\n      \"updated_at\": \"2026-06-15T10:02:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 10,\n  \"total\": 14,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get the product field mappings for a WooCommerce integration instance - which WooCommerce product fields populate which SKU.io product fields when products are created or updated from listings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response includes the default mappings, any custom overrides, the effective (merged) mappings, and the catalog of available fields on both sides.\n\nRoute name: woo-commerce.mappings.show"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My WooCommerce Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: weight to weight\"\n      }\n    ],\n    \"available_woocommerce_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Stock Keeping Unit\",\n        \"group\": \"Identifiers\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Product name/title\",\n        \"group\": \"Product Info\"\n      },\n      \"weight\": {\n        \"name\": \"weight\",\n        \"label\": \"Weight\",\n        \"type\": \"string\",\n        \"description\": \"Product weight\",\n        \"group\": \"Shipping\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Name\",\n        \"type\": \"string\"\n      },\n      \"weight\": {\n        \"name\": \"weight\",\n        \"label\": \"Weight\",\n        \"type\": \"number\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      }\n    ],\n    \"custom_mappings\": [\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: weight to weight\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: weight to weight\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Replace the custom product field mappings for a WooCommerce integration instance. Each mapping pairs a WooCommerce `listing_field` with a SKU.io `sku_field`, with optional `parsers` applied to transform the value. Custom mappings override the defaults for the same field.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.mappings.update","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"weight\",\n      \"sku_field\": \"weight\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My WooCommerce Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: weight to weight\"\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"name\",\n        \"source\": \"default\",\n        \"description\": \"Maps name to name\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": [],\n        \"source\": \"custom\",\n        \"description\": \"Custom mapping: weight to weight\"\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List WooCommerce Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/customers?filter[search]=john&page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","customers"],"query":[{"key":"filter[search]","value":"john","description":"Optional. Search by customer name or email.","disabled":true},{"key":"page","value":"1","description":"Page number for pagination.","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page.","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a paginated list of WooCommerce customers for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Sync WooCommerce Customers","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/customers/sync","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","customers","sync"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Sync customers from WooCommerce for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the count of synced customers and pages fetched."}},{"name":"List Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get a paginated list of fulfilled shipments for sales orders that originated from this WooCommerce store. Each item shows whether it has been submitted to WooCommerce (`sync_status` of submitted or pending).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nText and date filters accept operator suffixes, e.g. `filter[tracking_number.contains]=1Z9` or `filter[fulfilled_at.between]=2026-06-01,2026-06-30`. Text operators: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\n\nAllowed sorts: id, fulfilled_at, created_at, submitted_to_sales_channel_at (default -id).\n\nRoute name: woo-commerce.fulfillments.index"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3120,\n      \"fulfillment_number\": \"F-3120\",\n      \"fulfillment_type\": \"shipment\",\n      \"status\": \"FULFILLED\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"cost\": \"8.45\",\n      \"fulfilled_at\": \"2026-06-18T14:22:05+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-18T14:22:06+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 887,\n        \"sales_order_number\": \"SO-1042\"\n      },\n      \"woocommerce_order\": {\n        \"id\": 4512,\n        \"woo_commerce_id\": \"1189\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 14,\n        \"name\": \"UPS Ground\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/woo-commerce/1/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"{{base_url}}/api/woo-commerce/1/fulfillments?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/woo-commerce/1/fulfillments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/woo-commerce/1/fulfillments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 48\n}"}]},{"name":"List Pending Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get a paginated list of fulfilled shipments that have not yet been submitted to WooCommerce. Pickup fulfillments and fulfillments on cancelled orders are excluded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nText and date filters accept operator suffixes, e.g. `filter[tracking_number.contains]=1Z9`.\n\nAllowed sorts: id, fulfilled_at, created_at, tracking_number (default -created_at).\n\nRoute name: woo-commerce.fulfillments.pending"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3120,\n      \"fulfillment_number\": \"F-3120\",\n      \"fulfillment_type\": \"shipment\",\n      \"status\": \"FULFILLED\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"cost\": \"8.45\",\n      \"fulfilled_at\": \"2026-06-18T14:22:05+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-18T14:22:06+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 887,\n        \"sales_order_number\": \"SO-1042\"\n      },\n      \"woocommerce_order\": {\n        \"id\": 4512,\n        \"woo_commerce_id\": \"1189\"\n      },\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 14,\n        \"name\": \"UPS Ground\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/woo-commerce/1/fulfillments/pending?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{base_url}}/api/woo-commerce/1/fulfillments/pending?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/woo-commerce/1/fulfillments/pending?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/woo-commerce/1/fulfillments/pending\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 3\n}"}]},{"name":"Get Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get the count of fulfillments waiting to be submitted to WooCommerce, plus the automatic sync schedule. Pending fulfillments are submitted automatically every 10 minutes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.fulfillments.stats"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_sync_count\": 3,\n    \"sync_schedule\": {\n      \"interval\": 10,\n      \"unit\": \"minutes\",\n      \"description\": \"Fulfillments are automatically synced every 10 minutes\"\n    }\n  }\n}"}]},{"name":"Submit Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"salesOrderFulfillment","value":"3120","description":"Sales order fulfillment ID"}]},"description":"Submit a single fulfillment to WooCommerce, recording the shipment and its tracking details on the WooCommerce order and marking the order completed according to the store's settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.fulfillments.submit-single","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"salesOrderFulfillment","value":"3120","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"The fulfillment submitted successfully\"\n}"}]},{"name":"Bulk Submit Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Submit multiple fulfillments to WooCommerce by their IDs. The response reports how many were submitted and how many failed, with per-fulfillment error details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.fulfillments.submit-bulk","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3120,\n    3121\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 2,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"2 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"Submit All Pending Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Submit every pending fulfillment for the integration instance to WooCommerce in one call. The response reports how many were submitted and how many failed, with per-fulfillment error details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.fulfillments.submit-all","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 3,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"3 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"List Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get a paginated side-by-side comparison of SKU.io quantities vs WooCommerce quantities, one row per mapped product listing. Each row includes the variance and a status of synced, variance, or needs_recalc.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWooCommerce has no multi-location concept - every row belongs to a single synthetic \"WooCommerce Store\" location whose ID equals the integration instance ID.\n\nText, numeric, and date filters accept operator suffixes, e.g. `filter[sku_quantity.greater_than]=0`, `filter[listing_sku.contains]=WB`, `filter[updated_at.between]=2026-06-01,2026-06-30`.\n\nAllowed sorts: id, sku_quantity, sales_channel_quantity, created_at, updated_at (default -id).\n\nRoute name: woo-commerce.inventory.index"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9021,\n      \"product_listing_id\": 977,\n      \"document_id\": 231,\n      \"listing_sku\": \"WB-750-SS\",\n      \"title\": \"Stainless Water Bottle 750ml\",\n      \"product\": {\n        \"id\": 55,\n        \"sku\": \"WB-750-SS\",\n        \"name\": \"Stainless Water Bottle 750ml\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"1\",\n      \"location_name\": \"WooCommerce Store\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 132,\n      \"sales_channel_quantity\": 128,\n      \"variance\": 4,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-20T04:05:31+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-20T04:05:32+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-19T04:05:30+00:00\",\n      \"created_at\": \"2026-02-11T08:30:00+00:00\",\n      \"updated_at\": \"2026-06-20T04:05:32+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{base_url}}/api/woo-commerce/1/inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 48,\n  \"last_page_url\": \"{{base_url}}/api/woo-commerce/1/inventory?page=48\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{base_url}}/api/woo-commerce/1/inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{base_url}}/api/woo-commerce/1/inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 480\n}"}]},{"name":"Get Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get aggregate inventory sync statistics for the integration instance: total product rows, how many are in sync, how many have a variance, how many need recalculation, and the timestamps of the last fetch from WooCommerce and last sync to WooCommerce.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.inventory.summary"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 480,\n    \"in_sync\": 440,\n    \"with_variance\": 32,\n    \"needs_recalculation\": 8,\n    \"last_fetch_at\": \"2026-06-20T04:05:32.000000Z\",\n    \"last_sync_at\": \"2026-06-19T04:05:30.000000Z\"\n  }\n}"}]},{"name":"List Inventory Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Get the inventory locations for the integration instance. WooCommerce has no native location concept, so a single synthetic \"WooCommerce Store\" location is returned whose ID equals the integration instance ID. It is always active.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.inventory.locations"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"WooCommerce Store\",\n      \"is_active\": true\n    }\n  ]\n}"}]},{"name":"Recache Inventory Quantities","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Start a background job that recalculates SKU.io inventory quantities for every product listing mapped to this WooCommerce store. Run this when the comparison shows rows needing recalculation.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the recache progress endpoint to poll for completion.\n\nRoute name: woo-commerce.inventory.recache","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5120\n  }\n}"}]},{"name":"Get Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of an inventory recache job using the `tracked_job_log_id` returned when the job was queued. The response includes the job status, item counts, and completion percentage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.inventory.recache-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5120,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"WooCommerce Inventory Recache\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Sync Inventory to WooCommerce","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Start a background job that pushes SKU.io inventory quantities to the WooCommerce store, updating stock levels on the mapped products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the sync progress endpoint to poll for completion.\n\nRoute name: woo-commerce.inventory.sync","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5121\n  }\n}"}]},{"name":"Get Inventory Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of an inventory sync job using the `tracked_job_log_id` returned when the job was queued. The response includes the job status, item counts, and completion percentage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.inventory.sync-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5120,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"WooCommerce Inventory Sync\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Fetch Live Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]},"description":"Start a background job that downloads the current stock quantities from the WooCommerce store into the local comparison cache, so the comparison reflects the latest store-side values.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job runs asynchronously. Use the returned `tracked_job_log_id` with the live-fetch progress endpoint to poll for completion.\n\nRoute name: woo-commerce.inventory.fetch-live","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetch live inventory job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 5122\n  }\n}"}]},{"name":"Get Live Inventory Fetch Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]},"description":"Poll the progress of a live inventory fetch job using the `tracked_job_log_id` returned when the job was queued. The response includes the job status, item counts, and completion percentage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRoute name: woo-commerce.inventory.fetch-live-progress"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"trackedJobLogId","value":"5120","description":"Tracked job log ID returned when the job was queued"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5120,\n    \"job_type\": \"integration\",\n    \"queue\": \"serial\",\n    \"job_name\": \"WooCommerce Live Inventory Fetch\",\n    \"status\": \"in_progress\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T04:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-20T04:00:00.000000Z\",\n    \"updated_at\": \"2026-06-20T04:01:12.000000Z\",\n    \"results\": null,\n    \"total_items\": 480,\n    \"processed_items\": 120,\n    \"progress_percentage\": 25,\n    \"progress_mode\": \"batch\",\n    \"stages\": null\n  }\n}"}]},{"name":"Get Webhook Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{id}/webhooks/configurations","host":["{{baseUrl}}"],"path":["api","woo-commerce",":id","webhooks","configurations"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get all webhook configurations for the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the registration status (enabled/disabled) for each WooCommerce webhook topic."}},{"name":"Enable Webhook","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/webhooks/configurations/{topic}/enable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","webhooks","configurations",":topic","enable"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"topic","value":"order---created","description":"Webhook topic with dots encoded as triple dashes: order.created -> order---created, order.updated -> order---updated, product.created -> product---created, product.updated -> product---updated."}]},"description":"Enable a webhook for a specific WooCommerce topic. The webhook is registered on the WooCommerce store so the store notifies SKU.io when the topic fires. Enabling a webhook never deletes or resets existing synced data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe topic in the URL uses triple-dashes (---) in place of dots to be URL-safe.\nExamples:\n- order.created -> order---created\n- order.updated -> order---updated\n- product.created -> product---created\n- product.updated -> product---updated\n\nRoute name: woo-commerce.webhooks.configurations.enable"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/webhooks/configurations/{topic}/enable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","webhooks","configurations",":topic","enable"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"topic","value":"order---created","description":"Webhook topic with dots encoded as triple dashes: order.created -> order---created, order.updated -> order---updated, product.created -> product---created, product.updated -> product---updated."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook enabled successfully\",\n    \"topic\": \"order.created\",\n    \"wc_webhook_id\": \"812\"\n  },\n  \"message\": \"Webhook enabled successfully\",\n  \"status\": \"Success\"\n}"}]},{"name":"Disable Webhook","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/webhooks/configurations/{topic}/disable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","webhooks","configurations",":topic","disable"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"topic","value":"order---created","description":"Webhook topic with dots encoded as triple dashes: order.created -> order---created, order.updated -> order---updated, product.created -> product---created, product.updated -> product---updated."}]},"description":"Disable a webhook for a specific WooCommerce topic. The webhook is deleted from the WooCommerce store, so the store stops notifying SKU.io for that topic. Previously synced data is unaffected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe topic in the URL uses triple-dashes (---) in place of dots. See Enable Webhook for the encoding pattern.\n\nRoute name: woo-commerce.webhooks.configurations.disable"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/woo-commerce/{integrationInstance}/webhooks/configurations/{topic}/disable","host":["{{baseUrl}}"],"path":["api","woo-commerce",":integrationInstance","webhooks","configurations",":topic","disable"],"variable":[{"key":"integrationInstance","value":"1","description":"WooCommerce integration instance ID"},{"key":"topic","value":"order---created","description":"Webhook topic with dots encoded as triple dashes: order.created -> order---created, order.updated -> order---updated, product.created -> product---created, product.updated -> product---updated."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook disabled successfully\",\n    \"topic\": \"order.created\"\n  },\n  \"message\": \"Webhook disabled successfully\",\n  \"status\": \"Success\"\n}"}]},{"name":"Order Created Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/order.created","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","order.created"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when a new order is created.\n\nRequires WooCommerce webhook signature verification (VerifyWooCommerceWebhook middleware).\nDispatches a background job for async processing.\n\nRoute name: woocommerce.order_created","body":{"mode":"raw","raw":"{\n  \"id\": 1234,\n  \"status\": \"processing\",\n  \"total\": \"49.99\",\n  \"currency\": \"USD\",\n  \"line_items\": [\n    {\n      \"id\": 1,\n      \"product_id\": 500,\n      \"quantity\": 2,\n      \"price\": \"24.99\"\n    }\n  ],\n  \"billing\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"email\": \"john.doe@example.com\"\n  }\n}","options":{"raw":{"language":"json"}}}}},{"name":"Order Updated Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/order.updated","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","order.updated"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when an order is updated.\n\nRoute name: woocommerce.order_updated","body":{"mode":"raw","raw":"{\n  \"id\": 1234,\n  \"status\": \"completed\",\n  \"total\": \"49.99\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Order Deleted Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/order.deleted","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","order.deleted"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when an order is deleted.\n\nRoute name: woocommerce.order_deleted","body":{"mode":"raw","raw":"{\n  \"id\": 1234,\n  \"status\": \"trash\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Product Created Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/product.created","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","product.created"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when a product is created.\n\nRoute name: woocommerce.product_created","body":{"mode":"raw","raw":"{\n  \"id\": 500,\n  \"name\": \"Sample Product\",\n  \"sku\": \"SKU-001\",\n  \"status\": \"publish\",\n  \"type\": \"simple\",\n  \"price\": \"29.99\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Product Updated Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/product.updated","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","product.updated"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when a product is updated.\n\nRoute name: woocommerce.product_updated","body":{"mode":"raw","raw":"{\n  \"id\": 500,\n  \"name\": \"Updated Product\",\n  \"sku\": \"SKU-001\",\n  \"price\": \"34.99\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Product Deleted Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/wc-webhook/{id}/product.deleted","host":["{{baseUrl}}"],"path":["api","webhooks","wc-webhook",":id","product.deleted"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Inbound webhook endpoint called by WooCommerce when a product is deleted.\n\nRoute name: woocommerce.product_deleted","body":{"mode":"raw","raw":"{\n  \"id\": 500,\n  \"name\": \"Deleted Product\",\n  \"sku\": \"SKU-001\",\n  \"status\": \"trash\"\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Walmart","item":[{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart","host":["{{baseUrl}}"],"path":["api","walmart"]},"description":"List all Walmart integration instances (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- search: string — full-text search\n- sort: string — column name (prefix with - for descending, e.g. -created_at)\n- limit: integer — records per page (default 10)\n- page: integer — page number\n- archived: 0|1 — include archived instances (default 0)\n- included[]: JSON-encoded array of additional columns to include\n- excluded[]: JSON-encoded array of columns to exclude\n- table_specifications: 1 — return only table column specifications"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart","host":["{{baseUrl}}"],"path":["api","walmart"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_id\": 7,\n      \"name\": \"My Walmart Marketplace\",\n      \"connection_status\": \"connected\",\n      \"is_automatic_sync_enabled\": true,\n      \"integration_settings\": {\n        \"start_date\": \"2024-01-01\",\n        \"store_id\": 1,\n        \"auto_link_products\": true,\n        \"auto_create_products\": false\n      },\n      \"created_at\": \"2024-01-15T00:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T00:00:00.000000Z\",\n      \"integration_name\": \"Walmart\",\n      \"store\": {\n        \"id\": 1,\n        \"name\": \"Main Store\"\n      }\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart","host":["{{baseUrl}}"],"path":["api","walmart"]},"description":"Create a new Walmart integration instance. After creation, automatically fetches an access token, dispatches jobs to download locations, and refresh products and orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, unique): Human-readable name for this integration instance\n- integration_id (required, integer): ID of the Walmart integration type\n- environment (optional, string): Walmart environment — `sandbox` or `production`. Ignored on production servers (always forced to `production`). Defaults to `sandbox` on non-production servers. **Immutable after creation** — OAuth credentials are bound to the issuing environment. To switch, delete and recreate the instance.\n- connection_settings.clientId (optional, string): Walmart API client ID\n- connection_settings.clientSecret (optional, string): Walmart API client secret\n- integration_settings.start_date (required, string): Date to start syncing orders/products from (YYYY-MM-DD)\n- integration_settings.store_id (required, integer): Internal store ID to associate with\n- integration_settings.auto_link_products (required, boolean): Automatically link Walmart products to SKU products\n- integration_settings.auto_create_products (required, boolean): Automatically create SKU products from Walmart products\n- integration_settings.sales_nominal_code_id (nullable, integer): Nominal code ID for sales accounting\n- integration_settings.cogs_nominal_code_id (nullable, integer): Nominal code ID for cost of goods sold\n- integration_settings.shipping_revenue_nominal_code_id (nullable, integer): Nominal code ID for shipping revenue\n- integration_settings.shipping_refund_nominal_code_id (nullable, integer): Nominal code ID for shipping refunds\n- integration_settings.sales_returns_allowances_nominal_code_id (nullable, integer): Nominal code ID for returns\n- integration_settings.sync_sales_order_invoices_to_accounting (boolean, default true): Sync invoices to accounting\n- integration_settings.sync_sales_credit_to_accounting (boolean, default true): Sync credits to accounting\n- integration_settings.proforma_marketplace_cost_percentage (nullable, float): Marketplace cost percentage\n- integration_settings.proforma_payment_cost_percentage (nullable, float): Payment cost percentage\n- integration_settings.batch_period_sales_order_fulfillments (nullable, string): Batch period override for fulfillments\n- integration_settings.batch_period_customer_returns (nullable, string): Batch period override for customer returns\n- is_automatic_sync_enabled (boolean, default false): Enable automatic synchronization","body":{"mode":"raw","raw":"{\n  \"name\": \"My Walmart Marketplace\",\n  \"integration_id\": 7,\n  \"environment\": \"sandbox\",\n  \"connection_settings\": {\n    \"clientId\": \"your-walmart-client-id\",\n    \"clientSecret\": \"your-walmart-client-secret\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 1,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart","host":["{{baseUrl}}"],"path":["api","walmart"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_id\": 7,\n    \"name\": \"My Walmart Marketplace\",\n    \"environment\": \"sandbox\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-01-15T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T00:00:00.000000Z\"\n  },\n  \"message\": null\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Get a single Walmart integration instance with salesChannel and integration relationships loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_id\": 7,\n    \"name\": \"My Walmart Marketplace\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true,\n    \"integration_settings\": {\n      \"start_date\": \"2024-01-01\",\n      \"store_id\": 1,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false,\n      \"sync_sales_order_invoices_to_accounting\": true,\n      \"sync_sales_credit_to_accounting\": true\n    },\n    \"created_at\": \"2024-01-15T00:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T00:00:00.000000Z\",\n    \"integration_name\": \"Walmart\",\n    \"store\": {\n      \"id\": 1,\n      \"name\": \"Main Store\"\n    }\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Update a Walmart integration instance. Supports both PUT (full update) and PATCH (partial update — merges connection_settings and integration_settings with existing values).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSide effects:\n- If start_date changes, updates the sales channel date\n- If pricing.masterOfPrice changes, dispatches a job to re-cache product listing prices\n- If inventory settings change, invalidates the entire inventory cache\n- If accounting sync settings change, updates related accounting transactions","body":{"mode":"raw","raw":"{\n  \"name\": \"My Walmart Marketplace Updated\",\n  \"integration_settings\": {\n    \"start_date\": \"2024-01-01\",\n    \"store_id\": 1,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false,\n    \"sales_nominal_code_id\": null,\n    \"cogs_nominal_code_id\": null,\n    \"shipping_revenue_nominal_code_id\": null,\n    \"shipping_refund_nominal_code_id\": null,\n    \"sales_returns_allowances_nominal_code_id\": null,\n    \"sync_sales_order_invoices_to_accounting\": true,\n    \"sync_sales_credit_to_accounting\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Walmart Marketplace Updated\",\n    \"is_automatic_sync_enabled\": true,\n    \"updated_at\": \"2024-06-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Partial Update Integration Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Partially update a Walmart integration instance. Settings are deep-merged with existing values — only send the fields you want to change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Walmart Marketplace\",\n    \"is_automatic_sync_enabled\": true,\n    \"updated_at\": \"2024-06-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Delete a Walmart integration instance. Dispatches a background job to clean up associated data asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Store Mapped Warehouse Locations","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","walmart",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]},"description":"Map Walmart ship nodes (locations) to internal warehouses. Updates the warehouse_id for each Walmart location.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- warehouse_mappings (required, array): Array of ship-node-to-warehouse mappings\n- warehouse_mappings.*.shipNode (required, integer): Walmart ship node ID (must exist in walmart_locations)\n- warehouse_mappings.*.warehouse_id (nullable, integer): Internal warehouse ID (must exist in warehouses table, or null to unmap)","body":{"mode":"raw","raw":"{\n  \"warehouse_mappings\": [\n    {\n      \"shipNode\": 1001,\n      \"warehouse_id\": 2\n    },\n    {\n      \"shipNode\": 1002,\n      \"warehouse_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","walmart",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Warehouse mappings updated successfully.\"\n}"}]},{"name":"Download Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integration_instance}/download-locations","host":["{{baseUrl}}"],"path":["api","walmart",":integration_instance","download-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]},"description":"Sync Walmart ship nodes synchronously (runs a background job inline) and return the current list of Walmart locations along with configured inventory locations from the integration settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nErrors:\n- 422: Returned when Walmart credentials are invalid or expired (WalmartReauthorizeException)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integration_instance}/download-locations","host":["{{baseUrl}}"],"path":["api","walmart",":integration_instance","download-locations"],"variable":[{"key":"integration_instance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"walmartLocations\": [\n      {\n        \"id\": 1,\n        \"shipNode\": 1001,\n        \"integration_instance_id\": 1,\n        \"name\": \"East Fulfillment Center\",\n        \"type\": \"SellerOwned\",\n        \"warehouse_id\": 2,\n        \"created_at\": \"2024-01-15T00:00:00.000000Z\"\n      }\n    ],\n    \"inventoryLocations\": [\n      {\n        \"shipNode\": 1001,\n        \"warehouse_id\": 2\n      }\n    ]\n  }\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]},"description":"Get the Walmart OAuth authorization URL for connecting the integration. Note: OAuth support is planned but not yet implemented. Walmart currently uses client ID + client secret authentication.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://marketplace.walmart.com/oauth/authorize?client_id=your-client-id&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fwalmart%2Fcallback\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products?search=&sort=productName&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products"],"query":[{"key":"search","value":"","description":"Search term for product name, SKU, WPID, or UPC","disabled":true},{"key":"sort","value":"productName","description":"Column to sort by (prefix with - for descending, e.g. -productName). Available: id, sku, productName, priceAmount, publishedStatus, lifecycleStatus","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived products: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of additional columns: [\"product\", \"subscription_offering\", \"mapped_at\", \"mapped_sku\", \"json_object\", \"integration_instance_id\", \"product_listing_id\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List Walmart products for a specific integration instance (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nProduct fields include: id, integration_instance_id, mart, sku, condition, wpid, upc, gtin, productName, shelf, productType, priceCurrency, priceAmount, publishedStatus, lifecycleStatus.\n\nAvailable optional columns (via included[]):\n- product: Linked SKU product details (id, name, sku, listing_id)\n- subscription_offering: Linked subscription offering (id, name, sku)\n- mapped_at: Date the product was mapped\n- mapped_sku: SKU of the mapped product\n- json_object: Full raw Walmart product JSON data\n- integration_instance_id: Integration instance ID\n- product_listing_id: Product listing ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products?search=&sort=productName&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products"],"query":[{"key":"search","value":"","description":"Search term for product name, SKU, WPID, or UPC","disabled":true},{"key":"sort","value":"productName","description":"Column to sort by (prefix with - for descending, e.g. -productName). Available: id, sku, productName, priceAmount, publishedStatus, lifecycleStatus","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived products: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of additional columns: [\"product\", \"subscription_offering\", \"mapped_at\", \"mapped_sku\", \"json_object\", \"integration_instance_id\", \"product_listing_id\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 20,\n      \"sku\": \"WMT-WIDGET-L\",\n      \"wpid\": \"AB12CD34EF\",\n      \"upc\": 12345678901,\n      \"gtin\": 12345678901,\n      \"productName\": \"Large Widget\",\n      \"shelf\": \"Electronics\",\n      \"productType\": \"Electronics\",\n      \"priceCurrency\": \"USD\",\n      \"priceAmount\": 39.99,\n      \"publishedStatus\": \"PUBLISHED\",\n      \"lifecycleStatus\": \"ACTIVE\",\n      \"mart\": \"WALMART_US\",\n      \"condition\": \"New\",\n      \"integration_instance_id\": 1,\n      \"product_listing_id\": 75,\n      \"product\": {\n        \"id\": 200,\n        \"name\": \"Large Widget\",\n        \"sku\": \"LW-002\",\n        \"listing_id\": 75\n      },\n      \"mapped_sku\": \"LW-002\",\n      \"mapped_at\": \"2024-03-10T00:00:00.000000Z\",\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-25T00:00:00.000000Z\",\n      \"updated_at\": \"2024-05-15T00:00:00.000000Z\"\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"20","description":"Walmart product ID"}]},"description":"Get a single Walmart product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"20","description":"Walmart product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 20,\n    \"sku\": \"WMT-WIDGET-L\",\n    \"wpid\": \"AB12CD34EF\",\n    \"upc\": 12345678901,\n    \"gtin\": 12345678901,\n    \"productName\": \"Large Widget\",\n    \"shelf\": \"Electronics\",\n    \"productType\": \"Electronics\",\n    \"priceCurrency\": \"USD\",\n    \"priceAmount\": 39.99,\n    \"publishedStatus\": \"PUBLISHED\",\n    \"lifecycleStatus\": \"ACTIVE\",\n    \"mart\": \"WALMART_US\",\n    \"condition\": \"New\",\n    \"integration_instance_id\": 1,\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-25T00:00:00.000000Z\",\n    \"updated_at\": \"2024-05-15T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Create SKU Products from Walmart","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Create SKU.io products from selected Walmart products. Products are created asynchronously via queue.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (array, optional): Array of Walmart product IDs to create SKU products from.\n- create_all_products (boolean, default false): Create SKU products for all Walmart products.\n- mappings (optional, array): Product mapping overrides to persist.\n- filters (optional, object): list view filters to use instead of explicit ids.\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21,\n    22\n  ],\n  \"create_all_products\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be created shortly.\"\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Queue a job to refresh all products from Walmart for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, products will be refreshed shortly.\"\n}"}]},{"name":"Map Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Map Walmart products to SKU.io products. Creates product listings linking Walmart listings to internal products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"sales_channel_listing_id\": \"WMT-WIDGET-L\",\n      \"product_id\": 200\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\",\n  \"message\": null\n}"}]},{"name":"Smart Match Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]},"description":"Find suggested SKU product matches for a single Walmart listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMatching strategy:\n- exact_match: SKU product whose sku == walmart_product.sku\n- barcode_match: SKU product whose barcode == walmart_product.upc (falls back to gtin)\n- similar_matches: up to 5 fuzzy matches by productName / sku tokens\n\nArchived SKU products are excluded. Used by the listing detail page mapping modal.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 200,\n      \"sku\": \"WMT-WIDGET-L\",\n      \"name\": \"Widget Large\",\n      \"barcode\": 12345678905,\n      \"price\": 19.99,\n      \"type\": \"simple\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 201,\n        \"sku\": \"WMT-WIDGET-M\",\n        \"name\": \"Widget Medium\",\n        \"barcode\": 12345678912,\n        \"price\": 14.99,\n        \"type\": \"simple\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Map Single Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]},"description":"Map a single Walmart listing to a SKU product (or subscription offering). Creates a ProductListing record, or updates the existing one if already mapped (remap). After mapping, dispatches a job to map any previously unmapped sales order lines for the new listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields (exactly one of):\n- product_id (integer, required_without:subscription_offering_id): SKU product ID to map to. Must exist in products table.\n- subscription_offering_id (integer, required_without:product_id): Subscription offering ID to map to. Must exist in subscription_offerings table.","body":{"mode":"raw","raw":"{\n  \"product_id\": 200\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"WMT-WIDGET-L\",\n    \"productName\": \"Widget Large\",\n    \"productListing\": {\n      \"id\": 42,\n      \"sales_channel_id\": 7,\n      \"sales_channel_listing_id\": \"WMT-WIDGET-L\",\n      \"product_id\": 200,\n      \"subscription_offering_id\": null\n    }\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Single Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]},"description":"Remove the mapping between a Walmart listing and its SKU product by deleting the ProductListing record. The Walmart product itself is preserved.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 422 if the product is not currently mapped.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"WMT-WIDGET-L\",\n    \"productName\": \"Widget Large\",\n    \"productListing\": null\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Create SKU Product from Walmart Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]},"description":"Create a new SKU product from a Walmart listing's data and map it. If a SKU product with the same SKU already exists, the existing one is linked instead of creating a duplicate (response includes linked_existing=true).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis handles product creation, pricing, and listing.\n\nReturns 422 if the Walmart product is already mapped — unmap it first.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"sku\": \"WMT-WIDGET-L\",\n    \"productName\": \"Widget Large\",\n    \"productListing\": {\n      \"id\": 42,\n      \"product_id\": 200\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Get Raw Product from Walmart","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID (internal)"}]},"description":"Fetch the raw Walmart Marketplace API response for a single item, live from /v3/items/{sku}. Powers the \"Load Raw Data from Walmart\" button on the listing detail page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe data is not persisted — it reflects the live Walmart state. Uses the product's SKU for the upstream API call.\n\nReturns 403 if the product doesn't belong to the given integration instance. Returns 500 if Walmart's API call fails (e.g. credentials missing or SKU not found on Walmart).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"1","description":"Walmart product ID (internal)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"mart\": \"WALMART_US\",\n      \"sku\": \"5290084\",\n      \"wpid\": \"2CB8X1RKNCG4\",\n      \"upc\": \"\",\n      \"gtin\": \"07323450534660\",\n      \"productName\": \"Fjallraven Men's Ovik Fleece Sweater\",\n      \"productType\": \"Sweaters\",\n      \"price\": {\n        \"currency\": \"USD\",\n        \"amount\": 119.99\n      },\n      \"publishedStatus\": \"PUBLISHED\",\n      \"lifecycleStatus\": \"ACTIVE\"\n    }\n  }\n}"}]},{"name":"Export Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter exported products by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Export Walmart products as a CSV or Excel file. Supports the same list view filter parameters as the list endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download (text/csv or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter exported products by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,sku,productName,publishedStatus,priceAmount\n20,WMT-WIDGET-L,Large Widget,PUBLISHED,39.99"}]},{"name":"Sync Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Push current inventory levels to Walmart for the specified products (or all products if ids is omitted). Submits inventory quantities to the Walmart Marketplace API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (optional, array): Array of Walmart product IDs to sync inventory for. If omitted, syncs all products.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21,\n    22\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Archive Walmart products (soft-delete). Products are marked as archived and hidden from default listings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of Walmart product IDs to archive. Must belong to this integration instance.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Unarchive previously archived Walmart products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of Walmart product IDs to unarchive. Must belong to this integration instance.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products archived successfully.\"\n}"}]},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Check which of the given Walmart products can be archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of Walmart product IDs to check.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 20,\n      \"archiveable\": true\n    },\n    {\n      \"id\": 21,\n      \"archiveable\": false,\n      \"reason\": \"Product has pending orders\"\n    }\n  ]\n}"}]},{"name":"Delete Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Permanently delete Walmart products from SKU.io (does not delete from Walmart). Use archiveable endpoint first to check if deletion is safe.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (required, array): Array of Walmart product IDs to delete. Must belong to this integration instance.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    20,\n    21\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Products deleted successfully.\"\n}"}]},{"name":"Import Product Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Import product mapping data from a file (CSV/Excel). Queues a background job to process the mappings asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"file\": \"base64_encoded_csv_content\",\n  \"mapping_type\": \"listings\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, mappings will be imported shortly.\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders?search=&sort=-orderDate&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders"],"query":[{"key":"search","value":"","description":"Search term for order ID, customer name, or purchase order ID","disabled":true},{"key":"sort","value":"-orderDate","description":"Column to sort by (prefix with - for descending). Available: id, customerOrderId, purchaseOrderId, status, orderDate, total","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived orders: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of columns: [\"sku_sales_order\", \"json_object\", \"integration_instance_id\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List Walmart orders for a specific integration instance (list view endpoint).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOrder fields include: id, integration_instance_id, customerOrderId, purchaseOrderId, customerEmailId, customerName, estimatedDeliveryDate, estimatedShipDate, shipNodeType, status, orderDate, currency, total, syncStatus.\n\nAvailable optional columns (via included[]):\n- sku_sales_order: Linked SKU sales order (id, number)\n- json_object: Full raw Walmart order JSON data\n- integration_instance_id: Integration instance ID"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders?search=&sort=-orderDate&limit=10&page=1&archived=0&included=&excluded=","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders"],"query":[{"key":"search","value":"","description":"Search term for order ID, customer name, or purchase order ID","disabled":true},{"key":"sort","value":"-orderDate","description":"Column to sort by (prefix with - for descending). Available: id, customerOrderId, purchaseOrderId, status, orderDate, total","disabled":true},{"key":"limit","value":"10","description":"Records per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"archived","value":"0","description":"Include archived orders: 0 = active only, 1 = archived only","disabled":true},{"key":"included","value":"","description":"JSON-encoded array of columns: [\"sku_sales_order\", \"json_object\", \"integration_instance_id\"]","disabled":true},{"key":"excluded","value":"","description":"JSON-encoded array of columns to exclude","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 60,\n      \"customerOrderId\": \"5000000001234\",\n      \"purchaseOrderId\": \"P0000000001234\",\n      \"customerEmailId\": \"customer@example.com\",\n      \"customerName\": \"John Smith\",\n      \"estimatedDeliveryDate\": \"2024-05-10T00:00:00.000000Z\",\n      \"estimatedShipDate\": \"2024-05-07T00:00:00.000000Z\",\n      \"shipNodeType\": \"SellerOwned\",\n      \"status\": \"Shipped\",\n      \"orderDate\": \"2024-05-05T00:00:00.000000Z\",\n      \"currency\": \"USD\",\n      \"total\": \"49.98\",\n      \"syncStatus\": \"synced\",\n      \"integration_instance_id\": 1,\n      \"sku_sales_order\": {\n        \"id\": 600,\n        \"number\": \"SO-005678\"\n      },\n      \"archived_at\": null,\n      \"created_at\": \"2024-05-05T00:00:00.000000Z\",\n      \"updated_at\": \"2024-05-07T00:00:00.000000Z\"\n    }\n  ],\n  \"total\": 1,\n  \"per_page\": 10,\n  \"current_page\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"Get a single Walmart order with order items loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"customerOrderId\": \"5000000001234\",\n    \"purchaseOrderId\": \"P0000000001234\",\n    \"customerEmailId\": \"customer@example.com\",\n    \"customerName\": \"John Smith\",\n    \"estimatedDeliveryDate\": \"2024-05-10T00:00:00.000000Z\",\n    \"estimatedShipDate\": \"2024-05-07T00:00:00.000000Z\",\n    \"shipNodeType\": \"SellerOwned\",\n    \"status\": \"Shipped\",\n    \"orderDate\": \"2024-05-05T00:00:00.000000Z\",\n    \"currency\": \"USD\",\n    \"total\": \"49.98\",\n    \"syncStatus\": \"synced\",\n    \"integration_instance_id\": 1,\n    \"archived_at\": null,\n    \"orderItems\": [\n      {\n        \"id\": 300,\n        \"walmart_order_id\": 60,\n        \"lineNumber\": \"1\",\n        \"itemName\": \"Large Widget\",\n        \"itemId\": \"WMT-WIDGET-L\",\n        \"status\": \"Shipped\",\n        \"quantity\": 2,\n        \"amount\": \"39.98\"\n      }\n    ]\n  }\n}"}]},{"name":"Create SKU Orders from Walmart","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Create SKU.io sales orders from selected Walmart orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (array, optional): Array of Walmart order IDs to create SKU orders from.\n- create_all_orders (boolean, default false): Create SKU orders for all Walmart orders.\n- filters (optional, object): list view filters to use instead of explicit ids.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    60,\n    61,\n    62\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Sku.io sales orders successfully created\"\n}"}]},{"name":"Update SKU Orders from Walmart","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Update existing SKU.io sales orders from the latest Walmart order data. Useful for syncing status changes (e.g. cancellations, acknowledgements).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- ids (array, optional): Array of Walmart order IDs to update SKU orders from.\n- update_all_orders (boolean, default false): Update all Walmart orders' SKU counterparts.\n- use_jobs (boolean, optional): Process updates via queue jobs instead of synchronously.\n- filters (optional, object): list view filters to use instead of explicit ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    60,\n    61\n  ],\n  \"update_all_orders\": false,\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Sku.io sales orders successfully updated\"\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Queue a job to refresh all orders from Walmart for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Added to queue, orders will be refreshed shortly.\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Refresh a single Walmart order by its unique identifier (customerOrderId). Fetches the latest data from Walmart API and returns the updated order resource.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- uniqueId (required, string): The Walmart customerOrderId (e.g., '5000000001234')","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"5000000001234\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"customerOrderId\": \"5000000001234\",\n    \"purchaseOrderId\": \"P0000000001234\",\n    \"status\": \"Shipped\",\n    \"total\": \"49.98\",\n    \"currency\": \"USD\",\n    \"integration_instance_id\": 1,\n    \"updated_at\": \"2024-05-10T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Export Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Export Walmart orders as a CSV or Excel file.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: Binary file download."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/export?format=csv&search=&archived=0","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv or xlsx","disabled":true},{"key":"search","value":"","description":"Filter by search term","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"id,customerOrderId,purchaseOrderId,status,total,currency\n60,5000000001234,P0000000001234,Shipped,49.98,USD"}]},{"name":"Acknowledge Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/acknowledge","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"Acknowledge a released order to Walmart. Idempotent — orders already past the Created status are left unchanged. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.sync` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/acknowledge","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"customerOrderId\": \"5000000001234\",\n    \"purchaseOrderId\": \"P0000000001234\",\n    \"customerEmailId\": \"customer@example.com\",\n    \"customerName\": \"John Smith\",\n    \"estimatedDeliveryDate\": \"2026-07-20T00:00:00.000000Z\",\n    \"estimatedShipDate\": \"2026-07-17T00:00:00.000000Z\",\n    \"shipNodeType\": \"SellerOwned\",\n    \"status\": \"Acknowledged\",\n    \"orderDate\": \"2026-07-14T00:00:00.000000Z\",\n    \"currency\": \"USD\",\n    \"total\": \"49.98\",\n    \"syncStatus\": \"synced\",\n    \"integration_instance_id\": 1,\n    \"archived_at\": null,\n    \"orderItems\": [\n      {\n        \"id\": 300,\n        \"walmart_order_id\": 60,\n        \"lineNumber\": \"1\",\n        \"itemName\": \"Large Widget\",\n        \"itemId\": \"WMT-WIDGET-L\",\n        \"status\": \"Acknowledged\",\n        \"quantity\": 2,\n        \"amount\": \"39.98\"\n      }\n    ]\n  }\n}"}]},{"name":"Cancel Order Lines","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/cancel-lines","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","cancel-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"Cancel order lines on Walmart (seller-initiated cancellation).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- lines (optional, array): Lines to cancel. When omitted, every line still in a cancellable status (Created or Acknowledged) is cancelled.\n- lines[].lineNumber (required with lines, string): Walmart order line number.\n- lines[].amount (required with lines, integer): Quantity to cancel on that line.\n\nRequires the `sales_orders.cancel` permission.","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"lineNumber\": \"1\",\n      \"amount\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/cancel-lines","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","cancel-lines"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 60,\n    \"customerOrderId\": \"5000000001234\",\n    \"purchaseOrderId\": \"P0000000001234\",\n    \"customerEmailId\": \"customer@example.com\",\n    \"customerName\": \"John Smith\",\n    \"estimatedDeliveryDate\": \"2026-07-20T00:00:00.000000Z\",\n    \"estimatedShipDate\": \"2026-07-17T00:00:00.000000Z\",\n    \"shipNodeType\": \"SellerOwned\",\n    \"status\": \"Cancelled\",\n    \"orderDate\": \"2026-07-14T00:00:00.000000Z\",\n    \"currency\": \"USD\",\n    \"total\": \"49.98\",\n    \"syncStatus\": \"synced\",\n    \"integration_instance_id\": 1,\n    \"archived_at\": null,\n    \"orderItems\": [\n      {\n        \"id\": 300,\n        \"walmart_order_id\": 60,\n        \"lineNumber\": \"1\",\n        \"itemName\": \"Large Widget\",\n        \"itemId\": \"WMT-WIDGET-L\",\n        \"status\": \"Cancelled\",\n        \"quantity\": 2,\n        \"amount\": \"39.98\"\n      }\n    ]\n  }\n}"}]},{"name":"Fulfill Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Submit a fulfillment to Walmart for a given SKU.io sales order fulfillment. Sends shipment/tracking information back to the Walmart Marketplace API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sales_order_fulfillment_id (required, integer): ID of the SKU.io sales order fulfillment to push to Walmart.","body":{"mode":"raw","raw":"{\n  \"sales_order_fulfillment_id\": 456\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Successfully submitted to sales channel.\"\n}"}]},{"name":"List Inbound Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Paginated list of WFS inbound shipments for an integration instance (Spatie QueryBuilder).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters (query string, all optional):\n- filter[search]: global fuzzy search over shipment_id, inbound_order_id, ship_node.\n- Text filters (contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty; bare key = implicit 'is'): shipment_id, inbound_order_id, status, ship_node, carrier_name.\n- Numeric filters (is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty): id, shipment_units, received_units.\n- Datetime filters (is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week/month/year, next_week/month/year, days_ago, days_from_now, past_days, next_days): expected_delivery_date, walmart_created_at, created_at.\nOperator syntax: filter[&lt;column>.&lt;operator>]=value (e.g. filter[shipment_id.contains]=9012).\n\nSorts (sort=&lt;field>, prefix - for descending): id, shipment_id, inbound_order_id, status, ship_node, shipment_units, received_units, line_count, expected_delivery_date, updated_expected_delivery_date, walmart_created_at, created_at. Default sort: -created_at.\n\nPagination: page, per_page (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"inbound_order_id\": \"01J8ZT5K9Q7WFS0000000001\",\n      \"shipment_id\": \"9012345678\",\n      \"status\": \"AWAITING_DELIVERY\",\n      \"can_cancel\": true,\n      \"cancel_blocked_reason\": null,\n      \"ship_node\": \"US-WFS-ATL2\",\n      \"shipment_units\": 120,\n      \"received_units\": 0,\n      \"line_count\": 3,\n      \"has_shortage\": false,\n      \"expected_delivery_date\": \"2026-07-14T00:00:00.000000Z\",\n      \"updated_expected_delivery_date\": null,\n      \"carrier_name\": null,\n      \"tracking_numbers\": null,\n      \"ship_from_address\": {\n        \"name\": \"Main Warehouse\",\n        \"line1\": \"500 Industrial Pkwy\",\n        \"line2\": null,\n        \"city\": \"Dallas\",\n        \"state\": \"TX\",\n        \"postal_code\": \"75201\",\n        \"country\": \"US\"\n      },\n      \"ship_to_address\": {\n        \"name\": \"Atlanta FC\",\n        \"line1\": \"6055 N Bay Dr\",\n        \"line2\": null,\n        \"city\": \"Atlanta\",\n        \"state\": \"GA\",\n        \"postal_code\": \"30336\",\n        \"country\": \"US\"\n      },\n      \"source_warehouse_id\": 7,\n      \"source_supplier_id\": null,\n      \"source_type\": \"warehouse\",\n      \"source_name\": \"Main Warehouse\",\n      \"source_link_status\": \"confirmed\",\n      \"source_blocks_flows\": false,\n      \"walmart_created_at\": \"2026-07-03T15:22:41.000000Z\",\n      \"created_at\": \"2026-07-03T15:22:40.000000Z\",\n      \"created_by_user_id\": 5,\n      \"created_by\": \"Jane Operator\"\n    },\n    {\n      \"id\": 41,\n      \"inbound_order_id\": \"01J8ZT5K9Q7WFS0000000000\",\n      \"shipment_id\": \"9012345600\",\n      \"status\": \"RECEIVED\",\n      \"can_cancel\": false,\n      \"cancel_blocked_reason\": \"This shipment has already been received by Walmart, so it can no longer be cancelled.\",\n      \"ship_node\": \"US-WFS-DFW9\",\n      \"shipment_units\": 60,\n      \"received_units\": 58,\n      \"line_count\": 2,\n      \"has_shortage\": true,\n      \"expected_delivery_date\": \"2026-07-14T00:00:00.000000Z\",\n      \"updated_expected_delivery_date\": null,\n      \"carrier_name\": \"UPS\",\n      \"tracking_numbers\": [\n        \"1Z999AA10123456784\"\n      ],\n      \"ship_from_address\": {\n        \"name\": \"Main Warehouse\",\n        \"line1\": \"500 Industrial Pkwy\",\n        \"line2\": null,\n        \"city\": \"Dallas\",\n        \"state\": \"TX\",\n        \"postal_code\": \"75201\",\n        \"country\": \"US\"\n      },\n      \"ship_to_address\": {\n        \"name\": \"Atlanta FC\",\n        \"line1\": \"6055 N Bay Dr\",\n        \"line2\": null,\n        \"city\": \"Atlanta\",\n        \"state\": \"GA\",\n        \"postal_code\": \"30336\",\n        \"country\": \"US\"\n      },\n      \"source_warehouse_id\": null,\n      \"source_supplier_id\": 15,\n      \"source_type\": \"supplier\",\n      \"source_name\": \"Acme Supply Co.\",\n      \"source_link_status\": \"auto\",\n      \"source_blocks_flows\": false,\n      \"walmart_created_at\": \"2026-07-03T15:22:41.000000Z\",\n      \"created_at\": \"2026-07-03T15:22:40.000000Z\",\n      \"created_by_user_id\": 5,\n      \"created_by\": \"Jane Operator\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Create WFS Inbound Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Create a WFS inbound shipment from SKU.io — send the chosen SKUs/quantities into Walmart Fulfillment Services from a **warehouse OR a supplier** (exactly one). SKU.io enriches each SKU with the GTIN/UPC + description Walmart requires, generates a unique inboundOrderId, builds Walmart's Create-Inbound-Shipment-Order payload (returnAddress from the chosen warehouse's or supplier's address + orderItems), POSTs it to Walmart (POST /v3/fulfillment/inbound-shipments), and persists the shipment(s) Walmart returns — Walmart may split one inbound order across fulfillment centers, so `data` is an array. Typically driven from the inbound builder or the WFS Replenishment grid's cart (\"Send to WFS\").\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- source_warehouse_id (integer) — the warehouse the stock ships from. Required unless source_supplier_id is given.\n- source_supplier_id (integer) — the supplier the stock ships from (drop-ship into WFS). Required unless source_warehouse_id is given. Send exactly one of the two.\n- items (required, array, min 1) — each: { sku (required string), quantity (required integer >= 1) }.\n- items[].packing_type (optional, 'individual' | 'case_packed', default 'individual') — Seller Center's \"Packing setup\". Individual: each outer box holds one sellable unit. Case-packed: master cases of N units.\n- items[].units_per_case (optional, integer >= 1, default 1) — sellable units per master case (Walmart's innerPackQty). Only meaningful for case_packed; quantity MUST divide evenly into cases (422 otherwise). SKU.io maps vendorPackQty = quantity / units_per_case (the case count).\n- items[].prep_services (optional, array of 'LABEL' | 'BAG') — WFS Prep Services Walmart performs on receipt, sent as the order item's addOnServices. LABEL = item labeling ($0.45/unit), BAG = poly bagging ($0.60/unit) — billed by Walmart off its fixed rate card (the API carries no price field). Omit (or send []) for \"Do it myself\". Prep and packing are LOCKED once the IO is submitted — changing them means cancelling and recreating the inbound.\n- items[].kit_fulfillment_mode (optional): for kit/bundle SKUs — 'kit_stock' (ship pre-built) or 'components' (assemble from components at the source; the build is deferred until the 3PL confirms 'Kits Built').\n- expected_delivery_date (optional, date Y-m-d, must be today or later) — when the stock is expected to reach Walmart's fulfillment center. Walmart requires a non-null estimate; when omitted SKU.io defaults it to 7 days out and Walmart revises it on receipt.\n\nNotes on the Walmart payload SKU.io builds: returnAddress.countryCode is sent as a 2-letter uppercase code (e.g. US), and per Walmart each item's itemQty must equal vendorPackQty × innerPackQty — individually packed items ship with innerPackQty 1, case-packed items with innerPackQty = units_per_case.\n\nEach SKU must have a GTIN/UPC; a SKU without one is rejected (422) before any call to Walmart. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"source_warehouse_id\": 8,\n  \"items\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"quantity\": 24,\n      \"packing_type\": \"case_packed\",\n      \"units_per_case\": 6,\n      \"prep_services\": [\n        \"LABEL\",\n        \"BAG\"\n      ]\n    },\n    {\n      \"sku\": \"KIT-1\",\n      \"quantity\": 4,\n      \"kit_fulfillment_mode\": \"components\"\n    }\n  ],\n  \"expected_delivery_date\": \"06/30/2026\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"inbound_order_id\": \"IO-NEW-1\",\n      \"shipment_id\": \"0066618GDM\",\n      \"status\": \"CREATED\",\n      \"can_cancel\": true,\n      \"cancel_blocked_reason\": null,\n      \"ship_node\": \"NJ3\",\n      \"shipment_units\": 30,\n      \"received_units\": 0,\n      \"has_shortage\": false,\n      \"expected_delivery_date\": null,\n      \"updated_expected_delivery_date\": null,\n      \"carrier_name\": \"WFS-FEDEX\",\n      \"tracking_numbers\": null,\n      \"walmart_created_at\": \"2026-06-18T19:02:30.000000Z\",\n      \"created_at\": \"2026-06-18T19:05:00.000000Z\"\n    }\n  ],\n  \"message\": \"WFS inbound shipment created\"\n}"}]},{"name":"Get Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]},"description":"Fetch a single WFS inbound shipment by its SKU.io row id. Eager-loads the source warehouse (with address) and source supplier, so ship_from_address carries the warehouse name and source_name is populated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 404 when the shipment does not belong to the given integration instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"inbound_order_id\": \"01J8ZT5K9Q7WFS0000000001\",\n    \"shipment_id\": \"9012345678\",\n    \"status\": \"AWAITING_DELIVERY\",\n    \"can_cancel\": true,\n    \"cancel_blocked_reason\": null,\n    \"ship_node\": \"US-WFS-ATL2\",\n    \"shipment_units\": 120,\n    \"received_units\": 0,\n    \"line_count\": 3,\n    \"has_shortage\": false,\n    \"expected_delivery_date\": \"2026-07-14T00:00:00.000000Z\",\n    \"updated_expected_delivery_date\": null,\n    \"carrier_name\": null,\n    \"tracking_numbers\": null,\n    \"ship_from_address\": {\n      \"name\": \"Main Warehouse\",\n      \"line1\": \"500 Industrial Pkwy\",\n      \"line2\": null,\n      \"city\": \"Dallas\",\n      \"state\": \"TX\",\n      \"postal_code\": \"75201\",\n      \"country\": \"US\"\n    },\n    \"ship_to_address\": {\n      \"name\": \"Atlanta FC\",\n      \"line1\": \"6055 N Bay Dr\",\n      \"line2\": null,\n      \"city\": \"Atlanta\",\n      \"state\": \"GA\",\n      \"postal_code\": \"30336\",\n      \"country\": \"US\"\n    },\n    \"source_warehouse_id\": 7,\n    \"source_supplier_id\": null,\n    \"source_type\": \"warehouse\",\n    \"source_name\": \"Main Warehouse\",\n    \"source_link_status\": \"confirmed\",\n    \"source_blocks_flows\": false,\n    \"walmart_created_at\": \"2026-07-03T15:22:41.000000Z\",\n    \"created_at\": \"2026-07-03T15:22:40.000000Z\",\n    \"created_by_user_id\": 5,\n    \"created_by\": \"Jane Operator\"\n  }\n}"}]},{"name":"Cancel Inbound Shipment","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]},"description":"Cancel a WFS inbound shipment. This cancels the WHOLE inbound order on Walmart and marks every local shipment sharing that inbound order as CANCELLED (Walmart splits one inbound order across FCs, and cancel is order-level). Any materialized source document (Warehouse Transfer / Purchase Order) is unwound first, and source-stock reservations are released so the stock is sellable again. Walmart rejects the cancel once the shipment is receiving, closed, or already cancelled.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 200 on success, 404 when the shipment does not belong to the instance, and 422 when Walmart rejects the cancel or the shipment has no inbound order id on file."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"WFS inbound shipment cancelled\"\n}"}]},{"name":"Preview WFS Inbound Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Preview an inbound order before creating it — returns Walmart's destination fulfillment-center placement plus estimated transfer charges, without persisting anything. Takes the SAME request body as Create WFS Inbound Shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- source_warehouse_id (integer) — the warehouse the stock ships from. Required unless source_supplier_id is given.\n- source_supplier_id (integer) — the supplier the stock ships from. Required unless source_warehouse_id is given. Send exactly one of the two.\n- items (required, array, min 1) — each: { sku (required string), quantity (required integer >= 1) }.\n- expected_delivery_date (optional, date Y-m-d, today or later).\n\nValidation errors return 422; a Walmart-side rejection also returns 422 with the failure reason. Requires a Bearer token.\n\nAccepts the same body as Create WFS Inbound Shipment, including the per-item packing_type / units_per_case / prep_services fields (see that endpoint for field semantics).","body":{"mode":"raw","raw":"{\n  \"source_warehouse_id\": 8,\n  \"items\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"quantity\": 24,\n      \"packing_type\": \"case_packed\",\n      \"units_per_case\": 6,\n      \"prep_services\": [\n        \"LABEL\",\n        \"BAG\"\n      ]\n    },\n    {\n      \"sku\": \"KIT-1\",\n      \"quantity\": 4,\n      \"kit_fulfillment_mode\": \"components\"\n    }\n  ],\n  \"expected_delivery_date\": \"06/30/2026\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipments\": [\n      {\n        \"ship_node\": \"NJ3\",\n        \"items\": [\n          {\n            \"sku\": \"ABC-001\",\n            \"quantity\": 20\n          }\n        ]\n      }\n    ],\n    \"estimated_charges\": {\n      \"currency\": \"USD\",\n      \"amount\": 14.5\n    }\n  }\n}"}]},{"name":"Refresh Shipments (Tracked Job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Queue a tracked background job that pulls WFS inbound shipments from Walmart (all pages) and upserts them. Progress is surfaced via the tracked job log endpoints; the response returns the tracked job log id to watch. Takes no request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nJob name: 'Refresh WFS Inbound Shipments: {instance name}'. On completion the job stores results.shipments_synced (count synced).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8842\n  },\n  \"message\": \"WFS inbound shipment refresh started\"\n}"}]},{"name":"Set Source","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/source","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","source"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]},"description":"Set (or confirm) the definitive source of an inbound shipment — a warehouse OR a supplier (exactly one). Used to resolve an imported inbound, confirm an auto-matched one, or re-point an existing one. Unwinds any document already materialized against the old source (throws/blocks if it has already shipped), drops the prior source reservation, marks the link confirmed, and re-reserves against the new warehouse (a no-op when supplier-sourced or when there are no SKU intent lines).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- source_warehouse_id (integer, required without source_supplier_id, prohibits source_supplier_id, exists:warehouses,id): the source warehouse.\n- source_supplier_id (integer, required without source_warehouse_id, exists:suppliers,id): the source supplier.\nProvide exactly one — supplying source_warehouse_id together with source_supplier_id is rejected.\n\nResponse: the updated shipment (single Walmart WFS inbound shipment object). Returns 404 when the shipment does not belong to the instance.","body":{"mode":"raw","raw":"{\n  \"source_warehouse_id\": 7,\n  \"source_supplier_id\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/source","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","source"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WalmartWfsInboundShipment row ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"inbound_order_id\": \"01J8ZT5K9Q7WFS0000000001\",\n    \"shipment_id\": \"9012345678\",\n    \"status\": \"AWAITING_DELIVERY\",\n    \"can_cancel\": true,\n    \"cancel_blocked_reason\": null,\n    \"ship_node\": \"US-WFS-ATL2\",\n    \"shipment_units\": 120,\n    \"received_units\": 0,\n    \"line_count\": 3,\n    \"has_shortage\": false,\n    \"expected_delivery_date\": \"2026-07-14T00:00:00.000000Z\",\n    \"updated_expected_delivery_date\": null,\n    \"carrier_name\": null,\n    \"tracking_numbers\": null,\n    \"ship_from_address\": {\n      \"name\": \"Main Warehouse\",\n      \"line1\": \"500 Industrial Pkwy\",\n      \"line2\": null,\n      \"city\": \"Dallas\",\n      \"state\": \"TX\",\n      \"postal_code\": \"75201\",\n      \"country\": \"US\"\n    },\n    \"ship_to_address\": {\n      \"name\": \"Atlanta FC\",\n      \"line1\": \"6055 N Bay Dr\",\n      \"line2\": null,\n      \"city\": \"Atlanta\",\n      \"state\": \"GA\",\n      \"postal_code\": \"30336\",\n      \"country\": \"US\"\n    },\n    \"source_warehouse_id\": 7,\n    \"source_supplier_id\": null,\n    \"source_type\": \"warehouse\",\n    \"source_name\": \"Main Warehouse\",\n    \"source_link_status\": \"confirmed\",\n    \"source_blocks_flows\": false,\n    \"walmart_created_at\": \"2026-07-03T15:22:41.000000Z\",\n    \"created_at\": \"2026-07-03T15:22:40.000000Z\"\n  }\n}"}]},{"name":"Get Shipment Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/items","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","items"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"The per-SKU items Walmart holds for a shipment (sent vs. received), pulled live from Walmart and enriched with source-warehouse stock context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nEach row has exactly these keys:\n- sku (string|null): the item SKU / vendor SKU.\n- gtin (string|null): the item GTIN, when Walmart returns one.\n- description (string|null): the item description.\n- shipped_qty (number): units sent on this inbound (Walmart's itemQty).\n- received_qty (number): units Walmart has received so far.\n- product_id (number|null): local product id when the SKU matches a SKU.io product (null when unmatched) — lets the UI link to the product page.\n- available_to_sell (number|null): the product's sellable stock at the inbound's SOURCE warehouse, already net of what this inbound reserved. Null when the SKU is unmatched OR the inbound isn't warehouse-sourced (supplier/3PL inbounds reserve nothing).\n- committed_this_inbound (number|null): units this inbound reserved for that product at the source warehouse. Null under the same conditions as available_to_sell.\n\nErrors: 422 with { message } if the live Walmart fetch fails."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/items","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","items"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"WIDGET-BLU-12OZ\",\n      \"gtin\": 810000000012,\n      \"description\": \"Blue Widget 12oz\",\n      \"shipped_qty\": 50,\n      \"received_qty\": 38,\n      \"product_id\": 4821,\n      \"available_to_sell\": 38,\n      \"committed_this_inbound\": 12\n    },\n    {\n      \"sku\": \"UNKNOWN-SKU-99\",\n      \"gtin\": null,\n      \"description\": \"Unrecognized Item\",\n      \"shipped_qty\": 10,\n      \"received_qty\": 0,\n      \"product_id\": null,\n      \"available_to_sell\": null,\n      \"committed_this_inbound\": null\n    }\n  ]\n}"}]},{"name":"List Source Allocations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/allocations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","allocations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"Paginated source-stock reservations (inventory allocations) for this inbound — the source-warehouse reservations created when the inbound was made so the earmarked stock can't be oversold. Scoped to all shipments sharing the inbound order (split inbounds), plus any reservations handed off to a materialized Warehouse Transfer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters:\n- filter[status]: exact allocation status (e.g. allocated, cancelled, fulfilled).\n- filter[warehouse_id]: exact source warehouse id.\n- filter[search]: allocation id (when numeric) or product SKU / name.\n\nSorts (via sort): id, quantity, status, created_at. Prefix with - for descending. Default -id.\n\nPagination: page, per_page (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/allocations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","allocations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"product_id\": 4821,\n      \"product\": {\n        \"id\": 4821,\n        \"sku\": \"WIDGET-BLU-12OZ\",\n        \"name\": \"Blue Widget 12oz\"\n      },\n      \"warehouse_id\": 7,\n      \"warehouse\": {\n        \"id\": 7,\n        \"name\": \"Main Distribution Center\"\n      },\n      \"link_id\": 3312,\n      \"link_type\": \"Modules\\\\Walmart\\\\Entities\\\\WalmartWfsInboundShipment\",\n      \"link_type_label\": \"WalmartWfsInboundShipment\",\n      \"link_route\": null,\n      \"link_reference\": null,\n      \"date\": null,\n      \"quantity\": 12,\n      \"status\": \"allocated\",\n      \"status_label\": \"Allocated\",\n      \"priority\": 0,\n      \"supplier_id\": null,\n      \"purchase_order_line_id\": null,\n      \"is_tight_coverage\": false,\n      \"release_source_id\": null,\n      \"release_source_type\": null,\n      \"fulfilled_at\": null,\n      \"cancelled_at\": null,\n      \"created_at\": \"2026-06-28T14:05:11.000000Z\",\n      \"updated_at\": \"2026-06-28T14:05:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/allocations?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/allocations?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/allocations\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Reconciliation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/reconciliation","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","reconciliation"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"Sent-vs-received reconciliation for this inbound — per-SKU variance + status + the local investigated flag, plus a roll-up summary.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: { data: { summary, rows } }.\n\nsummary keys:\n- total_skus (number): distinct SKUs on the shipment.\n- matched (number): SKUs where received === sent (only once receipt is complete).\n- pending_skus (number): SKUs still mid-receipt / not yet fully received.\n- short_skus (number): SKUs received short (receipt complete only).\n- over_skus (number): SKUs received over.\n- short_units (number): total missing units across short SKUs (absolute value).\n- over_units (number): total surplus units across over SKUs.\n- unresolved (number): discrepant (short/over) SKUs not yet marked resolved.\n- receipt_complete (boolean): whether Walmart has finished receiving (status Received or Closed).\n\nrow keys: sku, description, product_id (number|null), sent, received, variance (received - sent), status (matched | over | short | pending), resolved (boolean — local investigated flag).\n\nErrors: 422 with { message } if reconciliation can't be loaded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/reconciliation","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","reconciliation"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"total_skus\": 2,\n      \"matched\": 1,\n      \"pending_skus\": 0,\n      \"short_skus\": 1,\n      \"over_skus\": 0,\n      \"short_units\": 12,\n      \"over_units\": 0,\n      \"unresolved\": 1,\n      \"receipt_complete\": true\n    },\n    \"rows\": [\n      {\n        \"sku\": \"WIDGET-BLU-12OZ\",\n        \"description\": \"Blue Widget 12oz\",\n        \"product_id\": 4821,\n        \"sent\": 50,\n        \"received\": 38,\n        \"variance\": -12,\n        \"status\": \"short\",\n        \"resolved\": false\n      },\n      {\n        \"sku\": \"WIDGET-RED-12OZ\",\n        \"description\": \"Red Widget 12oz\",\n        \"product_id\": 4822,\n        \"sent\": 25,\n        \"received\": 25,\n        \"variance\": 0,\n        \"status\": \"matched\",\n        \"resolved\": false\n      }\n    ]\n  }\n}"}]},{"name":"Resolve Discrepancy","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/reconciliation/resolve","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","reconciliation","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"Mark a SKU's receive discrepancy on this shipment as investigated/resolved (or reopen it).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- sku (string, required): the SKU whose discrepancy to flag.\n- resolved (boolean, required): true to mark resolved, false to reopen.\n\nResponse: { message } — 'Discrepancy resolved' when resolved is true, 'Discrepancy reopened' when false.","body":{"mode":"raw","raw":"{\n  \"sku\": \"WIDGET-BLU-12OZ\",\n  \"resolved\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/reconciliation/resolve","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","reconciliation","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Discrepancy resolved\"\n}"}]},{"name":"Get WFS Inbound Shipment Errors","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/errors","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","errors"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"The errors Walmart recorded against an inbound shipment (why an item or order was rejected), pulled live from Walmart. Scoped to the integration instance (404 if the shipment belongs to another instance). A Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/errors","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","errors"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"ABC-009\",\n      \"error_code\": \"GTIN_MISSING\",\n      \"description\": \"Item is missing a GTIN/UPC required by WFS.\"\n    }\n  ]\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"Paginated activity log for this inbound shipment (newest first).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters:\n- filter[event]: activity event — created | updated | deleted | bulk_upsert.\n- filter[source]: properties->source (manual | amazon_sync | inventory_allocation | ...).\n- filter[batch_uuid]: filter by batch uuid.\n- filter[search]: matches causer name, properties, or event.\n\nPagination: page, per_page (default 15).\n\nEach row: id, description, event, subject_type (class basename), subject_id, properties (object), causer_name (string|null), created_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55231,\n      \"description\": \"WFS inbound source set to Main Distribution Center\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WalmartWfsInboundShipment\",\n      \"subject_id\": 3312,\n      \"properties\": {\n        \"source\": \"manual\",\n        \"attributes\": {\n          \"source_warehouse_id\": 7\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-06-28T14:05:11.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/activity-log?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/walmart/1/wfs/inbound-shipments/1000012345/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Placement Preview","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/placement-preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","placement-preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]},"description":"Estimate the destination-FC placement + transfer charges for an existing shipment by re-running Walmart's inbound preview from its current items + source. This is an estimate — Walmart exposes no billed charges per existing order; actual charges live in Walmart Seller Center.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: { data: { total_charge (number), currency (string), placements: [ ... ] } }.\n\nEach placement: fc_name (string|null), ship_node (string|null), node_type (string|null), charge (number), currency (string), items: [ { sku (string|null), quantity (number), charge (number) } ].\n\nErrors: 422 with { message } — e.g. when Walmart hasn't reported items for the shipment yet, or the preview call fails."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/placement-preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","placement-preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"1000012345","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_charge\": 42.75,\n    \"currency\": \"USD\",\n    \"placements\": [\n      {\n        \"fc_name\": \"Bethlehem, PA (WFS)\",\n        \"ship_node\": \"10000045\",\n        \"node_type\": \"WFS\",\n        \"charge\": 42.75,\n        \"currency\": \"USD\",\n        \"items\": [\n          {\n            \"sku\": \"WIDGET-BLU-12OZ\",\n            \"quantity\": 50,\n            \"charge\": 28.5\n          },\n          {\n            \"sku\": \"WIDGET-RED-12OZ\",\n            \"quantity\": 25,\n            \"charge\": 14.25\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Get 3PL Turnaround Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","3pl-metrics"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"3PL/supplier turnaround SLA metrics: per-partner turnaround gaps between sending a WFS-inbound fulfilment request and each milestone (sent → box contents submitted, sent → ready to ship), plus an overall summary. Derived from packet timestamps + portal events across all of this integration instance's WFS inbound shipments.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters (both optional):\n- date_from (date, m/d/Y or Y-m-d): only include packets sent on/after this day (start of day).\n- date_to (date, m/d/Y or Y-m-d): only include packets sent on/before this day (end of day).\n\nResponse: { data: { summary, partners[] } }. summary is the 'All partners' aggregate; partners[] is one row per 3PL warehouse / supplier, sorted by shipments_sent desc. partner_type is 'all' (summary), '3pl', or 'supplier'. Median/avg hour fields are null when no packet has reached that milestone yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","3pl-metrics"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"partner_name\": \"All partners\",\n      \"partner_type\": \"all\",\n      \"shipments_sent\": 12,\n      \"ready_count\": 9,\n      \"overdue_count\": 1,\n      \"median_hours_to_box_contents\": 6.5,\n      \"median_hours_to_ready\": 20.5,\n      \"avg_hours_to_ready\": 22.3\n    },\n    \"partners\": [\n      {\n        \"partner_name\": \"Acme 3PL Warehouse\",\n        \"partner_type\": \"3pl\",\n        \"shipments_sent\": 7,\n        \"ready_count\": 6,\n        \"overdue_count\": 0,\n        \"median_hours_to_box_contents\": 5,\n        \"median_hours_to_ready\": 18,\n        \"avg_hours_to_ready\": 19.2\n      },\n      {\n        \"partner_name\": \"Widget Supply Co\",\n        \"partner_type\": \"supplier\",\n        \"shipments_sent\": 5,\n        \"ready_count\": 3,\n        \"overdue_count\": 1,\n        \"median_hours_to_box_contents\": 8,\n        \"median_hours_to_ready\": 26,\n        \"avg_hours_to_ready\": 27.5\n      }\n    ]\n  }\n}"}]},{"name":"Get Warehouse WFS Turnaround Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/wfs/warehouses/{warehouse}/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart","wfs","warehouses",":warehouse","3pl-metrics"],"variable":[{"key":"warehouse","value":"1","description":"Source warehouse (3PL) ID"}]},"description":"3PL/supplier turnaround SLA metrics scoped to a single source warehouse (3PL partner): per-partner turnaround gaps between sending a WFS-inbound fulfilment request and each milestone (sent -> box contents submitted, sent -> ready to ship), plus an overall summary. Unlike the instance-scoped metrics endpoint, this spans every Walmart integration instance -- a warehouse's turnaround is instance-agnostic.\n\nAuthentication: Requires Bearer token.\n\nPath parameter:\n- warehouse (integer): the source warehouse ID to scope to.\n\nQuery parameters (both optional):\n- date_from (date, m/d/Y or Y-m-d): only include packets sent on/after this day (start of day).\n- date_to (date, m/d/Y or Y-m-d): only include packets sent on/before this day (end of day).\n\nResponse: { data: { summary, partners[] } }. summary is the 'All partners' aggregate; partners[] is one row per 3PL warehouse / supplier, sorted by shipments_sent desc. partner_type is 'all' (summary), '3pl', or 'supplier'. Median/avg hour fields are null when no packet has reached that milestone yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/wfs/warehouses/{warehouse}/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart","wfs","warehouses",":warehouse","3pl-metrics"],"variable":[{"key":"warehouse","value":"1","description":"Source warehouse (3PL) ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"partner_name\": \"All partners\",\n      \"partner_type\": \"all\",\n      \"shipments_sent\": 7,\n      \"ready_count\": 6,\n      \"overdue_count\": 0,\n      \"median_hours_to_box_contents\": 5,\n      \"median_hours_to_ready\": 18,\n      \"avg_hours_to_ready\": 19.2\n    },\n    \"partners\": [\n      {\n        \"partner_name\": \"Acme 3PL Warehouse\",\n        \"partner_type\": \"3pl\",\n        \"shipments_sent\": 7,\n        \"ready_count\": 6,\n        \"overdue_count\": 0,\n        \"median_hours_to_box_contents\": 5,\n        \"median_hours_to_ready\": 18,\n        \"avg_hours_to_ready\": 19.2\n      }\n    ]\n  }\n}"}]},{"name":"Get Supplier WFS Turnaround Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/wfs/suppliers/{supplier}/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart","wfs","suppliers",":supplier","3pl-metrics"],"variable":[{"key":"supplier","value":"1","description":"Source supplier ID"}]},"description":"3PL/supplier turnaround SLA metrics scoped to a single source supplier: per-partner turnaround gaps between sending a WFS-inbound fulfilment request and each milestone (sent -> box contents submitted, sent -> ready to ship), plus an overall summary. Spans every Walmart integration instance -- a supplier's turnaround is instance-agnostic.\n\nAuthentication: Requires Bearer token.\n\nPath parameter:\n- supplier (integer): the source supplier ID to scope to.\n\nQuery parameters (both optional):\n- date_from (date, m/d/Y or Y-m-d): only include packets sent on/after this day (start of day).\n- date_to (date, m/d/Y or Y-m-d): only include packets sent on/before this day (end of day).\n\nResponse: { data: { summary, partners[] } }. summary is the 'All partners' aggregate; partners[] is one row per 3PL warehouse / supplier, sorted by shipments_sent desc. partner_type is 'all' (summary), '3pl', or 'supplier'. Median/avg hour fields are null when no packet has reached that milestone yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/wfs/suppliers/{supplier}/3pl-metrics","host":["{{baseUrl}}"],"path":["api","walmart","wfs","suppliers",":supplier","3pl-metrics"],"variable":[{"key":"supplier","value":"1","description":"Source supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"partner_name\": \"All partners\",\n      \"partner_type\": \"all\",\n      \"shipments_sent\": 5,\n      \"ready_count\": 3,\n      \"overdue_count\": 1,\n      \"median_hours_to_box_contents\": 8,\n      \"median_hours_to_ready\": 26,\n      \"avg_hours_to_ready\": 27.5\n    },\n    \"partners\": [\n      {\n        \"partner_name\": \"Widget Supply Co\",\n        \"partner_type\": \"supplier\",\n        \"shipments_sent\": 5,\n        \"ready_count\": 3,\n        \"overdue_count\": 1,\n        \"median_hours_to_box_contents\": 8,\n        \"median_hours_to_ready\": 26,\n        \"avg_hours_to_ready\": 27.5\n      }\n    ]\n  }\n}"}]},{"name":"Get WFS Inbound Suggested Package","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/suggested-package","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","suggested-package"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Best-guess a single shipping package (weight + dimensions) for an inbound shipment, derived from the shipment items' product records. Used to pre-fill the carrier-rate-quote form so the dimensions don't have to be typed by hand.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWeight is summed across all items (converted to LB); the box is approximated as a cube of the combined item volume (converted to IN). Items whose product has no dimensions are skipped. Values are returned in Walmart units (LB / IN).\n\nScoped to the integration instance (404 if the shipment belongs to another instance). A Walmart-side or estimation failure returns 422. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/suggested-package","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","suggested-package"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"weight\": 28,\n    \"length\": 16.49,\n    \"width\": 16.49,\n    \"height\": 16.49\n  }\n}"}]},{"name":"Get Carrier Rate Quotes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quotes","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quotes"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WFS inbound shipment ID"}]},"description":"Request WFS Preferred-Carrier rate quotes for a shipment. Walmart's payload is built from the shipment's source warehouse (origin/return address) + assigned FC (destination) + the supplied package dimensions. The inbound must have a resolved SOURCE WAREHOUSE (supplier-sourced or unresolved inbounds are rejected). Returns a normalized quote list.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- packages (array, required, min 1): one entry per distinct package.\n- packages[].weight (numeric, required, min 0): package weight in LB.\n- packages[].length (numeric, required, min 0): length in IN.\n- packages[].width (numeric, required, min 0): width in IN.\n- packages[].height (numeric, required, min 0): height in IN.\n- packages[].count (integer, optional, min 1): number of identical packages (default 1).\n- pickup_date (date, optional, nullable): requested carrier pickup date.\n\nEach normalized quote: quote_id, carrier, net_charge, currency, transit_days, estimated_delivery, status, mode.\n\nResponse: { \"data\": [ quotes ] }.","body":{"mode":"raw","raw":"{\n  \"packages\": [\n    {\n      \"weight\": 12.5,\n      \"length\": 14,\n      \"width\": 14,\n      \"height\": 14,\n      \"count\": 1\n    }\n  ],\n  \"pickup_date\": \"2026-07-08\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quotes","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quotes"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"quote_id\": \"QT-8842019\",\n      \"carrier\": \"FedEx\",\n      \"net_charge\": 42.75,\n      \"currency\": \"USD\",\n      \"transit_days\": 3,\n      \"estimated_delivery\": \"2026-07-12T00:00:00Z\",\n      \"status\": \"ACTIVE\",\n      \"mode\": \"PARCEL\"\n    },\n    {\n      \"quote_id\": \"QT-8842020\",\n      \"carrier\": \"UPS\",\n      \"net_charge\": 47.1,\n      \"currency\": \"USD\",\n      \"transit_days\": 2,\n      \"estimated_delivery\": \"2026-07-11T00:00:00Z\",\n      \"status\": \"ACTIVE\",\n      \"mode\": \"PARCEL\"\n    }\n  ]\n}"}]},{"name":"Confirm WFS Inbound Carrier Rate Quote","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote/confirm","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Confirm (book) the previously requested WFS Preferred-Carrier rate quote for an inbound shipment. No request body. Scoped to the integration instance (404 if the shipment belongs to another instance). A Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote/confirm","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote","confirm"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Carrier rate quote confirmed\"\n}"}]},{"name":"Get Existing WFS Inbound Carrier Rate Quote","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Fetch the carrier rate quote that already exists on Walmart for this inbound shipment. The detail page calls this on mount so a previously generated quote is shown (with Confirm / Void / Print) instead of a blank panel — Walmart's create endpoint is one-shot per shipment, so re-creating would 400. No request body. Scoped to the integration instance (404 if the shipment belongs to another instance). When no quote exists yet (the normal starting state — Walmart returns 404), this endpoint stays silent and returns an empty `data` list with a 200. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"quote_id\": \"RQ-88213\",\n      \"carrier\": \"WFS-FEDEX\",\n      \"net_charge\": 42.75,\n      \"currency\": \"USD\",\n      \"transit_days\": \"3\",\n      \"estimated_delivery\": \"2026-07-01T00:00:00Z\",\n      \"status\": \"ACTIVE\",\n      \"mode\": \"PARCEL\"\n    }\n  ]\n}"}]},{"name":"Void WFS Inbound Carrier Rate Quote","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Void the carrier rate quote / booking for an inbound shipment. No request body. Scoped to the integration instance (404 if the shipment belongs to another instance). A Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-rate-quote","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-rate-quote"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Carrier rate quote voided\"\n}"}]},{"name":"Print WFS Inbound Carrier Label","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-label","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-label"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Print the carrier label for a booked WFS inbound shipment. The response is the raw label document itself — binary PDF bytes streamed as a file download (Content-Type: application/pdf, Content-Disposition: attachment), NOT a JSON envelope. Scoped to the integration instance (404 if the shipment belongs to another instance).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- ship_date (optional, nullable, date) — the ship date to stamp on the label; defaults to today (UTC) when omitted.\n\nResponses:\n- 200: the PDF label bytes (binary download).\n- 404: the shipment does not belong to the given integration instance.\n- 422: ship_date is not a valid date.\n\nRequires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"ship_date\": \"2026-06-28\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/carrier-label","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","carrier-label"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 ...binary label bytes... %%EOF"}]},{"name":"Submit WFS Inbound Shipment Tracking","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/tracking","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","tracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Submit the carrier and tracking numbers for an inbound shipment to Walmart and persist them locally. Scoped to the integration instance (404 if the shipment belongs to another instance).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- carrier_name (required, string, max 255).\n- tracking_numbers (required, array, min 1) — each a required string (max 255).\n\nValidation errors return 422; a Walmart-side failure also returns 422 with the reason. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"carrier_name\": \"FEDEX\",\n  \"tracking_numbers\": [\n    \"787439195645\",\n    \"787439195646\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/tracking","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","tracking"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Tracking submitted to Walmart\"\n}"}]},{"name":"Update WFS Inbound Shipment Quantities","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/quantities","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","quantities"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]},"description":"Update the per-SKU quantities on a not-yet-received inbound shipment. Scoped to the integration instance (404 if the shipment belongs to another instance).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- items (required, array, min 1) — each: { sku (required string, max 255), quantity (required integer >= 0; 0 removes the line) }.\n\nValidation errors return 422; a Walmart-side failure also returns 422 with the reason. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"quantity\": 15\n    },\n    {\n      \"sku\": \"ABC-002\",\n      \"quantity\": 0\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/quantities","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","quantities"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"7","description":"Local WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipment quantities updated\"\n}"}]},{"name":"Get Inbound Shipment Label","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/label","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","label"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WFS inbound shipment ID"}]},"description":"Download the Walmart inbound receiving label (PDF) for a shipment. The response is streamed as raw PDF bytes (Content-Type: application/pdf, Content-Disposition: attachment), NOT JSON.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse: binary PDF (application/pdf) as a file attachment named wfs-inbound-&lt;shipment_id>.pdf."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/label","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","label"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 [binary PDF bytes — inbound receiving label; not JSON]"}]},{"name":"Search Inbound Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Search seller-fulfilled (non-WFS) Walmart listings eligible to send into Walmart Fulfillment Services for the inbound builder's search/add-items step. Only listings with a GTIN/UPC (Walmart rejects items without one) and a matching, non-archived SKU.io product are returned; SKUs already in WFS are excluded. Results are capped at 50, ordered by product name.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- query (string, optional): search text over Walmart SKU / Walmart product name / SKU.io product name.\n- source_warehouse_id (integer, optional): annotate each row with available stock at this warehouse (source_quantity). When omitted, source_quantity is null."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 3391,\n      \"sku\": \"WIDGET-BLUE\",\n      \"name\": \"Blue Widget 12oz\",\n      \"gtin\": 810000123456,\n      \"image\": \"https://cdn.sku.io/products/widget-blue.jpg\",\n      \"source_quantity\": 320\n    },\n    {\n      \"product_id\": 3392,\n      \"sku\": \"WIDGET-RED\",\n      \"name\": \"Red Widget 12oz\",\n      \"gtin\": 810000123463,\n      \"image\": null,\n      \"source_quantity\": 88\n    }\n  ]\n}"}]},{"name":"Resolve Inbound Identifiers (Bulk)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products/resolve","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Resolve a list of bulk-import identifiers (SKU / UPC / GTIN) to WFS-eligible products for the inbound builder's Bulk Add modal. Mirrors FBA bulk-add resolve: each identifier is classified as matched (exactly one product), multiple (several — the user picks), or not_found. Eligibility is identical to Search Inbound Products (non-WFS, GTIN/UPC-bearing, matching non-archived product, excluding already-WFS SKUs).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- identifiers (string[], required, 1–500 items): raw identifier strings to resolve; each max 255 chars.\n- identifier_type (string, optional, one of auto|sku|upc|gtin; default auto): how to interpret each identifier. auto matches against SKU, UPC, or GTIN.\n- source_warehouse_id (integer, optional, nullable): when set, resolved products carry source_quantity for that warehouse (null otherwise).","body":{"mode":"raw","raw":"{\n  \"identifiers\": [\n    \"WIDGET-BLUE\",\n    810000123463,\n    \"NOPE-999\"\n  ],\n  \"identifier_type\": \"auto\",\n  \"source_warehouse_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products/resolve","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products","resolve"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched\": [\n      {\n        \"identifier\": \"WIDGET-BLUE\",\n        \"product\": {\n          \"product_id\": 3391,\n          \"sku\": \"WIDGET-BLUE\",\n          \"name\": \"Blue Widget 12oz\",\n          \"gtin\": 810000123456,\n          \"image\": \"https://cdn.sku.io/products/widget-blue.jpg\",\n          \"source_quantity\": 320\n        }\n      },\n      {\n        \"identifier\": 810000123463,\n        \"product\": {\n          \"product_id\": 3392,\n          \"sku\": \"WIDGET-RED\",\n          \"name\": \"Red Widget 12oz\",\n          \"gtin\": 810000123463,\n          \"image\": null,\n          \"source_quantity\": 88\n        }\n      }\n    ],\n    \"multiple\": [],\n    \"not_found\": [\n      \"NOPE-999\"\n    ]\n  }\n}"}]},{"name":"List Source Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/source-warehouses","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","source-warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the warehouses eligible as a WFS inbound source for the Source step of the inbound builder — the seller's own Direct + 3PL warehouses (non-archived), each with its type and a formatted address. Integration-destination warehouses (Amazon FBA/AWD, the WFS warehouse itself, virtual) are excluded. Ordered by name.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/source-warehouses","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","source-warehouses"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"direct\",\n      \"address\": \"123 Commerce Way, Austin, TX\"\n    },\n    {\n      \"id\": 9,\n      \"name\": \"West Coast 3PL\",\n      \"type\": \"3pl\",\n      \"address\": \"88 Logistics Blvd, Ontario, CA\"\n    }\n  ]\n}"}]},{"name":"Get Fulfillment Packet","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Get the operator-side view of a shipment's 3PL/supplier fulfilment packet. Returns whether a packet even applies to this shipment's source (availability), the built packet if one exists (else null), the public portal URL, the auto-generated default prep instructions (used to pre-fill the editable field), the kitting-instruction snippet, and whether the shipment has any component-sourced kits (drives the 'Kits will be assembled' toggle).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nResponse keys:\n- availability { available, source_type (3pl|supplier|null), reason }: a packet only applies to 3PL- or supplier-sourced inbounds; reason explains an unavailable case.\n- packet: the WalmartWfsInboundFulfillmentPacket resource (with documents[]), or null if not yet built.\n- portal_url: public token-gated portal link (null if no packet).\n- default_instructions: auto-generated prep instructions text.\n- kitting_instruction: the fixed kitting note appended when kits will be assembled.\n- has_component_kits: whether a kitting work order is applicable."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"availability\": {\n      \"available\": true,\n      \"source_type\": \"3pl\",\n      \"reason\": null\n    },\n    \"packet\": {\n      \"id\": 12,\n      \"walmart_wfs_inbound_shipment_id\": 843,\n      \"source_type\": \"3pl\",\n      \"source_type_label\": \"3PL Warehouse\",\n      \"channels\": [\n        \"email\",\n        \"portal\"\n      ],\n      \"status\": \"draft\",\n      \"status_label\": \"Draft\",\n      \"build_required\": false,\n      \"instruction_override\": null,\n      \"portal_token\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\",\n      \"portal_accessible\": true,\n      \"portal_token_expires_at\": \"2026-08-05T14:30:00.000000Z\",\n      \"sent_at\": null,\n      \"acknowledged_at\": null,\n      \"recipient_email\": \"receiving@acme3pl.com\",\n      \"recipient_name\": \"Acme 3PL Warehouse\",\n      \"email_from\": {\n        \"address\": \"noreply@sku.io\",\n        \"name\": \"Acme Store\"\n      },\n      \"email_reply_to\": {\n        \"address\": \"ops@acme-store.com\",\n        \"name\": \"Jane Operator\"\n      },\n      \"email_from_default_mode\": \"system\",\n      \"email_from_options\": {\n        \"merchant\": {\n          \"address\": \"orders@acme-store.com\",\n          \"name\": \"Acme Store\"\n        },\n        \"system\": {\n          \"address\": \"noreply@sku.io\",\n          \"name\": \"Acme Store\"\n        }\n      },\n      \"email_from_dns_setup\": {\n        \"domain\": \"acme-store.com\",\n        \"provider\": \"Postmark\",\n        \"steps\": [\n          {\n            \"title\": \"Authorize Postmark in acme-store.com's SPF record\",\n            \"detail\": \"Add include:spf.mtasv.net to the SPF TXT record on acme-store.com. A domain must have exactly one SPF record — merge it into the existing one instead of adding a second. If acme-store.com has no SPF record yet, publish:\",\n            \"record\": {\n              \"type\": \"TXT\",\n              \"host\": \"acme-store.com\",\n              \"value\": \"v=spf1 include:spf.mtasv.net ~all\"\n            }\n          },\n          {\n            \"title\": \"Publish acme-store.com's DKIM records\",\n            \"detail\": \"DKIM records are unique per domain and are generated when acme-store.com is added to SKU.io's Postmark sending account. Ask SKU.io support to add acme-store.com — you'll receive three CNAME records (s1._domainkey.acme-store.com, s2._domainkey.acme-store.com and a return-path host) to publish, which also aligns the emails with your DMARC policy.\"\n          },\n          {\n            \"title\": \"Verify before relying on it\",\n            \"detail\": \"Send a test email and check it arrives in the inbox (not spam) with SPF and DKIM shown as PASS in the message headers. Until both pass, recipients with a strict DMARC policy on acme-store.com may reject these emails.\"\n          }\n        ]\n      },\n      \"email_template\": {\n        \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n        \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\",\n        \"is_custom\": false\n      },\n      \"email_will_attach_prep_sheet\": true,\n      \"email_will_attach_receiving_label\": true,\n      \"email_will_attach_carrier_label\": true,\n      \"documents\": [\n        {\n          \"id\": 101,\n          \"type\": \"receiving_label\",\n          \"type_label\": \"WFS Receiving Label\",\n          \"stage\": \"initial\",\n          \"stage_label\": \"Initial\",\n          \"status\": \"ready\",\n          \"status_label\": \"Ready\",\n          \"downloadable\": true\n        },\n        {\n          \"id\": 103,\n          \"type\": \"carrier_label\",\n          \"type_label\": \"WFS Carrier Label\",\n          \"stage\": \"initial\",\n          \"stage_label\": \"Initial\",\n          \"status\": \"ready\",\n          \"status_label\": \"Ready\",\n          \"downloadable\": true\n        },\n        {\n          \"id\": 102,\n          \"type\": \"instructions\",\n          \"type_label\": \"Prep Instructions\",\n          \"stage\": \"initial\",\n          \"stage_label\": \"Initial\",\n          \"status\": \"ready\",\n          \"status_label\": \"Ready\",\n          \"downloadable\": true\n        },\n        {\n          \"id\": 104,\n          \"type\": \"asn\",\n          \"type_label\": \"Advanced Shipment Notice\",\n          \"stage\": \"initial\",\n          \"stage_label\": \"Initial\",\n          \"status\": \"ready\",\n          \"status_label\": \"Ready\",\n          \"downloadable\": false\n        }\n      ],\n      \"created_at\": \"2026-07-06T14:30:00.000000Z\"\n    },\n    \"portal_url\": \"{{protocol}}://{{domain}}/v2/integrations/walmart/wfs/inbound-shipments/fulfillment-portal/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6?integration=1\",\n    \"default_instructions\": \"WALMART WFS INBOUND — PREP INSTRUCTIONS\\nShipment: 970000123456 (Order 100000987654)\\nDestination FC: 6099\\n\\nItems to prepare:\\n  • 48 × WIDGET-BLUE — Blue Widget 12oz\\n  • 24 × WIDGET-RED — Red Widget 12oz\\n\\nAffix the WFS Receiving Label (provided) to the outside of each carton.\",\n    \"kitting_instruction\": \"KITTING: assemble the kit SKUs per the Kitting Work Order, then confirm \\\"Kits Built\\\".\",\n    \"has_component_kits\": false\n  }\n}"}]},{"name":"Build/Update Fulfillment Packet","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Build (or refresh) the fulfilment packet for a 3PL/supplier-sourced inbound — resolves the source type, scaffolds the staged document set, and mints a portal token. Re-calling updates the existing packet (channels, build flag, instruction override) and re-scaffolds documents. Returns 422 if the shipment is direct-warehouse sourced (no packet applies) or its source is unresolved.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- channels (string[], optional, each one of email|portal): delivery channels. portal is always included even if omitted.\n- build_kits (boolean, optional, default false): when true AND the shipment has component-sourced kits, adds a Kitting Work Order and marks build_required.\n- instruction_override (string, optional, nullable, max 5000): replaces the auto-generated prep instructions.","body":{"mode":"raw","raw":"{\n  \"channels\": [\n    \"email\",\n    \"portal\"\n  ],\n  \"build_kits\": false,\n  \"instruction_override\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"walmart_wfs_inbound_shipment_id\": 843,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL Warehouse\",\n    \"channels\": [\n      \"email\",\n      \"portal\"\n    ],\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"build_required\": false,\n    \"instruction_override\": null,\n    \"portal_token\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\",\n    \"portal_accessible\": true,\n    \"portal_token_expires_at\": \"2026-08-05T14:30:00.000000Z\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"recipient_email\": \"receiving@acme3pl.com\",\n    \"recipient_name\": \"Acme 3PL Warehouse\",\n    \"email_template\": {\n      \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\"\n    },\n    \"email_will_attach_prep_sheet\": true,\n    \"email_will_attach_receiving_label\": true,\n    \"email_will_attach_carrier_label\": true,\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 103,\n        \"type\": \"carrier_label\",\n        \"type_label\": \"WFS Carrier Label\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 104,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": false\n      }\n    ],\n    \"created_at\": \"2026-07-06T14:30:00.000000Z\"\n  },\n  \"message\": \"Fulfilment packet built\"\n}"}]},{"name":"Rotate Portal Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/rotate-token","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","rotate-token"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Revoke the current portal token and issue a fresh one — the old public link stops working immediately. Returns 404 if no fulfilment packet has been built for this shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody: none (send an empty JSON object).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/rotate-token","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","rotate-token"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"walmart_wfs_inbound_shipment_id\": 843,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL Warehouse\",\n    \"channels\": [\n      \"email\",\n      \"portal\"\n    ],\n    \"status\": \"draft\",\n    \"status_label\": \"Draft\",\n    \"build_required\": false,\n    \"instruction_override\": null,\n    \"portal_token\": \"f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4\",\n    \"portal_accessible\": true,\n    \"portal_token_expires_at\": \"2026-08-05T15:10:00.000000Z\",\n    \"sent_at\": null,\n    \"acknowledged_at\": null,\n    \"recipient_email\": \"receiving@acme3pl.com\",\n    \"recipient_name\": \"Acme 3PL Warehouse\",\n    \"email_template\": {\n      \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\"\n    },\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": false\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 104,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": false\n      }\n    ],\n    \"created_at\": \"2026-07-06T14:30:00.000000Z\"\n  },\n  \"message\": \"Portal link rotated\"\n}"}]},{"name":"Preview Fulfillment Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/email/preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","email","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Render the operator's edited subject/body with the live tokens substituted, without sending anything — powers the compose dialog's preview pane. Tokens {{reference}} (the WFS shipment id), {{portal_link}} (a clickable anchor to the secure fulfilment portal), and {{instructions}} (the rendered prep instructions) are resolved server-side; the subject is treated as plain text, the body as HTML. Returns 422 if no fulfilment packet has been built for this shipment yet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- subject (string, required, max 255): the final subject line (tokens substituted server-side).\n- body (string, required): the final HTML body (tokens substituted server-side).\n- cc (string[], optional, nullable, each a valid email): additional CC recipients (ignored by preview; used on send).\n- from_mode (string, optional, nullable, one of: merchant, system): sender-identity override. 'merchant' sends From the store's own domain (needs the SPF/DKIM setup in email_from_dns_setup); 'system' sends via SKU.io with the operator as Reply-To. Null = the tenant's default (email_from_default_mode).","body":{"mode":"raw","raw":"{\n  \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n  \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\",\n  \"cc\": [\n    \"warehouse-manager@acme3pl.com\"\n  ],\n  \"from_mode\": \"system\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/email/preview","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","email","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"subject\": \"Walmart WFS inbound — prep & receiving label needed for 970000123456\",\n    \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>970000123456</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p><a href=\\\"{{protocol}}://{{domain}}/v2/integrations/walmart/wfs/inbound-shipments/fulfillment-portal/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6?integration=1\\\">{{protocol}}://{{domain}}/v2/integrations/walmart/wfs/inbound-shipments/fulfillment-portal/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6?integration=1</a></p><p><strong>Prep instructions:</strong></p><p>WALMART WFS INBOUND &mdash; PREP INSTRUCTIONS<br />\\nShipment: 970000123456 (Order 100000987654)<br />\\nDestination FC: 6099<br />\\n<br />\\nItems to prepare:<br />\\n&nbsp;&nbsp;&bull; 48 &times; WIDGET-BLUE &mdash; Blue Widget 12oz<br />\\n&nbsp;&nbsp;&bull; 24 &times; WIDGET-RED &mdash; Red Widget 12oz<br />\\n<br />\\nAffix the WFS Receiving Label (provided) to the outside of each carton.</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\"\n  }\n}"}]},{"name":"Send Fulfillment Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/email","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","email"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Send the operator-composed portal invite to the resolved 3PL/supplier recipient (a 3PL warehouse's address email, or the supplier's PO email), substituting the {{reference}}/{{portal_link}}/{{instructions}} tokens server-side, then flip the packet status to Sent (sets sent_at). The recipient is resolved server-side — it is not accepted from the request. Returns 422 if no packet has been built, or if no recipient email is configured for the source (add one to the 3PL warehouse address / supplier before emailing).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- subject (string, required, max 255): the final subject line (tokens substituted server-side).\n- body (string, required): the final HTML body (tokens substituted server-side).\n- cc (string[], optional, nullable, each a valid email): additional CC recipients.\n- attach_prep_sheet (boolean, optional, default true): attach the prep & pack sheet CSV (unit mix, prep requirements, kitting) — included when the shipment has lines.\n- attach_receiving_label (boolean, optional, default false; the compose dialog pre-checks it whenever a receiving label is available): attach the WFS receiving label PDF, fetched live from Walmart at send time. Silently skipped if the shipment is a source placeholder or the live fetch fails.\n- attach_carrier_label (boolean, optional, default false; the compose dialog pre-checks it whenever a carrier is booked): attach the WFS carrier / pickup label PDF, fetched live from Walmart at send time. Silently skipped if no carrier is booked or the live fetch fails.\n- from_mode (string, optional, nullable, one of: merchant, system): sender-identity override. 'merchant' sends From the store's own domain (needs the SPF/DKIM setup in email_from_dns_setup); 'system' sends via SKU.io with the operator as Reply-To. Null = the tenant's default (email_from_default_mode).","body":{"mode":"raw","raw":"{\n  \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n  \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\",\n  \"cc\": [\n    \"warehouse-manager@acme3pl.com\"\n  ],\n  \"attach_prep_sheet\": true,\n  \"attach_receiving_label\": true,\n  \"attach_carrier_label\": true,\n  \"from_mode\": \"system\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/email","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","email"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"walmart_wfs_inbound_shipment_id\": 843,\n    \"source_type\": \"3pl\",\n    \"source_type_label\": \"3PL Warehouse\",\n    \"channels\": [\n      \"email\",\n      \"portal\"\n    ],\n    \"status\": \"sent\",\n    \"status_label\": \"Sent\",\n    \"build_required\": false,\n    \"instruction_override\": null,\n    \"portal_token\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\",\n    \"portal_accessible\": true,\n    \"portal_token_expires_at\": \"2026-08-05T14:30:00.000000Z\",\n    \"sent_at\": \"2026-07-07T16:05:00.000000Z\",\n    \"acknowledged_at\": null,\n    \"recipient_email\": \"receiving@acme3pl.com\",\n    \"recipient_name\": \"Acme 3PL Warehouse\",\n    \"email_from\": {\n      \"address\": \"noreply@sku.io\",\n      \"name\": \"Acme Store\"\n    },\n    \"email_reply_to\": {\n      \"address\": \"ops@acme-store.com\",\n      \"name\": \"Jane Operator\"\n    },\n    \"email_from_default_mode\": \"system\",\n    \"email_from_options\": {\n      \"merchant\": {\n        \"address\": \"orders@acme-store.com\",\n        \"name\": \"Acme Store\"\n      },\n      \"system\": {\n        \"address\": \"noreply@sku.io\",\n        \"name\": \"Acme Store\"\n      }\n    },\n    \"email_from_dns_setup\": {\n      \"domain\": \"acme-store.com\",\n      \"provider\": \"Postmark\",\n      \"steps\": [\n        {\n          \"title\": \"Authorize Postmark in acme-store.com's SPF record\",\n          \"detail\": \"Add include:spf.mtasv.net to the SPF TXT record on acme-store.com. A domain must have exactly one SPF record — merge it into the existing one instead of adding a second. If acme-store.com has no SPF record yet, publish:\",\n          \"record\": {\n            \"type\": \"TXT\",\n            \"host\": \"acme-store.com\",\n            \"value\": \"v=spf1 include:spf.mtasv.net ~all\"\n          }\n        },\n        {\n          \"title\": \"Publish acme-store.com's DKIM records\",\n          \"detail\": \"DKIM records are unique per domain and are generated when acme-store.com is added to SKU.io's Postmark sending account. Ask SKU.io support to add acme-store.com — you'll receive three CNAME records (s1._domainkey.acme-store.com, s2._domainkey.acme-store.com and a return-path host) to publish, which also aligns the emails with your DMARC policy.\"\n        },\n        {\n          \"title\": \"Verify before relying on it\",\n          \"detail\": \"Send a test email and check it arrives in the inbox (not spam) with SPF and DKIM shown as PASS in the message headers. Until both pass, recipients with a strict DMARC policy on acme-store.com may reject these emails.\"\n        }\n      ]\n    },\n    \"email_template\": {\n      \"subject\": \"Walmart WFS inbound — prep & receiving label needed for {{reference}}\",\n      \"body\": \"<p>Hi,</p><p>We&rsquo;re sending a Walmart Fulfillment Services (WFS) inbound shipment (<strong>{{reference}}</strong>) from your location and need you to prep and pack it per the instructions below, then confirm when it&rsquo;s ready.</p><p><strong>Preferred &mdash; use the secure portal.</strong> It shows the items to prepare, the destination fulfillment center, downloadable paperwork (including the WFS receiving label), and a button to confirm the shipment is ready:</p><p>{{portal_link}}</p><p><strong>Prep instructions:</strong></p><p>{{instructions}}</p><p>Please affix the WFS receiving label to the outside of each carton before the shipment goes out. Once you confirm it&rsquo;s ready in the portal we&rsquo;ll finalize the inbound with Walmart and send the carrier / pickup details.</p><p>Thank you.</p>\",\n      \"is_custom\": false\n    },\n    \"email_will_attach_prep_sheet\": true,\n    \"email_will_attach_receiving_label\": true,\n    \"email_will_attach_carrier_label\": true,\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 103,\n        \"type\": \"carrier_label\",\n        \"type_label\": \"WFS Carrier Label\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": true\n      },\n      {\n        \"id\": 104,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"stage_label\": \"Initial\",\n        \"status\": \"ready\",\n        \"status_label\": \"Ready\",\n        \"downloadable\": false\n      }\n    ],\n    \"created_at\": \"2026-07-06T14:30:00.000000Z\"\n  },\n  \"message\": \"Email sent to the 3PL.\"\n}"}]},{"name":"Download Prep & Pack Sheet (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/prep-sheet.csv","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","prep-sheet.csv"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]},"description":"Stream the prep-&-pack sheet as a CSV (unit mix, packing, prep, and any kitting work order) so an operator can hand it to a 3PL/supplier that won't use the secure portal. The file is named wfs-prep-pack-sheet-&lt;packetId>.csv. A fulfilment packet must have been built first — returns 422 JSON { message } when none exists yet.\n\nAuthentication: Requires Bearer token.\n\nResponse: a text/csv file download (no JSON body on success)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/fulfillment/prep-sheet.csv","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","fulfillment","prep-sheet.csv"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"843","description":"WFS inbound shipment ID (local WalmartWfsInboundShipment id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"Section,SKU,Description,Quantity,Notes\r\nUnit Mix,WIDGET-BLUE,Blue Widget 12oz,48,\r\nUnit Mix,WIDGET-RED,Red Widget 12oz,24,\r\nPacking,,,,Affix WFS receiving label to each carton\r\nPrep,,,,Poly-bag units with suffocation warning\r\n"}]},{"name":"Portal: View Packet","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]},"description":"Load the public fulfilment portal for a WFS inbound packet, resolved by its portal token. Records a 'viewed' portal event and returns the full order summary the 3PL/supplier needs: reference + destination FC, rendered prep instructions, downloadable documents, the kit build manifest (when a build is required), the expected line items, and whether it has been acknowledged as ready.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPublic, token-gated endpoint — no bearer auth. The {token} in the path gates packet access; tenant is resolved by host.\n\nReturns 404 with {\"message\": \"This portal link is no longer valid.\"} when the token is unknown, expired, or revoked.\n\nResponse data fields:\n- reference (string): the WFS shipment_id.\n- inbound_order_id (string|null): Walmart inbound order id.\n- source_name (string|null): the source 3PL/supplier warehouse name.\n- source_type (string): '3pl' or 'supplier'.\n- destination_fc (string|null): Walmart ship node / FC.\n- status (string): packet status (draft, sent, in_progress, acknowledged, shipped, send_failed, revoked).\n- build_required (bool): whether component-sourced kits must be assembled.\n- kits_pending_build (bool): a build is required and at least one kit is not yet confirmed built.\n- kit_build_manifest (array): kits to assemble — { sku, name, quantity, components:[{ sku, quantity }] }.\n- instructions (string): rendered plain-text prep instructions (or operator override).\n- line_items (array): { sku, name, image_url, quantity } for every shipment line.\n- documents (array): downloadable documents — { id, type, type_label, stage, status }.\n- acknowledged_at (string|null): ISO-8601 timestamp once acknowledged, else null."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"WFS-8842190\",\n    \"inbound_order_id\": \"INB-4471203\",\n    \"source_name\": \"Eastgate 3PL Fulfillment\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"6094\",\n    \"destination_address\": {\n      \"name\": \"Walmart Fulfillment Center 6094\",\n      \"line1\": \"5300 Centennial Blvd\",\n      \"line2\": null,\n      \"city\": \"Nashville\",\n      \"state\": \"TN\",\n      \"postal_code\": \"37209\",\n      \"country\": \"US\"\n    },\n    \"status\": \"sent\",\n    \"build_required\": true,\n    \"kits_pending_build\": true,\n    \"kit_build_manifest\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"quantity\": 24,\n        \"components\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"quantity\": 2\n          },\n          {\n            \"sku\": \"WIDGET-CABLE\",\n            \"quantity\": 1\n          }\n        ]\n      }\n    ],\n    \"instructions\": \"WALMART WFS INBOUND — PREP INSTRUCTIONS\\nShipment: WFS-8842190 (Order INB-4471203)\\nDestination FC: 6094\\n\\nItems to prepare:\\n  • 24 × KIT-STARTER-01 — Starter Bundle Kit\\n  • 60 × WIDGET-BLUE-500 — Blue Widget 500ml\\n\\nAffix the WFS Receiving Label (provided) to the outside of each carton.\\n\\nKITTING: assemble the kit SKUs per the Kitting Work Order, then confirm \\\"Kits Built\\\".\",\n    \"line_items\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"image_url\": \"https://cdn.sku.io/products/kit-starter-01.jpg\",\n        \"quantity\": 24\n      },\n      {\n        \"sku\": \"WIDGET-BLUE-500\",\n        \"name\": \"Blue Widget 500ml\",\n        \"image_url\": \"https://cdn.sku.io/products/widget-blue-500.jpg\",\n        \"quantity\": 60\n      }\n    ],\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 104,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 105,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"acknowledged_at\": null\n  }\n}"}]},{"name":"Portal: Download Document","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/documents/{document}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","documents",":document","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"},{"key":"document","value":"1","description":"WFS inbound document ID (must belong to this packet)"}]},"description":"Download one of the packet's staged documents by id. Records a 'downloaded' portal event, then streams the document as a file attachment (not JSON):\n- receiving_label → the live WFS receiving label fetched from Walmart as a PDF (Content-Type: application/pdf, Content-Disposition: attachment; filename=\"wfs-receiving-label-&lt;shipment_id>.pdf\").\n- carrier_label → the live WFS carrier / pickup label fetched from Walmart as a PDF (Content-Type: application/pdf, Content-Disposition: attachment; filename=\"wfs-carrier-label-&lt;shipment_id>.pdf\"). Only present when a preferred carrier is booked on the shipment.\n- instructions / work_order → rendered on demand as a plain-text attachment (Content-Type: text/plain; charset=UTF-8, filename=\"&lt;type>-&lt;packet_id>.txt\").\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPublic, token-gated endpoint — no bearer auth. The {token} in the path gates packet access; tenant is resolved by host.\n\nErrors:\n- 404 (text 'This portal link is no longer valid.') when the token is invalid/expired/revoked or the document does not belong to this packet.\n- 422 (text 'This document is not yet available.') when the document status is not downloadable.\n- 422 (text 'The receiving label could not be retrieved from Walmart right now.') when the live label fetch fails.\n- 422 (text 'The carrier label could not be retrieved from Walmart right now.') when the live carrier-label fetch fails.\n- 422 (text 'This document is prepared elsewhere and will be attached when ready.') for a file-backed type (e.g. po/asn) with no rendered content."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/documents/{document}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","documents",":document","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"},{"key":"document","value":"1","description":"WFS inbound document ID (must belong to this packet)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4\n<binary PDF stream — the WFS receiving label carton PDF fetched live from Walmart>\n%%EOF\n\n(Sent as an attachment: filename=\"wfs-receiving-label-WFS-8842190.pdf\". Body is binary and not shown here.)"}]},{"name":"Portal: Confirm Kits Built","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/kits-built","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","kits-built"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]},"description":"Explicitly confirm the component-sourced kits have been assembled. Realizes the kit builds (releases the reserved components, assembles the kit, and reserves it against the shipment — idempotent and safe when there is nothing to build), records a 'kits_built' portal event, and returns the refreshed portal payload with kits_pending_build cleared.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body is required.\n\nPublic, token-gated endpoint — no bearer auth. The {token} in the path gates packet access; tenant is resolved by host.\n\nErrors:\n- 404 {\"message\": \"This portal link is no longer valid.\"} when the token is invalid.\n- 422 {\"message\": \"&lt;reason>\"} when the kit build cannot be realized (e.g. insufficient components).\n\nResponse: { data: &lt;full portal payload>, message: \"Thank you — the kits have been marked as built.\" }."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/kits-built","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","kits-built"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"WFS-8842190\",\n    \"inbound_order_id\": \"INB-4471203\",\n    \"source_name\": \"Eastgate 3PL Fulfillment\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"6094\",\n    \"destination_address\": {\n      \"name\": \"Walmart Fulfillment Center 6094\",\n      \"line1\": \"5300 Centennial Blvd\",\n      \"line2\": null,\n      \"city\": \"Nashville\",\n      \"state\": \"TN\",\n      \"postal_code\": \"37209\",\n      \"country\": \"US\"\n    },\n    \"status\": \"in_progress\",\n    \"build_required\": true,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"quantity\": 24,\n        \"components\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"quantity\": 2\n          },\n          {\n            \"sku\": \"WIDGET-CABLE\",\n            \"quantity\": 1\n          }\n        ]\n      }\n    ],\n    \"instructions\": \"WALMART WFS INBOUND — PREP INSTRUCTIONS\\nShipment: WFS-8842190 (Order INB-4471203)\\nDestination FC: 6094\\n\\nItems to prepare:\\n  • 24 × KIT-STARTER-01 — Starter Bundle Kit\\n  • 60 × WIDGET-BLUE-500 — Blue Widget 500ml\\n\\nAffix the WFS Receiving Label (provided) to the outside of each carton.\\n\\nKITTING: assemble the kit SKUs per the Kitting Work Order, then confirm \\\"Kits Built\\\".\",\n    \"line_items\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"image_url\": \"https://cdn.sku.io/products/kit-starter-01.jpg\",\n        \"quantity\": 24\n      },\n      {\n        \"sku\": \"WIDGET-BLUE-500\",\n        \"name\": \"Blue Widget 500ml\",\n        \"image_url\": \"https://cdn.sku.io/products/widget-blue-500.jpg\",\n        \"quantity\": 60\n      }\n    ],\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 104,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 105,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"acknowledged_at\": null\n  },\n  \"message\": \"Thank you — the kits have been marked as built.\"\n}"}]},{"name":"Portal: Acknowledge","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/acknowledge","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]},"description":"Acknowledge the shipment as ready to ship. Requires box contents to have been submitted first — otherwise returns 422. On success it backstops any unconfirmed component-sourced kit builds (idempotent), marks the packet 'acknowledged' with acknowledged_at set, records an 'acknowledged' portal event, and returns the refreshed portal payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body is required.\n\nPublic, token-gated endpoint — no bearer auth. The {token} in the path gates packet access; tenant is resolved by host.\n\nErrors:\n- 404 {\"message\": \"This portal link is no longer valid.\"} when the token is invalid.\n- 422 {\"message\": \"Submit your box contents before confirming the shipment is ready.\"} when box contents have not been submitted yet.\n\nResponse: { data: &lt;full portal payload with status 'acknowledged' and acknowledged_at set>, message: \"Thank you — the shipment has been confirmed as ready.\" }."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/acknowledge","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","acknowledge"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"WFS-8842190\",\n    \"inbound_order_id\": \"INB-4471203\",\n    \"source_name\": \"Eastgate 3PL Fulfillment\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"6094\",\n    \"destination_address\": {\n      \"name\": \"Walmart Fulfillment Center 6094\",\n      \"line1\": \"5300 Centennial Blvd\",\n      \"line2\": null,\n      \"city\": \"Nashville\",\n      \"state\": \"TN\",\n      \"postal_code\": \"37209\",\n      \"country\": \"US\"\n    },\n    \"status\": \"acknowledged\",\n    \"build_required\": true,\n    \"kits_pending_build\": false,\n    \"kit_build_manifest\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"quantity\": 24,\n        \"components\": [\n          {\n            \"sku\": \"WIDGET-RED\",\n            \"quantity\": 2\n          },\n          {\n            \"sku\": \"WIDGET-CABLE\",\n            \"quantity\": 1\n          }\n        ]\n      }\n    ],\n    \"instructions\": \"WALMART WFS INBOUND — PREP INSTRUCTIONS\\nShipment: WFS-8842190 (Order INB-4471203)\\nDestination FC: 6094\\n\\nItems to prepare:\\n  • 24 × KIT-STARTER-01 — Starter Bundle Kit\\n  • 60 × WIDGET-BLUE-500 — Blue Widget 500ml\\n\\nAffix the WFS Receiving Label (provided) to the outside of each carton.\\n\\nKITTING: assemble the kit SKUs per the Kitting Work Order, then confirm \\\"Kits Built\\\".\",\n    \"line_items\": [\n      {\n        \"sku\": \"KIT-STARTER-01\",\n        \"name\": \"Starter Bundle Kit\",\n        \"image_url\": \"https://cdn.sku.io/products/kit-starter-01.jpg\",\n        \"quantity\": 24\n      },\n      {\n        \"sku\": \"WIDGET-BLUE-500\",\n        \"name\": \"Blue Widget 500ml\",\n        \"image_url\": \"https://cdn.sku.io/products/widget-blue-500.jpg\",\n        \"quantity\": 60\n      }\n    ],\n    \"documents\": [\n      {\n        \"id\": 101,\n        \"type\": \"receiving_label\",\n        \"type_label\": \"WFS Receiving Label\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 102,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 104,\n        \"type\": \"work_order\",\n        \"type_label\": \"Kitting Work Order\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      },\n      {\n        \"id\": 105,\n        \"type\": \"asn\",\n        \"type_label\": \"Advanced Shipment Notice\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"acknowledged_at\": \"2026-07-06T14:32:05+00:00\"\n  },\n  \"message\": \"Thank you — the shipment has been confirmed as ready.\"\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/oauth/authorization-url","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","oauth","authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the Walmart seller-consent authorization URL for this integration instance. Redirect the seller's browser to the returned URL so they can grant delegated access to their Walmart Marketplace account; on approval Walmart redirects back with an authorization code that completes the connection.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/oauth/authorization-url","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","oauth","authorization-url"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://login.account.wal-mart.com/authorize?responseType=code&clientId=a1b2c3d4-1111-2222-3333-444455556666&redirectUri=https%3A%2F%2Fapp.sku.io%2Fwalmart%2Fcallback&clientType=seller&nonce=8f4e2a&state=eyJpbnN0YW5jZSI6MX0\"\n}"}]},{"name":"Disconnect OAuth Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/oauth/disconnect","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","oauth","disconnect"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Disconnect the delegated Walmart authorization for this integration instance. Destroys both the delegated access token and the refresh token and deactivates syncing until the seller re-authorizes. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/oauth/disconnect","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","oauth","disconnect"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"disconnected\": true\n  }\n}"}]},{"name":"List Feeds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List bulk feeds submitted to Walmart for this integration instance (inventory, price, and promotion feeds) with their processing status, paginated.\n\nAuthentication: Requires Bearer token.\n\nFeed fields include: id, feed_id (Walmart feed ID), feed_type, status, items_received, items_succeeded, items_failed, failed_item_count, payload_summary, failure_reason, submitted_at, completed_at, last_polled_at, poll_attempts, created_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1042,\n      \"feed_id\": \"6A76F037DF2A4D148103E18988215469@AVMBCgA\",\n      \"feed_type\": \"MP_INVENTORY\",\n      \"status\": \"PROCESSED\",\n      \"items_received\": 25,\n      \"items_succeeded\": 24,\n      \"items_failed\": 1,\n      \"failed_item_count\": 1,\n      \"payload_summary\": {\n        \"listing_count\": 25\n      },\n      \"failure_reason\": null,\n      \"submitted_at\": \"2026-07-15T10:41:00+00:00\",\n      \"completed_at\": \"2026-07-15T10:52:00+00:00\",\n      \"last_polled_at\": \"2026-07-15T10:52:00+00:00\",\n      \"poll_attempts\": 3,\n      \"created_at\": \"2026-07-15T10:41:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://app.sku.io/api/walmart/1/feeds?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/walmart/1/feeds?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/walmart/1/feeds?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/walmart/1/feeds\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Feed","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds/{feed}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds",":feed"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"feed","value":"1042","description":"Feed ID"}]},"description":"Get a single feed with its per-SKU ingestion errors. Each item in the items array is a SKU that Walmart reported on, including any error codes and descriptions for failed items.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds/{feed}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds",":feed"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"feed","value":"1042","description":"Feed ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1042,\n    \"feed_id\": \"6A76F037DF2A4D148103E18988215469@AVMBCgA\",\n    \"feed_type\": \"MP_INVENTORY\",\n    \"status\": \"PROCESSED\",\n    \"items_received\": 25,\n    \"items_succeeded\": 24,\n    \"items_failed\": 1,\n    \"failed_item_count\": 1,\n    \"payload_summary\": {\n      \"listing_count\": 25\n    },\n    \"failure_reason\": null,\n    \"submitted_at\": \"2026-07-15T10:41:00+00:00\",\n    \"completed_at\": \"2026-07-15T10:52:00+00:00\",\n    \"last_polled_at\": \"2026-07-15T10:52:00+00:00\",\n    \"poll_attempts\": 3,\n    \"created_at\": \"2026-07-15T10:41:00+00:00\",\n    \"items\": [\n      {\n        \"id\": 1,\n        \"sku\": \"SKU-BAD\",\n        \"status\": \"ERROR\",\n        \"errors\": [\n          {\n            \"code\": \"ERR_EXT_ITEM_0001\",\n            \"field\": \"description\",\n            \"description\": \"Required attribute \\\"Description\\\" is missing.\"\n          }\n        ],\n        \"created_at\": \"2026-07-15T10:52:01+00:00\"\n      }\n    ]\n  }\n}"}]},{"name":"Re-poll Feed Status","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds/{feed}/repoll","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds",":feed","repoll"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"feed","value":"1042","description":"Feed ID"}]},"description":"Re-queue status polling for a stalled or lagging feed. Use this when a feed has stopped receiving status updates from Walmart. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.sync` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/feeds/{feed}/repoll","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","feeds",":feed","repoll"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"feed","value":"1042","description":"Feed ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"repolling\": true\n  }\n}"}]},{"name":"Push Prices","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/prices/push","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","prices","push"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Submit current prices to Walmart as a bulk price feed for listings where SKU.io is the master of price.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- listing_ids (optional, array of integers): IDs of the listings to push. Omit to push all eligible listings.\n\nRequires the `integrations.sync` permission.","body":{"mode":"raw","raw":"{\n  \"listing_ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/prices/push","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","prices","push"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1043,\n    \"feed_id\": \"7B87E148EA3B5E259214F29099326570@AVMBCgA\",\n    \"feed_type\": \"price\",\n    \"status\": \"RECEIVED\",\n    \"items_received\": 2,\n    \"items_succeeded\": 0,\n    \"items_failed\": 0,\n    \"failed_item_count\": 0,\n    \"payload_summary\": {\n      \"listing_count\": 2\n    },\n    \"failure_reason\": null,\n    \"submitted_at\": \"2026-07-15T14:03:00+00:00\",\n    \"completed_at\": null,\n    \"last_polled_at\": null,\n    \"poll_attempts\": 0,\n    \"created_at\": \"2026-07-15T14:03:00+00:00\"\n  }\n}"}]},{"name":"Create or Update Promotion","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/listings/{listing}/promotions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","listings",":listing","promotions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"listing","value":"101","description":"Walmart listing ID"}]},"description":"Submit a promotional price for a listing to Walmart via the promotion feed. Submitting again for the same listing updates the promotion.\n\nThe listing must belong to this integration instance; requests for a listing owned by a different instance fail with 403 Forbidden.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- amount (required, numeric): Promotional price.\n- effective_date (required, datetime): When the promotion starts.\n- expiration_date (required, datetime): When the promotion ends. Must be after effective_date.\n\nRequires the `integrations.sync` permission.","body":{"mode":"raw","raw":"{\n  \"amount\": 19.99,\n  \"effective_date\": \"2026-08-01T00:00:00Z\",\n  \"expiration_date\": \"2026-08-15T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/listings/{listing}/promotions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","listings",":listing","promotions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"listing","value":"101","description":"Walmart listing ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1044,\n    \"feed_id\": \"8C98F259FB4C6F36A325039100437681@AVMBCgA\",\n    \"feed_type\": \"promo\",\n    \"status\": \"RECEIVED\",\n    \"items_received\": 1,\n    \"items_succeeded\": 0,\n    \"items_failed\": 0,\n    \"failed_item_count\": 0,\n    \"payload_summary\": {\n      \"listing_count\": 1\n    },\n    \"failure_reason\": null,\n    \"submitted_at\": \"2026-07-15T14:03:00+00:00\",\n    \"completed_at\": null,\n    \"last_polled_at\": null,\n    \"poll_attempts\": 0,\n    \"created_at\": \"2026-07-15T14:03:00+00:00\"\n  }\n}"}]},{"name":"Delete Promotion","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/listings/{listing}/promotions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","listings",":listing","promotions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"listing","value":"101","description":"Walmart listing ID"}]},"description":"Remove the promotional price for a listing on Walmart via the promotion feed, restoring the regular price. No request body.\n\nThe listing must belong to this integration instance; requests for a listing owned by a different instance fail with 403 Forbidden.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.sync` permission."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/listings/{listing}/promotions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","listings",":listing","promotions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"listing","value":"101","description":"Walmart listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1045,\n    \"feed_id\": \"9DA90360AC5D7047B436140211548792@AVMBCgA\",\n    \"feed_type\": \"promo\",\n    \"status\": \"RECEIVED\",\n    \"items_received\": 1,\n    \"items_succeeded\": 0,\n    \"items_failed\": 0,\n    \"failed_item_count\": 0,\n    \"payload_summary\": {\n      \"listing_count\": 1\n    },\n    \"failure_reason\": null,\n    \"submitted_at\": \"2026-07-15T14:03:00+00:00\",\n    \"completed_at\": null,\n    \"last_polled_at\": null,\n    \"poll_attempts\": 0,\n    \"created_at\": \"2026-07-15T14:03:00+00:00\"\n  }\n}"}]},{"name":"List Settlement Report Dates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/recon/dates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","recon","dates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the available reconciliation (settlement) report cycle dates for this integration instance. Use one of the returned dates as the report_date parameter when downloading a settlement report.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/recon/dates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","recon","dates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"availableApReportDates\": [\n      \"07152026\",\n      \"07012026\"\n    ]\n  }\n}"}]},{"name":"Download Settlement Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/recon/download?report_date=07152026","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","recon","download"],"query":[{"key":"report_date","value":"07152026","description":"Settlement report cycle date in MMDDYYYY format, as returned by List Settlement Report Dates","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Download the reconciliation (settlement) report for a given cycle date. The response is a ZIP file download (Content-Type: application/octet-stream), not JSON. The report_date query parameter is required and must be a cycle date in MMDDYYYY format as returned by List Settlement Report Dates.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/recon/download?report_date=07152026","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","recon","download"],"query":[{"key":"report_date","value":"07152026","description":"Settlement report cycle date in MMDDYYYY format, as returned by List Settlement Report Dates","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"PK [binary ZIP bytes — reconciliation report for cycle date 07152026; not JSON]"}]},{"name":"Get Payment Statement","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/payment-statement","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","payment-statement"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the payment statement for the current settlement cycle, including the currency, the total payable amount, and the statement line groups.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/payment-statement","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","payment-statement"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"currency\": \"USD\",\n    \"totalPayable\": 15234.12,\n    \"statements\": [\n      {\n        \"type\": \"ORDER_REVENUE\",\n        \"amount\": 16890.45\n      },\n      {\n        \"type\": \"FEES\",\n        \"amount\": -1656.33\n      }\n    ]\n  }\n}"}]},{"name":"Get Partner Performance Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/performance","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","performance"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the partner performance report for this integration instance, summarizing marketplace performance metrics as measured by Walmart.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/performance","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","performance"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"performance\": [\n      {\n        \"metric\": \"ORDER_DEFECT_RATE\",\n        \"value\": 0.008,\n        \"target\": 0.02,\n        \"status\": \"GOOD\"\n      },\n      {\n        \"metric\": \"ON_TIME_SHIPMENT_RATE\",\n        \"value\": 0.991,\n        \"target\": 0.99,\n        \"status\": \"GOOD\"\n      }\n    ]\n  }\n}"}]},{"name":"List Report Requests","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests?report_type=ITEM","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests"],"query":[{"key":"report_type","value":"ITEM","description":"Report type to list requests for, e.g. ITEM, INVENTORY, BUYBOX, CPA, SHIPPING_CONFIGURATION, RETURN_OVERRIDES, PROMO. Required; the request fails with 422 when omitted.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the on-request report requests submitted for this integration instance, with their report type and processing status.\n\nQuery parameters:\n- report_type (string, required): report type to list requests for, e.g. ITEM, INVENTORY, BUYBOX, CPA, SHIPPING_CONFIGURATION, RETURN_OVERRIDES, PROMO. The request fails with 422 when omitted.\n- report_version (string, optional): filter to a specific report version, e.g. v1.\n- request_status (string, optional): filter by request processing status, e.g. RECEIVED, INPROGRESS, READY, ERROR.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests?report_type=ITEM","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests"],"query":[{"key":"report_type","value":"ITEM","description":"Report type to list requests for, e.g. ITEM, INVENTORY, BUYBOX, CPA, SHIPPING_CONFIGURATION, RETURN_OVERRIDES, PROMO. Required; the request fails with 422 when omitted.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requests\": [\n      {\n        \"requestId\": \"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a\",\n        \"reportType\": \"ITEM\",\n        \"requestStatus\": \"READY\",\n        \"requestSubmissionDate\": \"2026-07-15T10:00:00Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Create Report Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Create an on-request report request. Walmart generates the report asynchronously; poll its status with Get Report Request Status and fetch the file with Get Report Download URL once it is READY.\n\nFields:\n- report_type (string, required): the type of report to generate, e.g. ITEM.\n- report_version (string, optional): the report version; defaults to v1.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.sync` permission.","body":{"mode":"raw","raw":"{\n  \"report_type\": \"ITEM\",\n  \"report_version\": \"v1\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requestId\": \"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a\",\n    \"requestStatus\": \"RECEIVED\",\n    \"reportType\": \"ITEM\"\n  }\n}"}]},{"name":"Get Report Request Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests/{requestId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests",":requestId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"requestId","value":"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a","description":"Report request ID"}]},"description":"Get the current status of an on-request report request.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests/{requestId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests",":requestId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"requestId","value":"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a","description":"Report request ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requestId\": \"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a\",\n    \"requestStatus\": \"READY\"\n  }\n}"}]},{"name":"Get Report Download URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests/{requestId}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests",":requestId","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"requestId","value":"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a","description":"Report request ID"}]},"description":"Get a time-limited signed download URL for a completed report request. Download the report file from the returned URL before it expires.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/reports/requests/{requestId}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","reports","requests",":requestId","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"requestId","value":"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a","description":"Report request ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requestId\": \"8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a\",\n    \"downloadURL\": \"https://marketplace-reports.walmartapis.com/8b78e243-4c14-4a4a-8a27-fd3ebeef2f0a.zip?Signature=abc123\",\n    \"downloadURLExpirationTime\": \"2026-07-15T12:00:00Z\"\n  }\n}"}]},{"name":"Get Seller Health Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/insights/seller-health","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","insights","seller-health"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get an aggregated seller health summary — valid tracking rate, on-time delivery, on-time shipment, cancellation rate, refund rate, and seller response rate — over the requested reporting window. Each metric is fetched independently; if a single metric cannot be retrieved it is returned with an error key while the remaining metrics still succeed.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/insights/seller-health","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","insights","seller-health"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"vtr\": {\n      \"vtrRate\": 0.98\n    },\n    \"on_time_delivery\": {\n      \"otdRate\": 0.95\n    },\n    \"on_time_shipment\": {\n      \"rate\": 0.97\n    },\n    \"cancellations\": {\n      \"rate\": 0.01\n    },\n    \"refunds\": {\n      \"rate\": 0.02\n    },\n    \"seller_response_rate\": {\n      \"error\": \"Metric unavailable\"\n    }\n  }\n}"}]},{"name":"Get API Platform Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/platform-status","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","platform-status"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the current status of the Walmart marketplace API platform and its components.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/platform-status","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","platform-status"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"status\": \"OK\",\n    \"components\": [\n      {\n        \"name\": \"Orders\",\n        \"status\": \"OPERATIONAL\"\n      },\n      {\n        \"name\": \"Items\",\n        \"status\": \"OPERATIONAL\"\n      },\n      {\n        \"name\": \"Prices\",\n        \"status\": \"OPERATIONAL\"\n      }\n    ]\n  }\n}"}]},{"name":"List Supported Carriers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/carriers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","carriers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the carriers supported by Ship With Walmart for purchasing shipping labels.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/carriers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","carriers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"carriers\": [\n      {\n        \"carrierShortName\": \"UPS\",\n        \"carrierName\": \"United Parcel Service\"\n      }\n    ]\n  }\n}"}]},{"name":"List Shipping Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/templates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","templates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the shipping templates configured on Walmart for this integration instance. Templates are read-only here and are managed in Walmart Seller Center.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/templates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","templates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shippingTemplates\": [\n      {\n        \"shipmentTemplateId\": \"5f2d8a1e-9c47-4b6d-8e15-3a7b2c9d0f41\",\n        \"templateName\": \"Standard Shipping\",\n        \"status\": \"ACTIVE\"\n      }\n    ]\n  }\n}"}]},{"name":"List Fulfillment Centers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/fulfillment-centers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","fulfillment-centers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the fulfillment centers (ship nodes) configured on Walmart for this integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/fulfillment-centers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","fulfillment-centers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"shipNodes\": [\n      {\n        \"shipNode\": \"10001516180\",\n        \"shipNodeName\": \"Main Warehouse\",\n        \"status\": \"ACTIVE\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Shipping Estimates","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/estimates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","estimates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"Get carrier rate estimates for shipping an order. Send the package details (dimensions and weight, passed through to Walmart) and optionally a carrier; the order's purchase order ID is attached automatically.\n\nAuthentication: Requires Bearer token.\n\nRequires the `sales_orders.fulfill` permission.","body":{"mode":"raw","raw":"{\n  \"carrierShortName\": \"UPS\",\n  \"packageDimensions\": {\n    \"length\": 10,\n    \"width\": 6,\n    \"height\": 4,\n    \"unitOfMeasurement\": \"IN\"\n  },\n  \"packageWeight\": {\n    \"value\": 2.5,\n    \"unitOfMeasurement\": \"LB\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/estimates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","estimates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"estimates\": [\n      {\n        \"carrierShortName\": \"UPS\",\n        \"serviceType\": \"GROUND\",\n        \"totalCharges\": 8.42\n      }\n    ]\n  }\n}"}]},{"name":"List Order Shipping Labels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"List the shipping labels purchased for an order.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"labels\": [\n      {\n        \"trackingNo\": \"1Z999AA10123456784\",\n        \"carrierShortName\": \"UPS\",\n        \"labelStatus\": \"CREATED\"\n      }\n    ]\n  }\n}"}]},{"name":"Purchase Shipping Label","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]},"description":"Purchase a Ship With Walmart shipping label for an order shipment. Send the package details and the chosen carrier service; the order's purchase order ID is attached automatically.\n\nAuthentication: Requires Bearer token.\n\nRequires the `sales_orders.fulfill` permission.","body":{"mode":"raw","raw":"{\n  \"carrierShortName\": \"UPS\",\n  \"serviceType\": \"GROUND\",\n  \"packageDimensions\": {\n    \"length\": 10,\n    \"width\": 6,\n    \"height\": 4,\n    \"unitOfMeasurement\": \"IN\"\n  },\n  \"packageWeight\": {\n    \"value\": 2.5,\n    \"unitOfMeasurement\": \"LB\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/shipping/labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","shipping","labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"60","description":"Walmart order ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"trackingNo\": \"1Z999AA10123456784\",\n    \"labelStatus\": \"CREATED\",\n    \"labelDownloadURL\": \"https://marketplace.walmartapis.com/v3/shipping/labels/1Z999AA10123456784\"\n  }\n}"}]},{"name":"Download Shipping Label","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/labels/{carrier}/{trackingNumber}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","labels",":carrier",":trackingNumber","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"carrier","value":"UPS","description":"Carrier short name the label was purchased with"},{"key":"trackingNumber","value":"1Z999AA10123456784","description":"Tracking number of the purchased label"}]},"description":"Download a purchased shipping label as a PDF file. The response is the label document (Content-Type: application/pdf), not JSON.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/labels/{carrier}/{trackingNumber}/download","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","labels",":carrier",":trackingNumber","download"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"carrier","value":"UPS","description":"Carrier short name the label was purchased with"},{"key":"trackingNumber","value":"1Z999AA10123456784","description":"Tracking number of the purchased label"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 [binary PDF bytes — shipping label; not JSON]"}]},{"name":"Discard Shipping Label","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/labels/{carrier}/{trackingNumber}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","labels",":carrier",":trackingNumber"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"carrier","value":"UPS","description":"Carrier short name the label was purchased with"},{"key":"trackingNumber","value":"1Z999AA10123456784","description":"Tracking number of the purchased label"}]},"description":"Discard (void) a purchased shipping label so it is no longer used or billed. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `sales_orders.fulfill` permission."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/shipping/labels/{carrier}/{trackingNumber}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","shipping","labels",":carrier",":trackingNumber"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"carrier","value":"UPS","description":"Carrier short name the label was purchased with"},{"key":"trackingNumber","value":"1Z999AA10123456784","description":"Tracking number of the purchased label"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"status\": \"DISCARDED\"\n  }\n}"}]},{"name":"List Webhook Subscriptions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the Walmart event subscriptions for this integration instance. Each record is the local mirror of a subscription registered with Walmart, including its event type, status, destination URL, and reconciliation state.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"subscription_id\": \"0e5fc5f5-7d19-4bd0-a1f3-59a3c1e7b2c4\",\n      \"event_type\": \"PO_CREATED\",\n      \"event_version\": \"V1\",\n      \"resource_name\": \"ORDER\",\n      \"status\": \"ACTIVE\",\n      \"destination_url\": \"https://app.sku.io/webhooks/walmart/wh_abc123def456ghi789\",\n      \"last_reconciled_at\": \"2026-07-15T11:40:00+00:00\",\n      \"last_error\": null,\n      \"created_at\": \"2026-07-15T09:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Webhook Subscription","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Create a webhook subscription so Walmart delivers event notifications for this integration instance. The subscription is registered with Walmart and mirrored locally.\n\nFields:\n- event_type (string, required, max 100 characters): the Walmart event type to subscribe to, e.g. PO_CREATED.\n- event_version (string, optional): the event payload version; defaults to V1.\n- resource_name (string, optional): the resource the event relates to, e.g. ORDER.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission.","body":{"mode":"raw","raw":"{\n  \"event_type\": \"PO_CREATED\",\n  \"event_version\": \"V1\",\n  \"resource_name\": \"ORDER\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"subscription_id\": \"7c31a9d2-4e58-4f6b-9a10-2b8f0d3c5e77\",\n    \"event_type\": \"PO_CREATED\",\n    \"event_version\": \"V1\",\n    \"resource_name\": \"ORDER\",\n    \"status\": \"ACTIVE\",\n    \"destination_url\": \"https://app.sku.io/webhooks/walmart/wh_abc123def456ghi789\",\n    \"last_reconciled_at\": null,\n    \"last_error\": null,\n    \"created_at\": \"2026-07-15T11:45:00+00:00\"\n  }\n}"}]},{"name":"List Available Event Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/event-types","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","event-types"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"List the event types available for webhook subscription, fetched directly from Walmart.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/event-types","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","event-types"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"eventTypes\": [\n      {\n        \"eventType\": \"PO_CREATED\",\n        \"eventVersion\": \"V1\",\n        \"resourceName\": \"ORDER\"\n      }\n    ]\n  }\n}"}]},{"name":"Auto-Subscribe Default Events","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/auto-subscribe","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","auto-subscribe"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Subscribe this integration instance to every default event type Walmart offers. Event types that are already subscribed are skipped. No request body.\n\nThe response lists the event types that were subscribed, skipped, and failed, plus an errors map of event type to failure reason for each failed subscription.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/auto-subscribe","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","auto-subscribe"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"subscribed\": [\n    \"PO_CREATED\"\n  ],\n  \"skipped\": [\n    \"OFFER_UNPUBLISHED\"\n  ],\n  \"failed\": [\n    \"PO_LINE_AUTOCANCELLED\"\n  ],\n  \"errors\": {\n    \"PO_LINE_AUTOCANCELLED\": \"Walmart returned HTTP 500 while creating the subscription.\"\n  }\n}"}]},{"name":"Reconcile Webhook Subscriptions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/reconcile","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Reconcile the local subscription records against Walmart's subscription registry and repair any drift. Subscriptions found on Walmart but missing locally are adopted, local records no longer present on Walmart are flagged as missing, and matching records are confirmed. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/reconcile","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions","reconcile"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"adopted\": 0,\n  \"missing\": 1,\n  \"confirmed\": 4\n}"}]},{"name":"Delete Webhook Subscription","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/{subscription}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions",":subscription"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"subscription","value":"1","description":"Webhook subscription ID"}]},"description":"Delete a webhook subscription on Walmart and remove the local record.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/{subscription}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions",":subscription"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"subscription","value":"1","description":"Webhook subscription ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Send Test Notification","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/{subscription}/test","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions",":subscription","test"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"subscription","value":"1","description":"Webhook subscription ID"}]},"description":"Ask Walmart to deliver a test event notification for this subscription to its destination URL. Use this to verify the subscription is wired up end to end. No request body.\n\nAuthentication: Requires Bearer token.\n\nRequires the `integrations.update` permission."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/webhook-subscriptions/{subscription}/test","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","webhook-subscriptions",":subscription","test"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"subscription","value":"1","description":"Webhook subscription ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"eventType\": \"PO_CREATED\",\n  \"status\": \"SUCCESS\"\n}"}]},{"name":"List Walmart Integration Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a paginated activity history for a Walmart integration instance. Covers every Walmart entity tied to the instance — orders, catalog items, fulfillment locations, returns, and the integration settings themselves — newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach entry includes the event type (created, updated, deleted), the affected entity type and id, the changed attributes (with old values where available), the acting user's name (null for system/background changes), and a timestamp. Returns a paginated result."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10231,\n      \"log_name\": \"default\",\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WalmartProduct\",\n      \"subject_id\": 87,\n      \"properties\": {\n        \"attributes\": {\n          \"publishedStatus\": \"PUBLISHED\"\n        },\n        \"old\": {\n          \"publishedStatus\": \"UNPUBLISHED\"\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-06-30T09:12:45.000000Z\"\n    },\n    {\n      \"id\": 9812,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WalmartOrder\",\n      \"subject_id\": 412,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"Shipped\"\n        },\n        \"old\": {\n          \"status\": \"Acknowledged\"\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-06-28T14:03:22.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/activity-log?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://your-instance.test/api/walmart/1/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"List Walmart Supported Carriers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/supported-carriers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","supported-carriers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the shipping carriers Walmart accepts on shipment confirmations (UPS, USPS, FedEx, DHL, OnTrac, and many more), together with the current mapping of each Walmart carrier to a shipping method in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUse this to discover valid carrier values before submitting fulfillments, and to review which internal shipping methods will be reported to Walmart for each carrier. `shipping_methods` lists all shipping methods available for mapping. Returns 404 if the integration instance has no linked sales channel."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/supported-carriers","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","supported-carriers"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"carriers\": [\n      {\n        \"id\": 3,\n        \"sales_channel_method\": \"UPS\",\n        \"shipping_method_id\": 12,\n        \"shipping_method_name\": \"UPS Ground\"\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"USPS\",\n        \"shipping_method_id\": null,\n        \"shipping_method_name\": null\n      },\n      {\n        \"id\": null,\n        \"sales_channel_method\": \"FedEx\",\n        \"shipping_method_id\": null,\n        \"shipping_method_name\": null\n      }\n    ],\n    \"shipping_methods\": [\n      {\n        \"id\": 12,\n        \"full_name\": \"UPS Ground\"\n      },\n      {\n        \"id\": 17,\n        \"full_name\": \"USPS Ground Advantage\"\n      }\n    ]\n  }\n}"}]},{"name":"Start Tracked Walmart Location Refresh","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/locations/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","locations","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Refresh the list of Walmart fulfillment locations (ship nodes) for this integration instance from the Walmart Marketplace API. This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/locations/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","locations","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Location refresh job has been queued\"\n}"}]},{"name":"Start Tracked Walmart Order Refresh","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Pull orders from the Walmart Marketplace API into SKU.io. This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body (all fields optional):\n- mode — which orders to pull: `latest` (default; orders modified since the most recent local order), `from_start_date` (orders modified since the integration's configured start date), `date_range` (orders modified since `date_from`), or `all`.\n- date_from — start of the modification window (date). Used with mode `date_range`.\n- date_to — end of the window (date). Accepted for validation but the pull is open-ended from `date_from`.","body":{"mode":"raw","raw":"{\n  \"mode\": \"latest\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Order refresh job has been queued\"\n}"}]},{"name":"Get Walmart Orders Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a snapshot of the order sync state for this integration instance: the most recent Walmart order on record (id, order date, status), the total number of synced Walmart orders, and how many are (or are not yet) linked to a SKU.io sales order. Useful for deciding which refresh mode to run.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"1796277083022\",\n    \"latest_order_date\": \"2026-06-27T00:00:00.000000Z\",\n    \"latest_order_status\": \"Shipped\",\n    \"total_orders\": 1250,\n    \"with_sku_order\": 1198,\n    \"without_sku_order\": 52\n  }\n}"}]},{"name":"Bulk Archive Walmart Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Archive multiple Walmart orders in one call. Archived orders are hidden from active listings but remain available with their history. Only currently-active orders belonging to the integration instance are affected; already-archived orders are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- ids (required, array of integers) — the Walmart order ids (SKU.io internal ids) to archive.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    412,\n    413\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders archived successfully\",\n  \"archived_count\": 2\n}"}]},{"name":"Bulk Unarchive Walmart Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Restore multiple archived Walmart orders in one call. Only currently-archived orders belonging to the integration instance are affected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- ids (required, array of integers) — the Walmart order ids (SKU.io internal ids) to unarchive.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    412,\n    413\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 orders unarchived successfully\",\n  \"unarchived_count\": 2\n}"}]},{"name":"List Walmart Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]},"description":"Get the paginated activity history for a single Walmart order, newest first. Each entry includes the event type, changed attributes with old values, the acting user's name (null for system/background changes), and a timestamp.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","activity-log"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9812,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"WalmartOrder\",\n      \"subject_id\": 412,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"Shipped\"\n        },\n        \"old\": {\n          \"status\": \"Acknowledged\"\n        }\n      },\n      \"causer_name\": \"Jane Operator\",\n      \"created_at\": \"2026-06-28T14:03:22.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/orders/412/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/orders/412/activity-log?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://your-instance.test/api/walmart/1/orders/412/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Raw Walmart Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]},"description":"Fetch the order directly from the Walmart Marketplace API and return Walmart's raw purchase-order payload without any transformation. Useful for troubleshooting sync discrepancies — this is the live payload as Walmart returns it today, not the locally stored copy.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the order does not belong to the integration instance, and 500 if Walmart cannot be reached or rejects the request."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order\": {\n      \"purchaseOrderId\": \"1796277083022\",\n      \"customerOrderId\": \"200010536482277\",\n      \"customerEmailId\": \"0A31D21A44D449D9@relay.walmart.com\",\n      \"orderDate\": 1750982400000,\n      \"shippingInfo\": {\n        \"phone\": \"5555550123\",\n        \"estimatedDeliveryTime\": 1751673600000,\n        \"estimatedShipTime\": 1751068800000,\n        \"methodCode\": \"Value\",\n        \"postalAddress\": {\n          \"name\": \"Jane Smith\",\n          \"address1\": \"123 Main St\",\n          \"address2\": \"Apt 4B\",\n          \"city\": \"Dallas\",\n          \"state\": \"TX\",\n          \"postalCode\": \"75201\",\n          \"country\": \"USA\",\n          \"addressType\": \"RESIDENTIAL\"\n        }\n      },\n      \"orderLines\": {\n        \"orderLine\": [\n          {\n            \"lineNumber\": \"1\",\n            \"item\": {\n              \"productName\": \"Stainless Steel Water Bottle 32 oz\",\n              \"sku\": \"WB-32-SS\"\n            },\n            \"charges\": {\n              \"charge\": [\n                {\n                  \"chargeType\": \"PRODUCT\",\n                  \"chargeName\": \"ItemPrice\",\n                  \"chargeAmount\": {\n                    \"currency\": \"USD\",\n                    \"amount\": 24.99\n                  },\n                  \"tax\": {\n                    \"taxName\": \"Tax1\",\n                    \"taxAmount\": {\n                      \"currency\": \"USD\",\n                      \"amount\": 2.06\n                    }\n                  }\n                }\n              ]\n            },\n            \"orderLineQuantity\": {\n              \"unitOfMeasurement\": \"EACH\",\n              \"amount\": \"1\"\n            },\n            \"statusDate\": 1751155200000,\n            \"orderLineStatuses\": {\n              \"orderLineStatus\": [\n                {\n                  \"status\": \"Shipped\",\n                  \"statusQuantity\": {\n                    \"unitOfMeasurement\": \"EACH\",\n                    \"amount\": \"1\"\n                  },\n                  \"trackingInfo\": {\n                    \"shipDateTime\": 1751155200000,\n                    \"carrierName\": {\n                      \"carrier\": \"UPS\"\n                    },\n                    \"methodCode\": \"Value\",\n                    \"trackingNumber\": \"1Z999AA10123456784\"\n                  }\n                }\n              ]\n            }\n          }\n        ]\n      }\n    }\n  }\n}"}]},{"name":"Archive Walmart Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]},"description":"Archive a single Walmart order. Archived orders are hidden from active listings but remain available with their history. Returns whether the order was actually archived (`archived` is false when it was already archived). Returns 403 if the order does not belong to the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Walmart Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]},"description":"Restore a single archived Walmart order. Returns whether the order was actually restored (`unarchived` is false when it was already active). Returns 403 if the order does not belong to the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"order","value":"412","description":"Walmart order ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"List Pre-Start-Date Walmart Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Start of the order-creation window (date). Must be before the inventory start date.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Query the Walmart Marketplace API live for orders created before the account's inventory start date, within a chosen creation-date window. Returns lightweight order summaries with an eligibility assessment for import: cancelled orders are marked ineligible, and orders that already exist in SKU.io are flagged `already_imported`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUp to 2,000 matching orders are returned per query (Walmart pagination is followed for at most 10 pages). The inventory start date must be configured; both window bounds must fall before it (422 otherwise). Returns 500 if Walmart cannot be reached."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders?created_at_min=2025-10-01","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2025-10-01","description":"Required. Start of the order-creation window (date). Must be before the inventory start date.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_id\": \"1796277083022\",\n      \"customer_order_id\": \"200010536482277\",\n      \"name\": \"Jane Smith\",\n      \"email\": \"0A31D21A44D449D9@relay.walmart.com\",\n      \"created_at\": \"2025-11-14T18:20:00Z\",\n      \"order_status\": \"Delivered\",\n      \"total_price\": 49.98,\n      \"currency\": \"USD\",\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Steel Water Bottle 32 oz\",\n          \"sku\": \"WB-32-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": 24.99,\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Search Pre-Start-Date Walmart Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders/search?search_by=purchase_order_id&search_term=1796277083022","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"purchase_order_id","description":"Required. Field to search on: purchase_order_id (direct lookup), customer_order_id, or order_number.","disabled":true},{"key":"search_term","value":"1796277083022","description":"Required. The value to search for (1-255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Search the Walmart Marketplace API live for specific orders created before the inventory start date. `purchase_order_id` performs a direct order lookup; `customer_order_id` and `order_number` scan up to two years of pre-start-date orders and match on the given value.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults use the same summary shape and eligibility flags as the pre-start-date listing. The inventory start date must be configured (422 otherwise). Returns 500 if Walmart cannot be reached."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders/search?search_by=purchase_order_id&search_term=1796277083022","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"purchase_order_id","description":"Required. Field to search on: purchase_order_id (direct lookup), customer_order_id, or order_number.","disabled":true},{"key":"search_term","value":"1796277083022","description":"Required. The value to search for (1-255 characters).","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"purchase_order_id\": \"1796277083022\",\n      \"customer_order_id\": \"200010536482277\",\n      \"name\": \"Jane Smith\",\n      \"email\": \"0A31D21A44D449D9@relay.walmart.com\",\n      \"created_at\": \"2025-11-14T18:20:00Z\",\n      \"order_status\": \"Delivered\",\n      \"total_price\": 49.98,\n      \"currency\": \"USD\",\n      \"line_items\": [\n        {\n          \"title\": \"Stainless Steel Water Bottle 32 oz\",\n          \"sku\": \"WB-32-SS\",\n          \"quantity\": 2,\n          \"current_quantity\": 2,\n          \"price\": 24.99,\n          \"variant_title\": null\n        }\n      ],\n      \"eligible\": true,\n      \"eligibility_reason\": null,\n      \"already_imported\": false\n    }\n  ],\n  \"inventory_start_date\": \"2026-01-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Walmart Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Import selected pre-start-date orders from Walmart. For each purchase order id, the full order is downloaded from the Walmart Marketplace API, saved through the standard order pipeline, and flagged as a pre-start-date import (so it does not affect inventory).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBecause each order requires its own throttled Walmart Marketplace API call, the import runs asynchronously as a queued background job. The request returns immediately with a tracked job log id that can be polled to follow the import's progress.\n\n**Requires the inventory start date to be set** — returns 422 otherwise.\n\n**Path Parameters:**\n- `integrationInstance` - The Walmart integration instance ID\n\n**Request Body:**\n- `purchase_order_ids` (required, array of strings, 1-10,000 entries) — Walmart purchase order ids to import.\n\n**Behavior:**\n- Runs as a background import — the request returns right away with a tracked job log id; the orders are fetched and stored asynchronously\n- Orders that already exist locally are flagged as pre-start-date imports instead of being re-imported\n- Cancelled or not-found orders are skipped\n\n**Response:**\n- `data.tracked_job_log_id` - id of the tracked job log; poll it to follow import progress\n- `message` - human-readable confirmation of how many orders are being imported","body":{"mode":"raw","raw":"{\n  \"purchase_order_ids\": [\n    \"1796277083022\",\n    \"1796277083055\",\n    \"1796277083060\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Importing 2 pre-start-date orders.\"\n}"}]},{"name":"Start Tracked Walmart Product Refresh","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Pull the Walmart item catalog for this integration instance from the Walmart Marketplace API into SKU.io. This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Product refresh job has been queued\"\n}"}]},{"name":"Get Walmart Products Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a snapshot of the catalog sync state for this integration instance: the most recently updated Walmart item (title and update time), total synced items, and how many are mapped (or not yet mapped) to SKU.io products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Stainless Steel Water Bottle 32 oz\",\n    \"latest_product_date\": \"2026-06-29T21:15:03+00:00\",\n    \"total_products\": 340,\n    \"mapped_products\": 312,\n    \"unmapped_products\": 28,\n    \"last_synced_at\": \"2026-06-29T21:15:03+00:00\"\n  }\n}"}]},{"name":"List Orders for Walmart Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"87","description":"Walmart product ID (SKU.io internal id)"}]},"description":"Get a paginated list of Walmart orders that contain this Walmart item, matched by the item's SKU across the instance's order lines. Orders are returned newest first as stored order records, including Walmart identifiers, status, totals, and the stored raw payload (`json_object`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the product does not belong to the integration instance."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"87","description":"Walmart product ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 412,\n      \"integration_instance_id\": 1,\n      \"customerOrderId\": \"200010536482277\",\n      \"purchaseOrderId\": \"1796277083022\",\n      \"customerEmailId\": \"0A31D21A44D449D9@relay.walmart.com\",\n      \"customerName\": \"Jane Smith\",\n      \"estimatedDeliveryDate\": \"2026-07-05 00:00:00\",\n      \"estimatedShipDate\": \"2026-06-28 00:00:00\",\n      \"shipNodeType\": \"SellerFulfilled\",\n      \"status\": \"Shipped\",\n      \"orderDate\": \"2026-06-27T00:00:00.000000Z\",\n      \"currency\": \"USD\",\n      \"total\": \"27.05\",\n      \"syncStatus\": \"synced\",\n      \"pre_start_date_import\": false,\n      \"json_object\": {\n        \"purchaseOrderId\": \"1796277083022\",\n        \"customerOrderId\": \"200010536482277\"\n      },\n      \"created_at\": \"2026-06-27T02:14:55.000000Z\",\n      \"updated_at\": \"2026-06-28T11:40:19.000000Z\",\n      \"archived_at\": null\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/products/87/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/products/87/orders?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://your-instance.test/api/walmart/1/products/87/orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Sync Walmart Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/sync","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"87","description":"Walmart product ID (SKU.io internal id)"}]},"description":"Re-fetch a single item from the Walmart Marketplace API and update the local record with the latest data (title, price, identifiers, publish status). Runs synchronously and returns the refreshed item, including any mapped SKU.io product. If the item can no longer be found on Walmart, a message is returned and the local record is left unchanged.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/{product}/sync","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products",":product","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"product","value":"87","description":"Walmart product ID (SKU.io internal id)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 87,\n    \"integration_instance_id\": 1,\n    \"mart\": \"WALMART_US\",\n    \"sku\": \"WB-32-SS\",\n    \"condition\": \"New\",\n    \"wpid\": \"0RCPILAXM0C1\",\n    \"upc\": \"884912129123\",\n    \"gtin\": 884912129123,\n    \"productName\": \"Stainless Steel Water Bottle 32 oz\",\n    \"shelf\": \"[\\\"Home\\\",\\\"Kitchen & Dining\\\",\\\"Drinkware\\\"]\",\n    \"productType\": \"Water Bottles\",\n    \"priceCurrency\": \"USD\",\n    \"priceAmount\": 24.99,\n    \"publishedStatus\": \"PUBLISHED\",\n    \"lifecycleStatus\": \"ACTIVE\",\n    \"fulfillment_type\": \"seller_fulfilled\",\n    \"product_listing_id\": 902,\n    \"product\": {\n      \"id\": 45,\n      \"name\": \"Stainless Steel Water Bottle 32 oz\",\n      \"sku\": \"WB-32-SS\",\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 902\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-03-15T09:30:00.000000Z\",\n    \"mapped_sku\": \"WB-32-SS\",\n    \"json_object\": {\n      \"sku\": \"WB-32-SS\",\n      \"wpid\": \"0RCPILAXM0C1\"\n    },\n    \"created_at\": \"2026-03-14T10:02:31.000000Z\",\n    \"updated_at\": \"2026-06-30T08:12:44.000000Z\"\n  }\n}"}]},{"name":"Check Walmart Products Deleteable","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Check whether the given Walmart items can be deleted from SKU.io, before running a bulk delete. Returns one entry per item with a `deleteable` flag and a `reason` when deletion is blocked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n- ids (array of integers) — explicit Walmart product ids (must belong to the integration instance).\n- mode — set to \"all\" to check every Walmart item on the instance instead of passing ids.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    87,\n    88\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 87,\n      \"deleteable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 88,\n      \"deleteable\": true,\n      \"reason\": false\n    }\n  ]\n}"}]},{"name":"Get Walmart Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get the field-mapping configuration for a Walmart integration instance: which Walmart item fields (title, price, identifiers, and so on) populate which SKU.io product fields during catalog sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response includes the built-in default mappings, any custom overrides configured for this instance, and the effective mappings actually applied (defaults merged with overrides). `available_walmart_fields` and `available_sku_fields` describe every field that can be used on each side, grouped and typed."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Walmart US Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"productName\",\n        \"sku_field\": \"name\",\n        \"parsers\": [],\n        \"is_default\": true\n      },\n      {\n        \"listing_field\": \"priceAmount\",\n        \"sku_field\": \"price\",\n        \"parsers\": [],\n        \"is_default\": true\n      }\n    ],\n    \"available_walmart_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Walmart product SKU\",\n        \"group\": \"Identifiers\"\n      },\n      \"productName\": {\n        \"name\": \"productName\",\n        \"label\": \"Product Name\",\n        \"type\": \"string\",\n        \"description\": \"Walmart item title\",\n        \"group\": \"Details\"\n      },\n      \"upc\": {\n        \"name\": \"upc\",\n        \"label\": \"UPC\",\n        \"type\": \"string\",\n        \"description\": \"Universal Product Code\",\n        \"group\": \"Identifiers\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"description\": \"Product SKU\",\n        \"group\": \"Identifiers\"\n      },\n      \"name\": {\n        \"name\": \"name\",\n        \"label\": \"Name\",\n        \"type\": \"string\",\n        \"description\": \"Product name\",\n        \"group\": \"Details\"\n      },\n      \"price\": {\n        \"name\": \"price\",\n        \"label\": \"Price\",\n        \"type\": \"number\",\n        \"description\": \"Selling price\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"productName\",\n        \"sku_field\": \"name\",\n        \"parsers\": [],\n        \"is_default\": true\n      },\n      {\n        \"listing_field\": \"priceAmount\",\n        \"sku_field\": \"price\",\n        \"parsers\": [],\n        \"is_default\": true\n      }\n    ],\n    \"custom_mappings\": [],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"productName\",\n        \"sku_field\": \"name\",\n        \"parsers\": [],\n        \"is_default\": true\n      },\n      {\n        \"listing_field\": \"priceAmount\",\n        \"sku_field\": \"price\",\n        \"parsers\": [],\n        \"is_default\": true\n      }\n    ]\n  }\n}"}]},{"name":"Update Walmart Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Replace the custom field-mapping overrides for a Walmart integration instance. The submitted mappings are stored as instance-specific overrides on top of the built-in defaults; the response returns the resulting effective mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- mappings (required, array) — each entry: { listing_field (required string, a Walmart field name), sku_field (required string, a SKU.io product field name), parsers (optional array of value-transformation steps) }.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"productName\",\n      \"sku_field\": \"name\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"Walmart US Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"productName\",\n        \"sku_field\": \"name\",\n        \"parsers\": [],\n        \"is_default\": false\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"productName\",\n        \"sku_field\": \"name\",\n        \"parsers\": [],\n        \"is_default\": false\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Walmart Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a paginated list of completed fulfillments for sales orders that originated from this Walmart integration instance — both those already submitted to Walmart and those still pending. Each entry includes tracking details, carrier and shipping method, the linked sales order and Walmart order identifiers, the fulfilling warehouse, and a `sync_status` of submitted or pending.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 55,\n      \"fulfillment_number\": \"F-1042\",\n      \"fulfillment_type\": \"shipping\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"cost\": 8.45,\n      \"fulfilled_at\": \"2026-06-27T18:22:10+00:00\",\n      \"submitted_to_sales_channel_at\": \"2026-06-27T18:30:02+00:00\",\n      \"created_at\": \"2026-06-27T18:22:11+00:00\",\n      \"carrier\": \"UPS\",\n      \"shipping_method_display\": \"UPS Ground\",\n      \"sales_order\": {\n        \"id\": 3120,\n        \"sales_order_number\": \"SO-3120\"\n      },\n      \"walmart_order\": {\n        \"id\": 412,\n        \"purchaseOrderId\": \"1796277083022\",\n        \"customerOrderId\": \"200010536482277\"\n      },\n      \"warehouse\": {\n        \"id\": 5,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 12,\n        \"name\": \"UPS Ground\"\n      },\n      \"sync_status\": \"submitted\"\n    },\n    {\n      \"id\": 61,\n      \"fulfillment_number\": \"F-1057\",\n      \"fulfillment_type\": \"shipping\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"9400111899220123456781\",\n      \"cost\": 8.45,\n      \"fulfilled_at\": \"2026-06-27T18:22:10+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-27T18:22:11+00:00\",\n      \"carrier\": \"USPS\",\n      \"shipping_method_display\": \"USPS Ground Advantage\",\n      \"sales_order\": {\n        \"id\": 3120,\n        \"sales_order_number\": \"SO-3120\"\n      },\n      \"walmart_order\": {\n        \"id\": 412,\n        \"purchaseOrderId\": \"1796277083022\",\n        \"customerOrderId\": \"200010536482277\"\n      },\n      \"warehouse\": {\n        \"id\": 5,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 17,\n        \"name\": \"USPS Ground Advantage\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/fulfillments?page=5\",\n  \"next_page_url\": \"https://your-instance.test/api/walmart/1/fulfillments?page=2\",\n  \"path\": \"https://your-instance.test/api/walmart/1/fulfillments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 42\n}"}]},{"name":"List Pending Walmart Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a paginated list of completed fulfillments that have not yet been submitted to Walmart. Pickup fulfillments and fulfillments on cancelled orders are excluded. Results are ordered newest first. These are the fulfillments that the automatic sync (every 10 minutes) or a manual submit call will send to Walmart.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","pending"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 61,\n      \"fulfillment_number\": \"F-1057\",\n      \"fulfillment_type\": \"shipping\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"9400111899220123456781\",\n      \"cost\": 8.45,\n      \"fulfilled_at\": \"2026-06-27T18:22:10+00:00\",\n      \"submitted_to_sales_channel_at\": null,\n      \"created_at\": \"2026-06-27T18:22:11+00:00\",\n      \"carrier\": \"USPS\",\n      \"shipping_method_display\": \"USPS Ground Advantage\",\n      \"sales_order\": {\n        \"id\": 3120,\n        \"sales_order_number\": \"SO-3120\"\n      },\n      \"walmart_order\": {\n        \"id\": 412,\n        \"purchaseOrderId\": \"1796277083022\",\n        \"customerOrderId\": \"200010536482277\"\n      },\n      \"warehouse\": {\n        \"id\": 5,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shipping_method\": {\n        \"id\": 17,\n        \"name\": \"USPS Ground Advantage\"\n      },\n      \"sync_status\": \"pending\"\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/fulfillments/pending?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/fulfillments/pending?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://your-instance.test/api/walmart/1/fulfillments/pending\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 3\n}"}]},{"name":"Get Walmart Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get summary figures for fulfillment syncing on this integration instance: how many completed fulfillments are still waiting to be submitted to Walmart, and the automatic sync schedule.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_sync_count\": 3,\n    \"sync_schedule\": {\n      \"interval\": 10,\n      \"unit\": \"minutes\",\n      \"description\": \"Fulfillments are automatically synced every 10 minutes\"\n    }\n  }\n}"}]},{"name":"Submit Walmart Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"salesOrderFulfillment","value":"61","description":"Sales order fulfillment ID"}]},"description":"Submit a single completed fulfillment's shipment confirmation (carrier, tracking number, shipped lines) to Walmart. Only fulfillments that are completed, not yet submitted, not pickup-type, and linked to a non-cancelled Walmart order of this instance are accepted. On success the fulfillment is marked as submitted; on failure a 422 is returned with the reason.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/{salesOrderFulfillment}/submit","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments",":salesOrderFulfillment","submit"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"salesOrderFulfillment","value":"61","description":"Sales order fulfillment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Fulfillment #F-1057 submitted successfully\"\n}"}]},{"name":"Bulk Submit Walmart Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Submit multiple fulfillments' shipment confirmations to Walmart in one call. Each fulfillment is processed independently; the response reports how many were submitted and how many failed, with per-fulfillment error messages. Fulfillments that are already submitted, pickup-type, or on cancelled orders are ignored.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- ids (required, array of integers) — sales order fulfillment ids to submit. Each id must exist.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    61,\n    62\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","submit-bulk"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": false,\n  \"data\": {\n    \"submitted\": 1,\n    \"failed\": 1\n  },\n  \"errors\": [\n    {\n      \"id\": 62,\n      \"message\": \"Sales order is not linked to a Walmart order\"\n    }\n  ],\n  \"message\": \"1 fulfillment(s) submitted, 1 failed\"\n}"}]},{"name":"Submit All Pending Walmart Fulfillments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Submit every pending fulfillment for this integration instance to Walmart in one call — the same set returned by the pending listing. Each fulfillment is processed independently; the response reports totals plus per-fulfillment errors. Returns zeros when nothing is pending.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","fulfillments","submit-all"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"submitted\": 3,\n    \"failed\": 0\n  },\n  \"errors\": [],\n  \"message\": \"3 fulfillment(s) submitted, 0 failed\"\n}"}]},{"name":"List Walmart Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get a paginated inventory comparison for this Walmart integration instance — one row per SKU per Walmart fulfillment location — showing the SKU.io quantity next to the quantity Walmart currently has, the variance, and a per-row sync status (synced, variance, or needs_recalc).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRows cover every listed item across the instance's fulfillment locations. When the instance is configured to clamp negative inventory to zero, negative SKU.io quantities count as synced while Walmart shows 0. Returns an empty result when the instance has no fulfillment locations yet."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 3311,\n      \"product_listing_id\": 902,\n      \"document_id\": 87,\n      \"listing_sku\": \"WB-32-SS\",\n      \"title\": \"Stainless Steel Water Bottle 32 oz\",\n      \"product\": {\n        \"id\": 45,\n        \"sku\": \"WB-32-SS\",\n        \"name\": \"Stainless Steel Water Bottle 32 oz\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"10001096717\",\n      \"location_name\": \"Main Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 142,\n      \"sales_channel_quantity\": 138,\n      \"variance\": 4,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-30T06:00:12+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-30T05:45:01+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-29T22:10:44+00:00\",\n      \"created_at\": \"2026-03-14T10:02:31+00:00\",\n      \"updated_at\": \"2026-06-30T06:00:12+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://your-instance.test/api/walmart/1/inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 42,\n  \"last_page_url\": \"https://your-instance.test/api/walmart/1/inventory?page=42\",\n  \"next_page_url\": \"https://your-instance.test/api/walmart/1/inventory?page=2\",\n  \"path\": \"https://your-instance.test/api/walmart/1/inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 420\n}"}]},{"name":"Get Walmart Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get aggregate inventory-comparison statistics for this integration instance, counting SKU/location combinations: totals in sync, with variance, and needing recalculation, plus when Walmart quantities were last fetched and when SKU.io last pushed quantities to Walmart.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 420,\n    \"in_sync\": 391,\n    \"with_variance\": 24,\n    \"needs_recalculation\": 5,\n    \"last_fetch_at\": \"2026-06-30 05:45:01\",\n    \"last_sync_at\": \"2026-06-29 22:10:44\"\n  }\n}"}]},{"name":"List Walmart Inventory Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Get every Walmart fulfillment location (ship node) known for this integration instance, with its display name and whether it is currently active on Walmart. Use the returned ids as `filter[location_id]` values on the inventory comparison listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"10001096717\",\n      \"name\": \"Main Warehouse\",\n      \"is_active\": true\n    },\n    {\n      \"id\": \"10001096718\",\n      \"name\": \"East Coast DC\",\n      \"is_active\": false\n    }\n  ]\n}"}]},{"name":"Start Walmart Inventory Recache","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Recalculate SKU.io's sellable quantities for every Walmart listing/location on this integration instance and refresh the comparison cache. Run this when SKU.io quantities look stale or rows show needs_recalc. This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  }\n}"}]},{"name":"Get Walmart Inventory Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1234","description":"Job id returned when the recache was started"}]},"description":"Poll the progress of a previously started inventory recache. Returns the job's status (queued, processing, completed, failed), item counts, and a progress percentage. Returns 404 for an unknown job id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1234","description":"Job id returned when the recache was started"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"job_type\": \"walmart_inventory\",\n    \"queue\": \"default\",\n    \"job_name\": \"Walmart Inventory Recache\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": \"integration_instance\",\n      \"reference\": \"Walmart US Store\"\n    },\n    \"related_model_reference\": \"Walmart US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-30T06:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-30T06:00:00.000000Z\",\n    \"updated_at\": \"2026-06-30T06:00:15.000000Z\",\n    \"results\": null,\n    \"total_items\": 420,\n    \"processed_items\": 180,\n    \"progress_percentage\": 42.86,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Start Walmart Inventory Sync","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Push SKU.io quantities to Walmart for every listing/location with a variance on this integration instance, updating Walmart's available-to-sell figures. This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 1235\n  }\n}"}]},{"name":"Get Walmart Inventory Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1235","description":"Job id returned when the sync was started"}]},"description":"Poll the progress of a previously started inventory sync to Walmart. Returns the job's status (queued, processing, completed, failed), item counts, and a progress percentage. Returns 404 for an unknown job id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1235","description":"Job id returned when the sync was started"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"job_type\": \"walmart_inventory\",\n    \"queue\": \"default\",\n    \"job_name\": \"Walmart Inventory Sync\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": \"integration_instance\",\n      \"reference\": \"Walmart US Store\"\n    },\n    \"related_model_reference\": \"Walmart US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-30T06:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-30T06:00:00.000000Z\",\n    \"updated_at\": \"2026-06-30T06:00:15.000000Z\",\n    \"results\": null,\n    \"total_items\": 420,\n    \"processed_items\": 180,\n    \"progress_percentage\": 42.86,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Start Walmart Live Inventory Fetch","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Fetch current on-hand quantities from the Walmart Marketplace API for every listing/location on this integration instance and store them on the comparison rows (`sales_channel_quantity`). This queues an asynchronous background job and returns immediately. Poll progress using the returned tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","fetch-live"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fetch live inventory job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 1236\n  }\n}"}]},{"name":"Get Walmart Live Inventory Fetch Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1236","description":"Job id returned when the live fetch was started"}]},"description":"Poll the progress of a previously started live inventory fetch from Walmart. Returns the job's status (queued, processing, completed, failed), item counts, and a progress percentage. Returns 404 for an unknown job id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/inventory/fetch-live-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","inventory","fetch-live-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"trackedJobLogId","value":"1236","description":"Job id returned when the live fetch was started"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1234,\n    \"job_type\": \"walmart_inventory\",\n    \"queue\": \"default\",\n    \"job_name\": \"Walmart Live Inventory Fetch\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": \"integration_instance\",\n      \"reference\": \"Walmart US Store\"\n    },\n    \"related_model_reference\": \"Walmart US Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-30T06:00:01.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-30T06:00:00.000000Z\",\n    \"updated_at\": \"2026-06-30T06:00:15.000000Z\",\n    \"results\": null,\n    \"total_items\": 420,\n    \"processed_items\": 180,\n    \"progress_percentage\": 42.86,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"List Walmart Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/returns?filter[search]=&filter[status]=&filter[refund_status]=&sort=-created_at&page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","walmart",":id","returns"],"query":[{"key":"filter[search]","value":"","description":"Optional. Search by return ID or order number.","disabled":true},{"key":"filter[status]","value":"","description":"Optional. Filter by return status (e.g. INITIATED, RECEIVED, CANCELLED).","disabled":true},{"key":"filter[refund_status]","value":"","description":"Optional. Filter by refund status (e.g. REFUND_INITIATED, REFUND_PROCESSED, REFUND_DECLINED).","disabled":true},{"key":"sort","value":"-created_at","description":"Optional. Sort field. Prefix with - for descending. Available: id, created_at, updated_at.","disabled":true},{"key":"page","value":"1","description":"Page number for pagination.","disabled":true},{"key":"per_page","value":"10","description":"Number of results per page (default 10).","disabled":true}],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get a paginated list of Walmart customer returns for a specific integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWalmart returns are synced from the Walmart Marketplace API and represent customer-initiated return requests.\n\nEach return includes:\n- return_order_id: Walmart's return order identifier\n- return_date: Date the return was initiated\n- status: Current return status (INITIATED, RECEIVED, CANCELLED)\n- refund_status: Current refund processing status\n- return_type: Type of return (REPLACEMENT, REFUND, EXCHANGE)\n- line_items: Individual SKUs and quantities being returned\n\nRoute name: walmart.returns.index (via salesChannel macro)"}},{"name":"Refresh Walmart Returns","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/returns/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","returns","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Queue a tracked job that pulls the latest returns from the Walmart Marketplace Returns API (seller- and WFS-fulfilled). Read-only against Walmart. Track progress via the returned tracked_job_log_id via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/returns/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","returns","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 1234\n  },\n  \"message\": \"Walmart returns refresh started\"\n}"}]},{"name":"Refund Walmart Return","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/returns/{return}/refund","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","returns",":return","refund"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"return","value":"7","description":"Local Walmart return ID (numeric)"}]},"description":"Issue a refund against a Walmart Marketplace return order. Without a request body, every returned line is refunded at its full quantity. To refund only specific line(s) or quantities, send an optional `lines` array — each item has `returnOrderLineNumber` (integer, required) and `quantity` (integer ≥ 1, required). Reflects the refund status locally.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWFS-fulfilled returns are settled by Walmart and cannot be refunded here; attempting to refund one (or any Walmart-side failure) returns a 422 with the failure reason. The return must belong to the integration instance in the path (404 otherwise).\n\nRequires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"returnOrderLineNumber\": 1,\n      \"quantity\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/returns/{return}/refund","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","returns",":return","refund"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"return","value":"7","description":"Local Walmart return ID (numeric)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Refund issued\"\n}"}]},{"name":"Get WFS Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Get the WFS settings (enabled flag, sync cadence, default source warehouse, MCF flag, MCF order channel id) for an integration instance, plus the per-instance `webhook_url` the seller registers with Walmart so WFS inbound/inventory/return status changes are pushed in real time. Returns defaults when WFS is not yet configured. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"default_source_warehouse_id\": null,\n    \"mcf_enabled\": false,\n    \"mcf_order_channel_id\": null\n  },\n  \"webhook_url\": \"https://app.sku.io/webhooks/walmart/wh_aB3xY7zKqLmN0pQrStUvWxYz12345678\"\n}"}]},{"name":"Update WFS Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update WFS settings. Toggling `enabled` creates (true) or archives (false) the dedicated WFS warehouse. Disabling while the WFS warehouse holds stock or inbound shipments are in flight returns 409 requires_confirmation; resend with `force: true` to proceed. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"enabled\": false,\n  \"force\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"enabled\": true,\n    \"default_source_warehouse_id\": null,\n    \"mcf_enabled\": false,\n    \"mcf_order_channel_id\": null\n  },\n  \"message\": \"WFS settings saved\"\n}"}]},{"name":"List WFS Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/inventory","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Paginated WFS inventory snapshot for a Walmart integration instance. Quantities are pulled from Walmart per SKU + ship node and are read-only (Walmart owns the stock). Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/inventory","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","inventory"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 41,\n      \"sku\": \"ABC-001\",\n      \"product_id\": 1,\n      \"ship_node\": \"10002506668\",\n      \"available_quantity\": 320,\n      \"reserved_quantity\": 12,\n      \"inbound_quantity\": 100,\n      \"unfulfillable_quantity\": 2,\n      \"total_quantity\": 320,\n      \"last_synced_at\": \"2026-06-17T14:32:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Refresh WFS Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/inventory/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","inventory","refresh-tracked"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Queue a tracked job that re-syncs WFS inventory from Walmart for every WFS SKU (listings flagged WFS plus SKUs with existing WFS snapshots). Returns the tracked job log id. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/inventory/refresh-tracked","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","inventory","refresh-tracked"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12346\n  },\n  \"message\": \"WFS inventory refresh started\"\n}"}]},{"name":"Get WFS Replenishment Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Instance-default WFS replenishment tunables (target days of supply, buffer, lead time, case pack, velocity window). Returns defaults when not configured. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"target_days_of_supply\": 30,\n    \"buffer_days\": 7,\n    \"lead_time_days\": 14,\n    \"case_pack_qty\": 1,\n    \"velocity_window_days\": 30,\n    \"candidate_min_units\": 30\n  }\n}"}]},{"name":"Update WFS Replenishment Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Update instance-default replenishment tunables. All fields required; target_days_of_supply 1-365, buffer 0-180, lead_time 0-365, case_pack >=1, velocity_window 7-365. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"target_days_of_supply\": 45,\n  \"buffer_days\": 10,\n  \"lead_time_days\": 21,\n  \"case_pack_qty\": 24,\n  \"velocity_window_days\": 60\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment/settings","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment","settings"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"target_days_of_supply\": 30,\n    \"buffer_days\": 7,\n    \"lead_time_days\": 14,\n    \"case_pack_qty\": 1,\n    \"velocity_window_days\": 30,\n    \"candidate_min_units\": 30\n  }\n}"}]},{"name":"List WFS Replenishment Suggestions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Replenishment grid as a full-featured, server-side list view: one row per WFS SKU with its WFS position (available/inbound summed across ship nodes), demand velocity (units/day from matched-product sales over the velocity window), and the suggested quantity to send (velocity x coverage horizon - net WFS position, case-pack rounded). Supports search, advanced filter_groups, sorting, and pagination — all applied server-side over the computed columns. Returns a Laravel LengthAwarePaginator. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{id}/wfs/replenishment","host":["{{baseUrl}}"],"path":["api","walmart",":id","wfs","replenishment"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"WFS-ABC-001\",\n      \"product_id\": 1,\n      \"wfs_available\": 10,\n      \"wfs_inbound\": 0,\n      \"velocity_per_day\": 2,\n      \"target_days_of_supply\": 30,\n      \"suggested_quantity\": 92\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{base_url}}/api/walmart/1/wfs/replenishment?page=1\",\n  \"last_page_url\": \"{{base_url}}/api/walmart/1/wfs/replenishment?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{base_url}}/api/walmart/1/wfs/replenishment\"\n}"}]},{"name":"List WFS Replenishment Candidates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/replenishment/candidates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","replenishment","candidates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"WFS candidate intelligence as a full-featured, server-side list view: seller-fulfilled Walmart listings NOT yet in WFS that sell enough on the Walmart channel (>= candidate_min_units in the velocity window) to warrant sending into WFS. Ranked by Walmart-channel volume by default, with a suggested initial ship quantity (velocity x coverage, nothing on hand yet). Supports search, advanced filter_groups, sorting, and pagination — all applied server-side over the computed columns. Returns a Laravel LengthAwarePaginator. Empty when the instance has no linked sales channel. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/replenishment/candidates","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","replenishment","candidates"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"SELL-HOTTER\",\n      \"product_id\": 42,\n      \"product_name\": \"Aurora LED Strip 5m\",\n      \"units_in_window\": 300,\n      \"velocity_per_day\": 10,\n      \"window_days\": 30,\n      \"suggested_initial_quantity\": 510\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"{{base_url}}/api/walmart/1/wfs/replenishment/candidates?page=1\",\n  \"last_page_url\": \"{{base_url}}/api/walmart/1/wfs/replenishment/candidates?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{base_url}}/api/walmart/1/wfs/replenishment/candidates\"\n}"}]},{"name":"WFS Recommended Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products/recommendations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products","recommendations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Walmart's WFS restock recommendations for the inbound builder's \"Recommended items\" modal — items running low at WFS with days of supply, stock status, and Walmart's suggested send quantities, joined to the local product (product_id) so a recommendation can be added straight to the cart.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nProxies Walmart's GET /v3/wfs/recommendation/restock with showInsights=true (no caching). Returns an empty data array when Walmart has no recommendations. A Walmart API failure returns 422 with a message.\n\nResponse fields per item: sku, gtin, item_name, brand, stock_status (e.g. 'At Risk'), days_of_supply, suggested_units, forecasted_sales_lift, customer_favorite, product_id (local product id or null).\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-products/recommendations","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-products","recommendations"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"gtin\": 894147009695,\n      \"item_name\": \"Charlie Banana Baby Washable Diaper\",\n      \"brand\": \"Charlie Banana\",\n      \"stock_status\": \"At Risk\",\n      \"days_of_supply\": 9,\n      \"suggested_units\": 40,\n      \"forecasted_sales_lift\": 120.5,\n      \"customer_favorite\": true,\n      \"product_id\": 512\n    }\n  ]\n}"}]},{"name":"Portal — Download WFS Unit-Mix Spreadsheet (CSV, public)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/unit-mix.csv","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","unit-mix.csv"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"<portal-token>","description":"The packet's revocable portal token"}]},"description":"PUBLIC. Downloads the unit-mix spreadsheet (CSV) for the WFS inbound shipment so the 3PL / supplier can reconcile what to pack. Columns: SKU, Product, GTIN/UPC, Qty, Packing, Units per case, Unit weight, Unit dimensions, Prep services — plus a Kitting Work Order section when the shipment contains kits. Streamed as text/csv with filename wfs-unit-mix-&lt;shipmentId>.csv. Returns 404 if the portal token is invalid or has been revoked."}},{"name":"Portal — Submit WFS Box Contents (public)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/box-contents","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","box-contents"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"<portal-token>","description":"The packet's revocable portal token"}]},"description":"PUBLIC. The 3PL/supplier reports what they packed in each box. Body: boxes[] each { box_number (int), lines[] of { sku, quantity } }. Moves the packet to In Progress and unlocks the ready-to-ship acknowledgement.","body":{"mode":"raw","raw":"{\n  \"boxes\": [\n    {\n      \"box_number\": 1,\n      \"lines\": [\n        {\n          \"sku\": \"ABC-001\",\n          \"quantity\": 5\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/box-contents","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","box-contents"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"<portal-token>","description":"The packet's revocable portal token"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"reference\": \"8973354WFA\",\n    \"inbound_order_id\": \"01KVV71P30GJ95KMT429EY76AK\",\n    \"source_name\": \"3PL East\",\n    \"source_type\": \"3pl\",\n    \"destination_fc\": \"KY1\",\n    \"status\": \"in_progress\",\n    \"build_required\": false,\n    \"kit_build_manifest\": [],\n    \"instructions\": \"WALMART WFS INBOUND — PREP INSTRUCTIONS\\n...\",\n    \"line_items\": [\n      {\n        \"sku\": \"ABC-001\",\n        \"name\": \"Blue Jeans\",\n        \"quantity\": 12\n      }\n    ],\n    \"documents\": [\n      {\n        \"id\": 2,\n        \"type\": \"instructions\",\n        \"type_label\": \"Prep Instructions\",\n        \"stage\": \"initial\",\n        \"status\": \"ready\"\n      }\n    ],\n    \"box_contents_submission\": [\n      {\n        \"box_number\": 1,\n        \"lines\": [\n          {\n            \"sku\": \"ABC-001\",\n            \"quantity\": 5\n          }\n        ]\n      }\n    ],\n    \"can_confirm\": true,\n    \"confirm_blocked_reason\": null,\n    \"acknowledged_at\": null\n  },\n  \"message\": \"Box contents submitted.\"\n}"}]},{"name":"Print WFS GTIN Item Labels (shipment)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"SKU.io WFS inbound shipment ID"}]},"description":"Render printable GTIN item labels (PDF) for a WFS inbound shipment's lines — the detail page's \"Item labels\" print-all. Defaults to ONE LABEL PER UNIT of every intent line when the body is empty; pass items to override per-SKU label counts (per-row printing).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body (all optional):\n- items (array, 1–500) — each: { sku (required string), quantity (required integer 1–3000) }. Omit to print every line at its full quantity.\n- format: 'letter_30' (default) or 'thermal_2_25x1_25'.\n\n404 when the shipment belongs to another integration instance; 422 when the shipment has no lines (e.g. synced from Walmart without local intent lines) or a SKU lacks a GTIN/UPC. Response is the raw PDF (application/pdf). See the ad-hoc variant for label/symbology details. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"quantity\": 12\n    }\n  ],\n  \"format\": \"thermal_2_25x1_25\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/{shipment}/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments",":shipment","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"shipment","value":"42","description":"SKU.io WFS inbound shipment ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 … (binary PDF stream — the generated GTIN label sheet)"}]},{"name":"Print WFS GTIN Item Labels (ad-hoc)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Render printable GTIN item labels (PDF) for arbitrary WFS-bound SKUs — the inbound builder's per-row \"Print GTIN label\". Walmart exposes NO item-label API (Seller Center only), but WFS item labels are plain GTIN-14 / UPC-12 barcodes (no FNSKU-style Walmart identifier), so SKU.io renders the PDF locally from the listing's GTIN/UPC (fallback UPC → product barcode), mirroring the Amazon FBA item-label UX.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- items (required, array, 1–500) — each: { sku (required string), quantity (required integer 1–3000) — number of labels to print for that SKU }.\n- format (optional): 'letter_30' (default — Avery-5160-style letter sheet, 30 labels of 2⅝\" × 1\") or 'thermal_2_25x1_25' (one 2¼\" × 1¼\" label per page).\n\nHard cap 3,000 labels per render. Barcode symbology is chosen by code length (12 → UPC-A, 13 → EAN-13, 14 → ITF-14, else Code 128). Each label shows product name, barcode, the numeric GTIN/UPC, and the SKU.\n\nResponse is the raw PDF (Content-Type: application/pdf, attachment). A SKU without a GTIN/UPC returns 422 before any rendering. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"quantity\": 24\n    }\n  ],\n  \"format\": \"letter_30\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 … (binary PDF stream — the generated GTIN label sheet)"}]},{"name":"Portal — Print WFS GTIN Item Labels (public)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]},"description":"Self-service GTIN item labels from the PUBLIC fulfillment portal — the 3PL/supplier prints the barcode label sheet (PDF) straight from the portal, no login. Mirrors the authenticated \"Print WFS GTIN Item Labels (shipment)\" download. Defaults to ONE LABEL PER UNIT of every shipment line when the body is empty; pass items to override per-SKU label counts (per-row printing).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWalmart has no item-label API — SKU.io renders the GTIN/UPC barcode PDF locally, so the response is the raw PDF (application/pdf), not JSON. Each label encodes the product's GTIN, falling back to UPC, then the product barcode.\n\nRequest body (all optional):\n- items (array, 1–500) — each: { sku (required string, max 255), quantity (required integer 1–3000) }.\n- format: 'letter_30' (default) or 'thermal_2_25x1_25'.\n\nPublic, token-gated endpoint — NO bearer auth. The :token gates packet access; tenant is resolved by request host. 404 when the token is invalid/expired; 422 when the shipment has no lines or a SKU lacks a GTIN/UPC/barcode.","body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"sku\": \"WIDGET-BLUE-500\",\n      \"quantity\": 12\n    }\n  ],\n  \"format\": \"thermal_2_25x1_25\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inbound-shipments/fulfillment-portal/{token}/item-labels","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inbound-shipments","fulfillment-portal",":token","item-labels"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"token","value":"a1b2c3d4e5","description":"Portal access token that gates this packet (revocable, expiring)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"%PDF-1.4 … (binary PDF stream — the generated GTIN label sheet)"}]},{"name":"List WFS Inventory Log Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/log?sku=ABC-001","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","log"],"query":[{"key":"sku","value":"ABC-001","description":"Required. Seller SKU; resolved to its GTIN before querying Walmart.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"The WFS inventory transaction log for a single SKU (resolved to its GTIN), pulled live from Walmart and capped at 50 rows. `sku` is required; `transaction_type` optionally narrows to one transaction type. A missing/unresolvable SKU or Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/log?sku=ABC-001","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","log"],"query":[{"key":"sku","value":"ABC-001","description":"Required. Seller SKU; resolved to its GTIN before querying Walmart.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"transaction_type\": \"Inbound\",\n      \"quantity\": 100,\n      \"reason\": \"Inbound receipt\",\n      \"ship_node\": \"NJ3\",\n      \"event_time\": \"2026-06-15T14:32:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Get WFS Inventory Health Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/health-report","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","health-report"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Download the WFS Inventory Health report (aged / long-term-storage exposure) Walmart generates. Returns the raw file as a download (Content-Disposition attachment) — CSV when Walmart returns CSV, or ZIP when Walmart returns a zipped report (filename wfs-inventory-health.csv or .zip accordingly). Not a JSON envelope. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/health-report","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","health-report"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"sku,gtin,available_qty,aged_90_plus,long_term_storage_fee\nABC-001,00689107230963,320,40,12.50"}]},{"name":"List WFS Compliance Holds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/compliance-holds","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","compliance-holds"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Search items on a WFS compliance hold (WERCS / hazmat) so they can be excluded from replenishment, pulled live from Walmart. `search` is optional and matched against `field` (sku or gtin, default sku). A Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/inventory/compliance-holds","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","inventory","compliance-holds"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"ABC-001\",\n      \"gtin\": 689107230963,\n      \"hold_type\": \"WERCS\",\n      \"reason\": \"Awaiting hazmat classification.\"\n    }\n  ]\n}"}]},{"name":"List MCF Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]},"description":"Paginated WFS MCF orders for an integration instance. Supports free-text search (filter[search] spans customer_order_no + customer_order_id), advanced filters via filter_groups (columns: customer_order_no, customer_order_id, status, created_at), and sorting (allowed: id, customer_order_no, customer_order_id, status, created_at, updated_at; default -created_at). `can_cancel` is true while the order still has items and is not yet CANCELLED/SHIPPED/DELIVERED. Returns a Laravel LengthAwarePaginator. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"customer_order_no\": \"CO-1001\",\n      \"customer_order_id\": \"118123456789012\",\n      \"request_id\": \"req-abc-123\",\n      \"status\": \"CREATED\",\n      \"can_cancel\": true,\n      \"item_count\": 2,\n      \"destination_address\": {\n        \"name\": \"Jane Doe\",\n        \"address1\": \"1 Market St\",\n        \"city\": \"Newark\",\n        \"state\": \"NJ\",\n        \"postal_code\": \"07102\",\n        \"country\": \"US\"\n      },\n      \"fulfillment_order_id\": \"FO-77001\",\n      \"created_at\": \"2026-06-18T19:05:00.000000Z\",\n      \"updated_at\": \"2026-06-18T19:05:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Get MCF Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]},"description":"Fetch a single WFS MCF order by id, scoped to the integration instance (404 if it belongs to another instance). Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"customer_order_no\": \"CO-1001\",\n    \"customer_order_id\": \"118123456789012\",\n    \"request_id\": \"req-abc-123\",\n    \"status\": \"SHIPPED\",\n    \"can_cancel\": false,\n    \"cancel_blocked_reason\": \"This shipment can no longer be cancelled.\",\n    \"item_count\": 2,\n    \"destination_address\": {\n      \"name\": \"Jane Doe\",\n      \"address1\": \"1 Market St\",\n      \"city\": \"Newark\",\n      \"state\": \"NJ\",\n      \"postal_code\": \"07102\",\n      \"country\": \"US\"\n    },\n    \"fulfillment_order_id\": \"FO-77001\",\n    \"created_at\": \"2026-06-18T19:05:00.000000Z\",\n    \"updated_at\": \"2026-06-19T09:12:00.000000Z\"\n  }\n}"}]},{"name":"Cancel MCF Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/cancel","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","cancel"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]},"description":"Cancel an MCF order on Walmart and reflect the cancellation locally. No request body. Scoped to the integration instance (404 if it belongs to another instance). Walmart rejects the cancel once the order has shipped/delivered/already-cancelled — that returns a 422. Returns the updated order resource. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/cancel","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","cancel"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"customer_order_no\": \"CO-1001\",\n    \"customer_order_id\": \"118123456789012\",\n    \"request_id\": \"req-abc-123\",\n    \"status\": \"CANCELLED\",\n    \"can_cancel\": false,\n    \"cancel_blocked_reason\": \"This shipment can no longer be cancelled.\",\n    \"item_count\": 2,\n    \"destination_address\": null,\n    \"fulfillment_order_id\": \"FO-77001\",\n    \"created_at\": \"2026-06-18T19:05:00.000000Z\",\n    \"updated_at\": \"2026-06-20T08:00:00.000000Z\"\n  },\n  \"message\": \"MCF order cancelled\"\n}"}]},{"name":"Sync MCF Order Status","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/sync-status","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","sync-status"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]},"description":"Pull the latest status for an MCF order from Walmart and update the local record. No request body. Scoped to the integration instance (404 if it belongs to another instance). A Walmart-side failure returns a 422. Returns the updated order resource. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/sync-status","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","sync-status"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"customer_order_no\": \"CO-1001\",\n    \"customer_order_id\": \"118123456789012\",\n    \"request_id\": \"req-abc-123\",\n    \"status\": \"DELIVERED\",\n    \"can_cancel\": false,\n    \"cancel_blocked_reason\": \"This shipment can no longer be cancelled.\",\n    \"item_count\": 2,\n    \"destination_address\": null,\n    \"fulfillment_order_id\": \"FO-77001\",\n    \"created_at\": \"2026-06-18T19:05:00.000000Z\",\n    \"updated_at\": \"2026-06-21T11:30:00.000000Z\"\n  },\n  \"message\": \"MCF order status synced\"\n}"}]},{"name":"Fetch MCF Order Promise Options","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/promise-options","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","promise-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]},"description":"Re-check Walmart's delivery-promise / fulfillability options for an MCF order (which shipping speeds Walmart can still honour from WFS stock). No request body. Scoped to the integration instance (404 if it belongs to another instance). A Walmart-side failure returns a 422. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/walmart/{integrationInstance}/wfs/mcf-orders/{mcfOrder}/promise-options","host":["{{baseUrl}}"],"path":["api","walmart",":integrationInstance","wfs","mcf-orders",":mcfOrder","promise-options"],"variable":[{"key":"integrationInstance","value":"1","description":"Walmart integration instance ID"},{"key":"mcfOrder","value":"5","description":"Local WFS MCF order ID (numeric)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shipping_speed\": \"STANDARD\",\n      \"available\": true,\n      \"promised_delivery_date\": \"2026-06-26\"\n    },\n    {\n      \"shipping_speed\": \"EXPEDITED\",\n      \"available\": false,\n      \"promised_delivery_date\": null\n    }\n  ]\n}"}]},{"name":"Receive Walmart Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/webhooks/walmart/{webhook_token}","host":["{{baseUrl}}"],"path":["webhooks","walmart",":webhook_token"],"variable":[{"key":"webhook_token","value":"wh_aB3xY7zKqLmN0pQrStUvWxYz12345678","description":"Opaque per-instance secret token (format wh_[A-Za-z0-9]+) from Get WFS Settings → webhook_url. Unknown tokens 404."}]},"description":"Receive a Walmart WFS webhook delivery. No Bearer auth — the secret path token is the credential. The body shape is whatever Walmart sends; the receiver classifies the delivery into a coarse bucket (inbound / inventory / return / order / unknown) by keyword-matching the `eventType` (or `topic`/`type`) field, persists it, and dispatches a resync. An unrecognised event type triggers a full WFS resync so nothing is missed. Always acks 2xx on success so Walmart does not retry; unknown tokens return 404.","body":{"mode":"raw","raw":"{\n  \"eventType\": \"WFS_INBOUND_SHIPMENT_STATUS\",\n  \"shipmentId\": \"IB-123456\",\n  \"status\": \"RECEIVED\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/webhooks/walmart/{webhook_token}","host":["{{baseUrl}}"],"path":["webhooks","walmart",":webhook_token"],"variable":[{"key":"webhook_token","value":"wh_aB3xY7zKqLmN0pQrStUvWxYz12345678","description":"Opaque per-instance secret token (format wh_[A-Za-z0-9]+) from Get WFS Settings → webhook_url. Unknown tokens 404."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"received\": true\n}"}]},{"name":"Get Walmart Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/walmart/dashboard?integration_instance_ids=1,2&period=7d","host":["{{baseUrl}}"],"path":["api","walmart","dashboard"],"query":[{"key":"integration_instance_ids","value":"1,2","description":"Optional. Comma-separated list of integration instance IDs to filter by. Omit for all instances.","disabled":true},{"key":"period","value":"7d","description":"Optional. Time period filter. Valid values: today, 7d, 30d. Returns 422 for invalid values.","disabled":true}]},"description":"Get aggregated dashboard metrics across all Walmart integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns order counts, revenue metrics, and sync status per instance.\n\nPeriod validation: Must be one of today, 7d, or 30d. Invalid values return a 422 error.\n\nSync summary: the response includes sync_summary.auto_sync.schedules with one entry per sync type — orders (300s interval), products (86400s), and inventory (900s) — each carrying interval_seconds and seconds_until_next, which the frontend uses to render the \"Next auto-sync in ...\" countdown. Orders/products countdowns derive from the sync cursor's last completion; inventory runs on a splayed every-15-minutes cron (ScheduleSplay::offset('walmart') minutes past each quarter-hour, currently :04/:19/:34/:49), so its countdown targets those offset boundaries.\n\nRoute name: walmart.dashboard"}}]},{"name":"Magento","item":[{"name":"Download Orders","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/download-orders","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","download-orders"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]},"description":"Download Magento orders by increment_id. Dispatches a synchronous job to fetch the specified orders from Magento and create/update them in SKU.\n\nAuthentication: Requires Bearer token with power user access.\n\nRequest Body:\n- increment_ids (required, array): Array of Magento order increment IDs to download","body":{"mode":"raw","raw":"{\n  \"increment_ids\": [\n    \"100000001\",\n    \"100000002\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/download-orders","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","download-orders"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully downloaded magento orders\"\n}"}]},{"name":"Download Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/download-products","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","download-products"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]},"description":"Download Magento products by ID or SKU. Provide either 'ids' (entity_id) or 'skus', not both.\n\nAuthentication: Requires Bearer token with power user access.\n\nRequest Body (at least one required):\n- ids (array): Array of Magento product entity IDs\n- skus (array): Array of Magento product SKUs","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    123,\n    456\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/download-products","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","download-products"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully downloaded magento products\"\n}"}]},{"name":"List Inventory Sources","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/inventory-sources","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","inventory-sources"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]},"description":"Returns the locally stored Magento inventory sources and the integration settings inventory sources for the given integration instance.\n\nAuthentication: Requires Bearer token with power user access."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/inventory-sources","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","inventory-sources"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"magentoSources\": [\n      {\n        \"id\": 1,\n        \"integration_instance_id\": 1,\n        \"source_code\": \"default\",\n        \"name\": \"Default Source\",\n        \"enabled\": true\n      }\n    ],\n    \"inventorySources\": [\n      {\n        \"source_code\": \"default\",\n        \"name\": \"Default Source\"\n      }\n    ]\n  }\n}"}]},{"name":"Download Inventory Sources","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/inventory-sources","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","inventory-sources"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]},"description":"Downloads inventory sources from Magento API and stores them locally, then refreshes the integration instance settings. Returns the updated inventory sources list.\n\nAuthentication: Requires Bearer token with power user access."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/inventory-sources","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","inventory-sources"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"magentoSources\": [\n      {\n        \"id\": 1,\n        \"integration_instance_id\": 1,\n        \"source_code\": \"default\",\n        \"name\": \"Default Source\",\n        \"enabled\": true\n      }\n    ],\n    \"inventorySources\": [\n      {\n        \"source_code\": \"default\",\n        \"name\": \"Default Source\"\n      }\n    ]\n  }\n}"}]},{"name":"List Product Attributes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/product-attributes","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","product-attributes"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]},"description":"Returns the Magento product attributes for the given integration instance.\n\nAuthentication: Requires Bearer token with power user access."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento/{integration_instance}/product-attributes","host":["{{baseUrl}}"],"path":["api","magento",":integration_instance","product-attributes"],"variable":[{"key":"integration_instance","value":"1","description":"Magento integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"attribute_code\": \"color\",\n      \"default_frontend_label\": \"Color\",\n      \"attribute_id\": 93\n    },\n    {\n      \"attribute_code\": \"size\",\n      \"default_frontend_label\": \"Size\",\n      \"attribute_id\": 144\n    }\n  ]\n}"}]}]},{"name":"TikTok Shop","item":[{"name":"Get Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/config","host":["{{baseUrl}}"],"path":["api","tiktok-shop","config"]},"description":"Returns the public OAuth config (app_key, redirect_url) for the requested environment. the application UI uses this to build the TikTok authorization URL.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery: environment (sandbox|production, default sandbox).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/config","host":["{{baseUrl}}"],"path":["api","tiktok-shop","config"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"environment\": \"production\",\n    \"app_key\": \"tt_app_key_xxx\",\n    \"redirect_url\": \"https://app.sku.io/tiktok-shop/callback\"\n  }\n}"}]},{"name":"OAuth Init","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/oauth/init","host":["{{baseUrl}}"],"path":["api","tiktok-shop","oauth","init"]},"description":"Generates a state UUID, caches it for 15 minutes, and returns the TikTok authorization URL the user should be redirected to. Optionally accepts an integration_instance_id to re-link an existing instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/oauth/init","host":["{{baseUrl}}"],"path":["api","tiktok-shop","oauth","init"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorization_url\": \"https://services.tiktokshop.com/open/authorize?service_id=...&state=8c7...\",\n    \"state\": \"8c7e0d12-b91c-4d2b-a6f4-9c0a2bb1f0aa\"\n  }\n}"}]},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances"]},"description":"List Integration Instances\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Returns a single integration instance with integration and salesChannel relations.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Acme TikTok Shop\",\n    \"integration_id\": 17,\n    \"environment\": \"production\",\n    \"open_id\": \"7211223344556677\",\n    \"seller_name\": \"Acme Co.\",\n    \"has_access_token\": true,\n    \"access_token_expires_at\": \"2026-05-26T10:00:00+00:00\",\n    \"refresh_token_expires_at\": \"2027-04-26T10:00:00+00:00\",\n    \"integration_settings\": {\n      \"submit_tracking\": true\n    },\n    \"created_at\": \"2026-04-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-04-26T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Patch-update name and/or integration_settings. integration_settings is deep-merged into the existing JSON.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- name (sometimes, string, max 255)\n- integration_settings (sometimes, array)\n- integration_settings.* (nullable)\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme TikTok Shop (US)\",\n  \"integration_settings\": {\n    \"submit_tracking\": true,\n    \"default_warehouse_id\": 5\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Acme TikTok Shop\",\n    \"integration_id\": 17,\n    \"environment\": \"production\",\n    \"open_id\": \"7211223344556677\",\n    \"seller_name\": \"Acme Co.\",\n    \"has_access_token\": true,\n    \"access_token_expires_at\": \"2026-05-26T10:00:00+00:00\",\n    \"refresh_token_expires_at\": \"2027-04-26T10:00:00+00:00\",\n    \"integration_settings\": {\n      \"submit_tracking\": true\n    },\n    \"created_at\": \"2026-04-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-04-26T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Deletes the integration instance. Webhook unsubscribe is best-effort — local delete proceeds even on remote failure.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": true\n  }\n}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/dashboard","host":["{{baseUrl}}"],"path":["api","tiktok-shop","dashboard"]},"description":"Aggregate dashboard metrics for one or many TikTok Shop connections: the connection summaries, synced entity counts (orders, products, returns, refunds, transactions, shops), a financial summary (gross/net revenue, refunds, units sold) for an optional period, and per-entity sync health.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:**\n- `integration_instance_ids` (optional, comma-separated integers) — limit to specific connections; omit for all.\n- `period` (optional, one of `today`, `7d`, `30d`) — window for the financial summary; omit for all time. Invalid values return 422.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/dashboard","host":["{{baseUrl}}"],"path":["api","tiktok-shop","dashboard"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"integrations\": [\n      {\n        \"id\": 12,\n        \"name\": \"TikTok Shop US\",\n        \"shop_url\": \"https://seller-us.tiktok.com\",\n        \"shop_name\": \"Acme Official Store\",\n        \"shop_id\": \"7495632100001\",\n        \"shop_cipher\": \"ROW_XXXXXXXXX\",\n        \"shop_region\": \"US\",\n        \"seller_id\": \"7493311000002\",\n        \"is_automatic_sync_enabled\": true,\n        \"has_warehouse_mappings\": true,\n        \"integration_settings\": {\n          \"orders_start_date\": \"2026-01-01\"\n        },\n        \"created_at\": \"2026-03-02T18:20:00+00:00\",\n        \"updated_at\": \"2026-06-20T08:00:00+00:00\"\n      }\n    ],\n    \"entity_counts\": {\n      \"entities\": {\n        \"orders\": {\n          \"display_name\": \"orders\",\n          \"total\": 1840\n        },\n        \"products\": {\n          \"display_name\": \"products\",\n          \"total\": 312\n        },\n        \"returns\": {\n          \"display_name\": \"returns\",\n          \"total\": 45\n        },\n        \"refunds\": {\n          \"display_name\": \"refunds\",\n          \"total\": 38\n        },\n        \"transactions\": {\n          \"display_name\": \"transactions\",\n          \"total\": 1720\n        },\n        \"shops\": {\n          \"display_name\": \"shops\",\n          \"total\": 1\n        }\n      },\n      \"totals\": {\n        \"total_records\": 3956\n      }\n    },\n    \"financial_summary\": {\n      \"gross_revenue\": 48210.55,\n      \"total_refunds\": 1120.4,\n      \"net_revenue\": 47090.15,\n      \"units_sold\": 2210,\n      \"units_refunded\": 0,\n      \"net_units_sold\": 2210,\n      \"error\": null\n    },\n    \"sync_summary\": {\n      \"entities\": {\n        \"orders\": {\n          \"last_synced_at\": \"2026-06-20T08:00:00+00:00\",\n          \"is_healthy\": true\n        },\n        \"products\": {\n          \"last_synced_at\": \"2026-06-20T07:45:00+00:00\",\n          \"is_healthy\": true\n        }\n      },\n      \"overall_health\": {\n        \"status\": \"healthy\",\n        \"healthy_entities\": 2,\n        \"total_entities\": 2,\n        \"health_percentage\": 100\n      },\n      \"auto_sync\": {\n        \"is_enabled\": true,\n        \"status_text\": \"Auto sync enabled\"\n      }\n    },\n    \"generated_at\": \"2026-06-20T08:05:00+00:00\"\n  }\n}"}]},{"name":"Get Shop Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shop-info","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shop-info"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Get the TikTok Shop metadata for a connection: shop name, id, cipher, region, seller id, and the authorizing seller's account details captured during authorization.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shop-info","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shop-info"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"shop_name\": \"Acme Official Store\",\n    \"shop_id\": \"7495632100001\",\n    \"shop_cipher\": \"ROW_XXXXXXXXX\",\n    \"region\": \"US\",\n    \"seller_id\": \"7493311000002\",\n    \"main_account_open_id\": \"7405118000003\",\n    \"seller_name\": \"Acme Inc\"\n  }\n}"}]},{"name":"List Access Scopes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/access-scopes","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","access-scopes"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"List the TikTok Shop API permission scopes granted to this connection during authorization, each with a human-readable description. Use this to verify the connection has the permissions a feature needs (orders, products, fulfillment, logistics, finance, returns, webhooks).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/access-scopes","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","access-scopes"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"scopes\": [\n      {\n        \"handle\": \"order.list\",\n        \"description\": \"Read and write order data\"\n      },\n      {\n        \"handle\": \"product.list\",\n        \"description\": \"Read and write product data\"\n      },\n      {\n        \"handle\": \"seller.fulfillment.basic\",\n        \"description\": \"Manage fulfillment and shipping for orders\"\n      },\n      {\n        \"handle\": \"seller.logistics\",\n        \"description\": \"Manage logistics and warehouse data\"\n      }\n    ],\n    \"total\": 4\n  }\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/orders?filter[integration_instance_ids]={{integration_instance_id}}&per_page=10","host":["{{baseUrl}}"],"path":["api","tiktok-shop","orders"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Filter by integration instance ids (see the Filtering & Sorting guide for operators).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"Spatie QueryBuilder paginated list of TikTok Shop orders across instances. Allowed filters: integration_instance_ids, status (TikTok Shop single-axis enum: UNPAID|ON_HOLD|AWAITING_SHIPMENT|PARTIALLY_SHIPPING|AWAITING_COLLECTION|IN_TRANSIT|DELIVERED|COMPLETED|CANCELLED), fulfillment_method, currency, payment_method_name, cancelled, archived, status_state (active|archived|all), search (matches tiktok_order_id/buyer_email/recipient_name), date_from, date_to. Allowed sorts: id, tiktok_order_id, status, total_amount, tiktok_create_time, tiktok_update_time, tiktok_paid_time, last_sync_at, created_at, updated_at. Default sort: -tiktok_create_time. per_page defaults to 10.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/orders/{order_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","orders",":order_id"],"variable":[{"key":"order_id","value":"","description":"The order_id identifier"}]},"description":"Returns a single TikTok Shop order with lineItems and packages eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/orders/{order_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","orders",":order_id"],"variable":[{"key":"order_id","value":"","description":"The order_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 100,\n    \"integration_instance_id\": 12,\n    \"tiktok_order_id\": \"576461413164253045\",\n    \"status\": \"AWAITING_SHIPMENT\",\n    \"fulfillment_method\": \"fulfillment_by_seller\",\n    \"payment_method_name\": \"PayPal\",\n    \"currency\": \"USD\",\n    \"subtotal_amount\": 49.99,\n    \"discount_amount\": 5,\n    \"shipping_amount\": 4.99,\n    \"tax_amount\": 3.5,\n    \"total_amount\": 53.48,\n    \"buyer_email\": \"buyer@example.com\",\n    \"recipient_name\": \"Jane Doe\",\n    \"shipping_address\": {\n      \"address_line1\": \"123 Main St\",\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"zip\": \"78701\",\n      \"country\": \"US\"\n    },\n    \"raw_payload\": {\n      \"id\": \"576461413164253045\"\n    },\n    \"tiktok_create_time\": \"2026-04-25T08:00:00+00:00\",\n    \"tiktok_update_time\": \"2026-04-26T09:00:00+00:00\",\n    \"tiktok_paid_time\": \"2026-04-25T08:01:00+00:00\",\n    \"tracking_submitted_at\": null,\n    \"archived_at\": null,\n    \"last_sync_at\": \"2026-04-26T09:05:00+00:00\",\n    \"line_items\": [\n      {\n        \"id\": 200,\n        \"tiktok_line_item_id\": \"576461413180000000\",\n        \"tiktok_product_id\": \"1729384756102938\",\n        \"tiktok_sku_id\": \"1729384756102939\",\n        \"product_name\": \"Wireless Earbuds\",\n        \"sku_name\": \"Black / Standard\",\n        \"seller_sku\": \"EAR-BLK-STD\",\n        \"package_id\": \"576461413200000000\",\n        \"quantity\": 1,\n        \"unit_price\": 49.99,\n        \"item_status\": \"UNSHIPPED\"\n      }\n    ],\n    \"packages\": [\n      {\n        \"id\": 300,\n        \"package_id\": \"576461413200000000\",\n        \"tracking_number\": null,\n        \"shipping_provider_name\": null,\n        \"package_status\": \"TO_FULFILL\",\n        \"shipped_at\": null,\n        \"delivered_at\": null\n      }\n    ]\n  }\n}"}]},{"name":"Get Raw Order from TikTok","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]},"description":"Fetches the live order JSON directly from the TikTok Shop API (`/order/202309/orders?ids=...`) for a single previously-synced order. Mirrors the Shopify `getRawOrderFromShopify` pattern — used by the frontend Raw Data section as a fetch-on-demand tool to inspect the current upstream payload without writing it to the database.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath params:\n- `tikTokShopIntegrationInstance` (required) — integration instance id.\n- `tikTokShopOrder` (required) — local TikTokShopOrder id.\n\nReturns: `{ data: <raw TikTok Shop order object> | null }`. `data` is the first element from the upstream `orders` array, or `null` if not found."},"response":[{"name":"Successful response","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]}},"status":"Successful response","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"576461413038489876\",\n    \"buyer_email\": \"buyer@example.com\",\n    \"status\": \"AWAITING_SHIPMENT\",\n    \"payment\": {\n      \"currency\": \"USD\",\n      \"total_amount\": \"42.99\",\n      \"sub_total\": \"39.99\",\n      \"shipping_fee\": \"3.00\"\n    },\n    \"line_items\": [\n      {\n        \"id\": \"576461413038489876-1\",\n        \"product_name\": \"Sample Product\",\n        \"sku_name\": \"Default\",\n        \"seller_sku\": \"ABC-123\",\n        \"quantity\": 1,\n        \"sale_price\": \"39.99\"\n      }\n    ],\n    \"create_time\": 1745164200,\n    \"update_time\": 1745250720\n  }\n}"}]},{"name":"Refresh Orders from TikTok","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/refresh","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","refresh"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Dispatches a tracked job to pull recent orders from TikTok Shop.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAccepts (all optional, all dates):\n- `updated_at` — fetch orders updated since this datetime (preferred)\n- `created_at_min` — fetch orders created since this datetime\n- `since` — legacy alias for `updated_at`\n\nThe controller picks the first non-null in the order: `updated_at` → `created_at_min` → `since`. If none provided, defaults to last 24 hours.\n\nReturns `{ data: { tracked_job_log_id }, message }` — track progress via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"updated_at\": \"2026-04-01T00:00:00Z\",\n  \"created_at_min\": null,\n  \"since\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Successful response","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/refresh","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","refresh"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"Successful response","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4521\n  },\n  \"message\": \"Order refresh queued.\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/refresh-one","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","refresh-one"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Re-syncs a single order by TikTok order ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `uniqueId` (required, string) — the TikTok order ID to refresh.\n\nNote: TikTok Shop's API does not currently support fetching a single order by ID, so this dispatches a 30-day a background job as a workaround. The targeted order will be re-synced as part of that window.\n\nReturns `{ data: { tracked_job_log_id }, message }`.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"576461413038489876\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Successful response","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/refresh-one","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","refresh-one"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"Successful response","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4522\n  },\n  \"message\": \"Order refresh queued.\"\n}"}]},{"name":"Search Orders (Local DB)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/search?search_by=order_number&query=576461413038489876","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","search"],"query":[{"key":"search_by","value":"order_number","description":"One of: order_number, tiktok_order_id, email. Defaults to order_number.","disabled":true},{"key":"query","value":"576461413038489876","description":"Search term — order ID or buyer email.","disabled":true}],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Searches LOCAL DB for already-synced TikTok Shop orders. Unlike Shopify's equivalent endpoint, this does NOT hit the TikTok Shop API — TikTok's API does not currently support free-text order search. Use this to find orders already synced into SKU.io and re-trigger an update via Refresh Single Order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params:\n- `search_by` (required, string) — `order_number`, `tiktok_order_id`, or `email`. Defaults to `order_number`.\n- `query` (required, string) — the search term.\n\nReturns: `{ data: [{ id, legacy_resource_id, name, email, status, tiktok_create_time, tiktok_update_time, total_price, currency, exists_in_database, database_id }], total }`. `status` is the TikTok Shop single-axis order status enum."},"response":[{"name":"Successful response","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/search?search_by=order_number&query=576461413038489876","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","search"],"query":[{"key":"search_by","value":"order_number","description":"One of: order_number, tiktok_order_id, email. Defaults to order_number.","disabled":true},{"key":"query","value":"576461413038489876","description":"Search term — order ID or buyer email.","disabled":true}],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"Successful response","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12345,\n      \"legacy_resource_id\": \"576461413038489876\",\n      \"name\": \"#576461413038489876\",\n      \"email\": \"buyer@example.com\",\n      \"status\": \"AWAITING_SHIPMENT\",\n      \"tiktok_create_time\": \"2026-04-20T15:30:00Z\",\n      \"tiktok_update_time\": \"2026-04-21T09:12:00Z\",\n      \"total_price\": \"42.99\",\n      \"currency\": \"USD\",\n      \"exists_in_database\": true,\n      \"database_id\": 12345\n    }\n  ],\n  \"total\": 1\n}"}]},{"name":"Submit Tracking","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/submit-tracking","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","submit-tracking"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"order_id","value":"","description":"The order_id identifier"}]},"description":"Dispatches a background job to push tracking numbers up to TikTok for the order's packages. Returns a tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/submit-tracking","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","submit-tracking"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"order_id","value":"","description":"The order_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9877\n  },\n  \"message\": \"Tracking submission queued.\"\n}"}]},{"name":"List Shipping Providers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-providers","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-providers"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Returns the list of TikTok-recognized shipping providers for the instance (used to populate dropdowns in the shipping method mapping UI).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-providers","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-providers"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"7208012345678\",\n      \"name\": \"USPS\"\n    },\n    {\n      \"id\": \"7208087654321\",\n      \"name\": \"FedEx\"\n    }\n  ]\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","latest-sync-info"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Returns sync metadata: latest_order_name, latest_order_date, sync_cursor_at, total_orders, last_sync_at.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/archive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","archive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]},"description":"Soft-archives a TikTok Shop order. Sets archived_at timestamp.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Unarchive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/unarchive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","unarchive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]},"description":"Restores a previously archived TikTok Shop order. Clears archived_at.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Archive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","bulk-archive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-archives orders. Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object to archive every matching order. Returns archived_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Unarchive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","bulk-unarchive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-unarchives orders. Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object. Returns unarchived_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]},"description":"Permanently deletes a TikTok Shop order from SKU.io (does not affect TikTok).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","bulk-delete"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-deletes orders. Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object. Returns deleted_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Create SKU Orders from TikTok Shop","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","create-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Create SKU sales orders from TikTok Shop orders. Mirrors the Shopify endpoint. Supports three request shapes:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n1. `create_all_orders: true` — \"Create All\" header button: creates SKU orders for ALL pending TikTok Shop orders (no filters).\n2. `apply_to_all: true, filters: {...}` — bulk toolbar with \"All\" scope: creates SKU orders for filtered pending orders.\n3. `ids: [...]` — bulk toolbar with specific selected orders.\n\nOnly TikTok Shop orders that don't already have a linked SalesOrder and aren't archived are eligible. Returns the count of orders processed. TODO: For large batches a tracked job should be dispatched (currently runs synchronously).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","create-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 SKU orders created successfully\",\n  \"total_orders\": 3,\n  \"tracked_job_log_id\": null\n}"}]},{"name":"Update SKU Orders from TikTok Shop","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","update-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Update existing SKU sales orders from their linked TikTok Shop orders. Re-derives the SalesOrder DTO and persists changes. Only TikTok Shop orders that already have a linked SalesOrder are eligible. Pass either `ids: [...]` for a specific subset, or `update_all_orders: true` (optionally with `filters: {...}`). The `use_jobs` flag is accepted for parity with Shopify but is currently ignored — TikTok always runs synchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"update_all_orders\": false,\n  \"use_jobs\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","update-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 SKU orders updated successfully\",\n  \"total_orders\": 3\n}"}]},{"name":"Delete Linked SKU Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/sku-order","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","sku-order"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]},"description":"Delete the SKU sales order linked to a single TikTok Shop order. The TikTok Shop order itself is kept intact. Pass `archive_tiktok_shop_order=true` to additionally archive the TikTok Shop order so it won't be re-created on the next sync. Returns 404 if no SKU order is linked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/{order_id}/sku-order","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders",":order_id","sku-order"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"order_id","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully\",\n  \"archived_tiktok_shop_order\": false\n}"}]},{"name":"Bulk Delete Linked SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","bulk-delete-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-delete the SKU sales orders linked to the given TikTok Shop orders. The TikTok Shop orders themselves are kept intact unless `archive_tiktok_shop_orders=true` is passed. Pass either an explicit `ids` array, or `apply_to_all: true` with the current `filters` object. Returns the deleted count. TODO: For large batches a tracked job should be dispatched (currently runs synchronously, mirroring Shopify's a background job).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"archive_tiktok_shop_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","orders","bulk-delete-sku-orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 SKU orders deleted successfully\",\n  \"total_orders\": 3,\n  \"tracked_job_log_id\": null\n}"}]},{"name":"Query Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/pre-start-date-orders?created_at_min=2024-01-01","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2024-01-01","disabled":true}],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Query TikTok Shop for orders predating the inventory start date in a given window.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params:\n- `created_at_min` (required, date)\n- `created_at_max` (optional, date, after_or_equal:created_at_min)\n- `status` (optional, one of: any, UNPAID, AWAITING_SHIPMENT, AWAITING_COLLECTION, PARTIALLY_SHIPPING, IN_TRANSIT, DELIVERED, COMPLETED, CANCELLED)"}},{"name":"Search Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/pre-start-date-orders/search?search_by=order_id&search_term=576461413038489876","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"order_id","disabled":true},{"key":"search_term","value":"576461413038489876","disabled":true}],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Search TikTok Shop for a specific pre-start-date order by ID or buyer email.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery params:\n- `search_by` (required, one of: order_id, email)\n- `search_term` (required, max 255 chars)"}},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","pre-start-date-orders","import"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Import selected pre-start-date orders from TikTok Shop by their TikTok order ids. Each order is fetched from the TikTok Shop API and stored, flagged as a pre-start-date import.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBecause each order requires its own throttled TikTok Shop API call, the import runs asynchronously as a queued background job. The request returns immediately with a tracked job log id that can be polled to follow the import's progress.\n\n**Requires `inventory_start_date` to be set** — returns 422 otherwise.\n\n**Request Body:**\n- `tiktok_order_ids` (required, array of strings, 1-10,000 entries, each a TikTok order id string up to 100 chars)\n\n**Response:**\n- `data.tracked_job_log_id` - id of the tracked job log; poll it to follow import progress\n- `message` - human-readable confirmation of how many orders are being imported","body":{"mode":"raw","raw":"{\n  \"tiktok_order_ids\": [\n    \"576461413038489876\",\n    \"576461413038489877\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","pre-start-date-orders","import"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Importing 2 pre-start-date orders.\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/products?filter[integration_instance_ids]={{integration_instance_id}}&include=skus&per_page=15","host":["{{baseUrl}}"],"path":["api","tiktok-shop","products"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Filter by integration instance ids (see the Filtering & Sorting guide for operators).","disabled":true},{"key":"include","value":"skus","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"List Products\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List Product SKUs (Flattened Mapping List)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/products/skus?filter[integration_instance_ids]={{integration_instance_id}}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","products","skus"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Comma-separated TikTok integration-instance IDs to scope to.","disabled":true}]},"description":"Flattened one-row-per-SKU product list — the Shopify-parity product-mapping table. Unlike **List Products** (one row per TikTok product), each row here is a single `TikTokShopProductSku` variant carrying its own mapping block (`product`, `sku_product`, `subscription_offering`, `mapped_at`, `mapped_sku`), so the shared frontend mapped-product column renders 1:1 exactly as it does for Shopify variants.\n\nRequires a Bearer token.\n\n**Pagination:** `page` (1-indexed), `per_page` (default 10).\n**Default sort:** `-updated_at`. Allowed sorts: id, seller_sku, tiktok_sku_id, name, inventory_quantity, price, inventory_synced_at, archived_at, created_at, updated_at (prefix with `-` for descending).\n\n**Archived behaviour:** archived SKUs are excluded by default. Supply `filter[archived]` to change this — `archived`/`true`/`1` returns only archived SKUs, `all` returns both.\n\n**Filters:**\n- `filter[integration_instance_ids]` — comma-separated TikTok integration-instance IDs.\n- `filter[seller_sku]` — partial match on the seller SKU.\n- `filter[tiktok_sku_id]` — partial match on the TikTok SKU id.\n- `filter[name]` — partial match on the variant name.\n- `filter[mapped_sku]` — partial match on the mapped SKU.io product SKU.\n- `filter[mapping_status]` — `mapped` or `unmapped`.\n- `filter[mapped]` — boolean; `true` = mapped only, `false` = unmapped only.\n- `filter[archived]` — see Archived behaviour above.\n- `filter[search]` — free-text across id, seller_sku, tiktok_sku_id, name, and parent product title.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/products/skus?filter[integration_instance_ids]={{integration_instance_id}}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","products","skus"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Comma-separated TikTok integration-instance IDs to scope to.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4412,\n      \"integration_instance_id\": 7,\n      \"tiktok_shop_product_id\": 883,\n      \"tiktok_sku_id\": \"1729578451203841001\",\n      \"seller_sku\": \"TEE-RED-L\",\n      \"name\": \"Classic Tee / Red / L\",\n      \"price\": 24.99,\n      \"inventory_quantity\": 132,\n      \"inventory_synced_at\": \"2026-07-02T09:14:22.000000Z\",\n      \"archived_at\": null,\n      \"created_at\": \"2026-05-11T18:02:10.000000Z\",\n      \"updated_at\": \"2026-07-02T09:14:22.000000Z\",\n      \"tiktok_product_id\": \"1729511000000112233\",\n      \"product_title\": \"Classic Cotton Tee\",\n      \"product_status\": \"ACTIVATE\",\n      \"main_image_url\": \"https://p16-oec-va.ibyteimg.com/tos-maliva/classic-tee.jpeg\",\n      \"product_listing_id\": 55231,\n      \"product\": {\n        \"id\": 90233,\n        \"name\": \"Classic Tee Red Large\",\n        \"sku\": \"SKU-TEE-RED-L\",\n        \"listing_id\": 55231,\n        \"default_financial_line_type_id\": 4,\n        \"default_financial_line_type\": {\n          \"id\": 4,\n          \"name\": \"Product Sales\",\n          \"classification\": \"income\"\n        }\n      },\n      \"subscription_offering\": null,\n      \"mapped_at\": \"2026-06-20T12:41:03.000000Z\",\n      \"mapped_sku\": \"SKU-TEE-RED-L\",\n      \"sku_product\": {\n        \"id\": 90233,\n        \"sku\": \"SKU-TEE-RED-L\",\n        \"name\": \"Classic Tee Red Large\",\n        \"barcode\": \"0641243100000\",\n        \"price\": 24.99,\n        \"type\": \"standard\",\n        \"default_financial_line_type_id\": 4,\n        \"default_financial_line_type\": {\n          \"id\": 4,\n          \"name\": \"Product Sales\",\n          \"classification\": \"income\"\n        }\n      }\n    },\n    {\n      \"id\": 4413,\n      \"integration_instance_id\": 7,\n      \"tiktok_shop_product_id\": 883,\n      \"tiktok_sku_id\": \"1729578451203841002\",\n      \"seller_sku\": \"TEE-BLU-M\",\n      \"name\": \"Classic Tee / Blue / M\",\n      \"price\": 24.99,\n      \"inventory_quantity\": 0,\n      \"inventory_synced_at\": \"2026-07-02T09:14:22.000000Z\",\n      \"archived_at\": null,\n      \"created_at\": \"2026-05-11T18:02:10.000000Z\",\n      \"updated_at\": \"2026-07-02T09:14:22.000000Z\",\n      \"tiktok_product_id\": \"1729511000000112233\",\n      \"product_title\": \"Classic Cotton Tee\",\n      \"product_status\": \"ACTIVATE\",\n      \"main_image_url\": \"https://p16-oec-va.ibyteimg.com/tos-maliva/classic-tee.jpeg\",\n      \"product_listing_id\": null,\n      \"product\": null,\n      \"subscription_offering\": null,\n      \"mapped_at\": null,\n      \"mapped_sku\": null,\n      \"sku_product\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"last_page\": 1,\n  \"from\": 1,\n  \"to\": 2,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/tiktok-shop/products/skus?page=1\",\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/tiktok-shop/products/skus?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/tiktok-shop/products/skus\"\n}"}]},{"name":"Show Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/products/{product_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","products",":product_id"],"variable":[{"key":"product_id","value":"","description":"The product_id identifier"}]},"description":"Returns a single TikTok Shop product with skus and shop eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/products/{product_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","products",":product_id"],"variable":[{"key":"product_id","value":"","description":"The product_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 500,\n    \"integration_instance_id\": 12,\n    \"tiktok_product_id\": \"1729384756102938\",\n    \"title\": \"Wireless Earbuds\",\n    \"status\": \"ACTIVATE\",\n    \"skus\": [\n      {\n        \"id\": 800,\n        \"seller_sku\": \"EAR-BLK-STD\"\n      }\n    ],\n    \"shop\": {\n      \"id\": 5,\n      \"shop_id\": \"7494838299\",\n      \"name\": \"Acme US\"\n    }\n  }\n}"}]},{"name":"Sync Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Dispatches a background job to fetch all products for the instance. Returns a tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9878\n  },\n  \"message\": \"Product sync started.\"\n}"}]},{"name":"Smart Match SKU to SKU.io Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/skus/{product_sku_id}/smart-match","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","skus",":product_sku_id","smart-match"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_sku_id","value":"","description":"The product sku ID."}]},"description":"Suggest SKU.io Products to map a TikTok Shop SKU (TikTokShopProductSku) to, before the user maps it. Mirrors Shopify's smart-match, but operates at TikTok's per-SKU listing grain (Shopify matches per-variant).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe endpoint is keyed on the flattened SKU row (`{{product_sku_id}}` — the `id` returned by List Product SKUs). No request body: matching is derived from the SKU's `seller_sku`, its variant `name`, and the parent product `title`.\n\nMatch tiers returned in `data`:\n- `exact_match` — a non-archived SKU.io Product whose `sku` exactly equals the TikTok `seller_sku` (`match_type` = `sku`). Null when none.\n- `barcode_match` — **always null** for TikTok Shop: TikTok SKUs carry no barcode. The key is retained purely so the shared frontend mapping modal renders identically to Shopify's.\n- `similar_matches` — up to 5 non-archived fuzzy matches (LIKE on `name`/`sku`, plus the first three >2-char words of the parent title), excluding the exact match (`match_type` = `fuzzy`).\n\nReturns 403 if the SKU does not belong to the given integration instance.\n\nAuthentication: requires a Bearer token (Personal Access Token)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/skus/{product_sku_id}/smart-match","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","skus",":product_sku_id","smart-match"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_sku_id","value":"","description":"The product sku ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 4821,\n      \"sku\": \"ZKM-001\",\n      \"name\": \"Zesty Kumquat Marmalade\",\n      \"barcode\": \"0761234500017\",\n      \"price\": \"12.99\",\n      \"type\": \"standard\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 4822,\n        \"sku\": \"KM-JAR\",\n        \"name\": \"Kumquat Marmalade Jar\",\n        \"barcode\": null,\n        \"price\": \"9.50\",\n        \"type\": \"standard\",\n        \"match_type\": \"fuzzy\"\n      },\n      {\n        \"id\": 4823,\n        \"sku\": \"KM-SPREAD\",\n        \"name\": \"Organic Kumquat Spread\",\n        \"barcode\": null,\n        \"price\": \"8.25\",\n        \"type\": \"standard\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Create SKU.io Product from SKU","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/skus/{product_sku_id}/create-sku-product","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","skus",":product_sku_id","create-sku-product"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_sku_id","value":"","description":"The product sku ID."}]},"description":"Create a brand-new SKU.io Product from a TikTok Shop SKU's own data (SKU, name, price) and map the SKU to it in one step. Mirrors Shopify's create-sku-product, but operates at TikTok's per-SKU listing grain (Shopify creates per-variant).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe endpoint is keyed on the flattened SKU row (`{{product_sku_id}}` — the `id` returned by List Product SKUs). No request body: the new product's `sku` is the TikTok `seller_sku` (falling back to `tiktok_sku_id` when the seller SKU is blank), its `name` is the SKU variant name (falling back to the parent product title), price is copied from the SKU, and barcode is always null (TikTok SKUs carry none).\n\nCreate-or-link behaviour (Shopify parity):\n- If **no** SKU.io Product with the resolved SKU exists, a new one is created, then the TikTok SKU is mapped to it. `linked_existing` = `false`.\n- If a SKU.io Product with that SKU **already** exists, it is linked to instead of duplicated, then the TikTok SKU is mapped to it. `linked_existing` = `true`.\n\nMapping creates a ProductListing and re-links any previously-unmapped sales-order lines for this listing (dispatched asynchronously). The response `data` is the flattened SKU row (same shape as List Product SKUs) reflecting the new mapping.\n\nReturns 422 if the SKU is already mapped (unmap it first), and 403 if the SKU does not belong to the given integration instance.\n\nAuthentication: requires a Bearer token (Personal Access Token)."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/skus/{product_sku_id}/create-sku-product","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","skus",":product_sku_id","create-sku-product"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_sku_id","value":"","description":"The product sku ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 90321,\n    \"integration_instance_id\": 12,\n    \"tiktok_shop_product_id\": 4471,\n    \"tiktok_sku_id\": \"1729382734500123\",\n    \"seller_sku\": \"ZKM-001\",\n    \"name\": \"Zesty Kumquat Marmalade / 250g\",\n    \"price\": \"12.99\",\n    \"inventory_quantity\": 84,\n    \"inventory_synced_at\": \"2026-07-02T09:15:00.000000Z\",\n    \"archived_at\": null,\n    \"created_at\": \"2026-06-28T11:02:41.000000Z\",\n    \"updated_at\": \"2026-07-03T08:40:12.000000Z\",\n    \"tiktok_product_id\": \"1729382700000456\",\n    \"product_title\": \"Zesty Kumquat Marmalade\",\n    \"product_status\": \"ACTIVATE\",\n    \"main_image_url\": \"https://p16-oec.tiktokcdn.com/kumquat-main.jpeg\",\n    \"product_listing_id\": 55231,\n    \"product\": {\n      \"id\": 4821,\n      \"name\": \"Zesty Kumquat Marmalade / 250g\",\n      \"sku\": \"ZKM-001\",\n      \"listing_id\": 55231,\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      }\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-07-03T08:40:12.000000Z\",\n    \"mapped_sku\": \"ZKM-001\",\n    \"sku_product\": {\n      \"id\": 4821,\n      \"sku\": \"ZKM-001\",\n      \"name\": \"Zesty Kumquat Marmalade / 250g\",\n      \"barcode\": null,\n      \"price\": \"12.99\",\n      \"type\": \"standard\",\n      \"default_financial_line_type_id\": 3,\n      \"default_financial_line_type\": {\n        \"id\": 3,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      }\n    }\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU.io product created and mapped successfully.\"\n}"}]},{"name":"Map Product SKU","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{product_id}/map","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":product_id","map"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_id","value":"","description":"The product ID."}]},"description":"Map a TikTok Shop product SKU (TikTokShopProductSku) to a SKU.io Product or Subscription Offering. Mirrors Shopify single-map. Body requires `sku_id` plus exactly one of `product_id` or `subscription_offering_id`. Response includes the reloaded product with skus + product listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"sku_id\": 1,\n  \"product_id\": 123\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unmap Product SKU","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{product_id}/map","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":product_id","map"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_id","value":"","description":"The product ID."}]},"description":"Unmap a TikTok Shop product SKU. Deletes the underlying ProductListing. Returns 422 if the SKU is not currently mapped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{product_id}/archive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":product_id","archive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_id","value":"","description":"The product ID."}]},"description":"Soft-archive a single TikTok Shop product (sets archived_at). Mirrors Shopify single-archive.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Unarchive Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{product_id}/unarchive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":product_id","unarchive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_id","value":"","description":"The product ID."}]},"description":"Restore an archived TikTok Shop product (clears archived_at). Mirrors Shopify single-unarchive.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Delete Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{product_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":product_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"product_id","value":"","description":"The product ID."}]},"description":"Hard-delete a single TikTok Shop product and its child SKUs. Mirrors Shopify single delete.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Archive Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-archive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-archive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-archives TikTok Shop products (sets archived_at). Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object to archive every product matching the listing filters. Returns archived_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors Shopify bulk-archive. Filters reuse the same Spatie QueryBuilder allowed filters as the listing endpoint (`status`, `category_id`, `archived`, `search`, `title`, `tiktok_product_id`, `category_name`).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Unarchive Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-unarchive"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-unarchives TikTok Shop products (clears archived_at). Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object. Returns unarchived_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors Shopify bulk-unarchive.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Delete Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-delete","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-delete"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Hard-deletes TikTok Shop products (and their child SKUs) in bulk. Either pass an explicit `ids` array, or `apply_to_all: true` with the current `filters` object. Returns deleted_count.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors Shopify bulk-delete.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Bulk Unmap Product SKUs","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-unmap","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-unmap"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Bulk-unmaps TikTok Shop product SKUs from their SKU.io ProductListings (deletes the ProductListing records). Per-SKU, not per-product, because mapping is at the SKU level.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEither pass an explicit `sku_ids` array (TikTok Shop SKU IDs), or `apply_to_all: true` with `filters` (product-level filters). When `apply_to_all` is used, the backend resolves all mapped SKUs under products matching the filter set. Returns unmapped_count.\n\nMirrors Shopify's bulk-unmap pattern adapted for TikTok's SKU-level mapping model.","body":{"mode":"raw","raw":"{\n  \"sku_ids\": [\n    10,\n    11,\n    12\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Download CSV Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings?scope=unmapped","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings"],"query":[{"key":"scope","value":"unmapped","description":"Required. One of: selected | unmapped | all","disabled":true}],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Download a CSV of TikTok Shop SKU → SKU.io product mappings, scoped by selection, unmapped-only, or all (filtered).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nColumns: tiktok_sku_id, tiktok_product_id, seller_sku, product_title, sku_name, price, map_to_sku.\n\nUsers edit the `map_to_sku` column then re-upload via the upload endpoint to bulk-apply mappings. Mirrors Shopify's bulk mapping CSV flow but operates per-SKU (TikTok lists each SKU as its own variant).\n\nReturns a binary CSV download (Content-Type: text/csv)."}},{"name":"Upload CSV Mappings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Upload an edited CSV (downloaded from the Download CSV Mappings endpoint) to bulk-apply TikTok SKU → SKU.io product mappings in one pass. Validates and applies row-by-row.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFile must be CSV/TXT, max 10 MB. Required columns: tiktok_sku_id, map_to_sku. Empty `map_to_sku` rows are skipped. Rows where the TikTok SKU isn't found, or the SKU.io product code doesn't match, are returned in `invalid_rows`.\n\nResponse: { mapped_count, skipped_count, failed_count, invalid_rows[] }.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_count\": 12,\n    \"skipped_count\": 3,\n    \"failed_count\": 1,\n    \"invalid_rows\": [\n      {\n        \"row_number\": 7,\n        \"tiktok_sku_id\": \"1729380000000000000\",\n        \"map_to_sku\": \"BAD-SKU-001\",\n        \"error\": \"No SKU.io product found with code: BAD-SKU-001\"\n      }\n    ]\n  },\n  \"message\": \"CSV mapping import complete\"\n}"}]},{"name":"Validate CSV Mappings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings/validate","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings","validate"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Parse/preview half of the two-step CSV import — mirrors Shopify's Validate Bulk Mapping CSV, but operates per-SKU (TikTok lists each SKU as its own variant, keyed on `tiktok_sku_id`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidates the uploaded CSV WITHOUT applying anything, then returns the resolved `{tiktok_shop_product_sku_id, tiktok_sku_id, sku_product_id}` pairings the frontend previews and posts back to the Apply CSV Mappings endpoint, plus counts and any invalid/skipped rows.\n\nFile must be CSV/TXT, max 10 MB. Required columns: tiktok_sku_id, map_to_sku. Rows with an empty `map_to_sku` are counted in `skipped_count`. Rows whose `tiktok_sku_id` isn't found for this integration, or whose `map_to_sku` product code doesn't match a SKU.io product, are returned in `invalid_rows` (with a per-row `error`).\n\nResponse: { valid_count, skipped_count, invalid_rows[], mappings[] }.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings/validate","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings","validate"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"valid_count\": 2,\n    \"skipped_count\": 1,\n    \"invalid_rows\": [\n      {\n        \"row_number\": 5,\n        \"tiktok_sku_id\": \"1729380000000000099\",\n        \"map_to_sku\": \"BAD-SKU-001\",\n        \"error\": \"No SKU.io product found with code: BAD-SKU-001\"\n      }\n    ],\n    \"mappings\": [\n      {\n        \"tiktok_shop_product_sku_id\": 4821,\n        \"tiktok_sku_id\": \"1729380000000000001\",\n        \"sku_product_id\": 991\n      },\n      {\n        \"tiktok_shop_product_sku_id\": 4822,\n        \"tiktok_sku_id\": \"1729380000000000002\",\n        \"sku_product_id\": 992\n      }\n    ]\n  }\n}"}]},{"name":"Apply CSV Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings/apply","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings","apply"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Commit half of the two-step CSV import — mirrors Shopify's Apply Bulk Mapping CSV. Applies the `{tiktok_shop_product_sku_id, sku_product_id}` pairings returned by the Validate CSV Mappings endpoint. Each pairing maps a flattened TikTok SKU to a SKU.io product via the canonical mapping path (creates/updates the ProductListing and re-links any unmapped sales-order lines).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody: `mappings` (required, min 1). Each entry needs `tiktok_shop_product_sku_id` (integer — the internal TikTokShopProductSku id, NOT the tiktok_sku_id string) and `sku_product_id` (integer, must exist in `products`). SKUs that don't belong to this integration instance are counted in `failed_count` rather than mapped.\n\nResponse: { mapped_count, failed_count }.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"tiktok_shop_product_sku_id\": 4821,\n      \"sku_product_id\": 991\n    },\n    {\n      \"tiktok_shop_product_sku_id\": 4822,\n      \"sku_product_id\": 992\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/csv-mappings/apply","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","csv-mappings","apply"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mapped_count\": 2,\n    \"failed_count\": 0\n  },\n  \"message\": \"Applied 2 mapping(s).\"\n}"}]},{"name":"Get Raw Product from TikTok","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{tiktok_shop_product_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":tiktok_shop_product_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tiktok_shop_product_id","value":"","description":"The tiktok shop product ID."}]},"description":"Fetches the live raw product JSON directly from the TikTok Shop API (`GET /product/202309/products/{tiktok_product_id}`) for the given local product. Used by the product detail page's 'Raw Data from TikTok' accordion when the user clicks 'Load Raw Data from TikTok'.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the product does not belong to the given integration instance, 500 on TikTok API failure.\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{tiktok_shop_product_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":tiktok_shop_product_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tiktok_shop_product_id","value":"","description":"The tiktok shop product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": \"1729382911234567890\",\n      \"title\": \"Demo TikTok Product\",\n      \"status\": \"ACTIVATE\",\n      \"create_time\": 1716595200,\n      \"update_time\": 1716681600,\n      \"category_chains\": [\n        {\n          \"id\": \"600001\",\n          \"parent_id\": \"0\",\n          \"local_name\": \"Apparel & Accessories\",\n          \"is_leaf\": false\n        }\n      ],\n      \"skus\": [\n        {\n          \"id\": \"1729382911234567891\",\n          \"seller_sku\": \"DEMO-SKU-1\",\n          \"price\": {\n            \"sale_price\": \"12.99\",\n            \"currency\": \"USD\"\n          }\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Get Orders Containing Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{tiktok_shop_product_id}/orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":tiktok_shop_product_id","orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tiktok_shop_product_id","value":"","description":"The tiktok shop product ID."}]},"description":"Returns a paginated list of TikTok Shop orders that contain this product (orders whose line items reference the product's `tiktok_product_id`). Used by the product detail page's 'Orders Containing This Product' accordion.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 if the product does not belong to the given integration instance.\n\nPagination: `page` (default 1), `per_page` (default 10). Sorted by `tiktok_create_time` DESC.\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/{tiktok_shop_product_id}/orders","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products",":tiktok_shop_product_id","orders"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tiktok_shop_product_id","value":"","description":"The tiktok shop product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12345,\n      \"integration_instance_id\": 9,\n      \"tiktok_order_id\": \"5780000000001234567\",\n      \"status\": \"AWAITING_SHIPMENT\",\n      \"currency\": \"USD\",\n      \"total_amount\": \"42.97\",\n      \"buyer_email\": \"buyer@example.com\",\n      \"tiktok_create_time\": \"2026-05-20T15:32:11Z\",\n      \"tiktok_update_time\": \"2026-05-20T15:35:00Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 27,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Bulk Map / Unmap / Create / Remap Product SKUs (Sync)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Synchronous per-SKU bulk mapping engine backing the frontend BulkMappingModal for below-threshold selections. Runs each resolved TikTok Shop SKU through the mapping manager and returns Shopify-parity count keys.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `tiktok-shop.products.bulk`.\n\n**Body**\n- `action` (required, one of `map` | `unmap` | `create` | `remap`) — the per-SKU operation. `map` = smart-match & map unmapped SKUs; `unmap` = delete the SKU's ProductListing; `create` = create-or-link a SKU.io product from the SKU and map it; `remap` = repoint an already-mapped SKU to its current best match. (archive/unarchive/delete are NOT here — they use the product-id batch endpoints.)\n- `selection` (required, object) — `type` is one of `selected` | `visible` | `filtered`. For `selected`, pass `selection.ids` (array of TikTok Shop SKU IDs). For `visible`/`filtered`, pass `selection.filters` (same filter keys as the flattened SKU list) and the backend resolves the id set.\n- `options` (optional, object) — `match_by` (`sku` | `barcode`; `barcode` falls back to exact SKU match since TikTok SKUs carry no barcode), `create_if_no_match` (boolean — on `map`, create a SKU.io product when no match is found; counts toward `mapped_count`), `field_mappings` (array of `{shopify_field, sku_field}` overrides).\n\n**Response** returns `processed` / `failed` / `skipped` plus one action-specific count key (`mapped_count` | `created_count` | `remapped_count` | `unmapped_count`). Returns **422** when the selection resolves to no SKUs. Larger selections should use `products/bulk-tracked` instead.","body":{"mode":"raw","raw":"{\n  \"action\": \"map\",\n  \"selection\": {\n    \"type\": \"selected\",\n    \"ids\": [\n      10,\n      11,\n      12\n    ]\n  },\n  \"options\": {\n    \"match_by\": \"sku\",\n    \"create_if_no_match\": false\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"action\": \"map\",\n    \"processed\": 3,\n    \"failed\": 0,\n    \"skipped\": 1,\n    \"mapped_count\": 2\n  },\n  \"message\": \"Bulk map completed. Processed: 3, Failed: 0, Skipped: 1\"\n}"}]},{"name":"Bulk Map Product SKUs (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-tracked"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Queued counterpart to `products/bulk`, dispatched when the BulkMappingModal crosses its tracked-operation threshold. Same body contract as `products/bulk` (`action` = `map` | `unmap` | `create` | `remap`, plus `selection` and `options`). Dispatches a tracked job and returns its `tracked_job_log_id` for polling via `products/bulk-progress/{id}`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `tiktok-shop.products.bulk-tracked`.\n\nThe job surfaces via the tracked job log endpoints. Returns **422** when the selection resolves to no SKUs.","body":{"mode":"raw","raw":"{\n  \"action\": \"map\",\n  \"selection\": {\n    \"type\": \"filtered\",\n    \"filters\": {\n      \"mapping_status\": \"unmapped\"\n    }\n  },\n  \"options\": {\n    \"match_by\": \"sku\",\n    \"create_if_no_match\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-tracked"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 8842\n  },\n  \"message\": \"Bulk operation job has been queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Bulk Mapping Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]},"description":"Fetch progress for a tracked bulk mapping operation started by `products/bulk-tracked`. Returns the tracked job log object for the given `trackedJobLogId` — the same shape the tracked job log endpoints consumes (status, processed/total items, progress percentage, messages, results).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `tiktok-shop.products.bulk-progress`. Returns **404** when the log id is unknown."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/bulk-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","bulk-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 8842,\n    \"job_type\": \"tiktok-shop-bulk-product-operation\",\n    \"queue\": \"default\",\n    \"job_name\": \"Bulk Map: 42 TikTok Shop products\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": null,\n      \"type\": null,\n      \"reference\": null\n    },\n    \"related_model_reference\": null,\n    \"messages\": [\n      \"Processing SKU 18 of 42\"\n    ],\n    \"attempted_at\": \"2026-07-03T10:14:00+00:00\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-07-03T10:13:58+00:00\",\n    \"updated_at\": \"2026-07-03T10:14:12+00:00\",\n    \"results\": null,\n    \"total_items\": 42,\n    \"processed_items\": 18,\n    \"progress_percentage\": 43,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Map to Existing SKUs (Bulk, Queued)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/map-to-existing-skus","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","map-to-existing-skus"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Queue a bulk \"map to existing SKU.io products only\" operation (no product creation) over the shared toolbar selection contract. Guarded by the instance's configured field mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `tiktok-shop.mappings.map-to-existing-skus` (URL is under `products/`).\n\n**Body** — exactly one selection mode:\n- `ids` (array of TikTok Shop SKU IDs, max 1000), or\n- `process_all` (boolean `true` — all eligible SKUs), or\n- `filters` (object — same filter keys as the flattened SKU list).\n\n**Responses**: **200** queued-with-summary; **400** when no field mappings are configured (`No field mappings found...`), when the selection is invalid (none of ids/process_all/filters), or when more than 1000 ids are supplied.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    10,\n    11,\n    12\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/map-to-existing-skus","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","map-to-existing-skus"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"message\": \"Processing 3 specific SKUs - check queue status for progress\",\n    \"status\": \"queued\",\n    \"selection_summary\": {\n      \"selection_type\": \"specific_skus\",\n      \"sku_count\": 3,\n      \"sku_ids\": [\n        10,\n        11,\n        12\n      ]\n    }\n  }\n}"}]},{"name":"Create Products from Mappings (Bulk, Queued)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/create-products-from-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","create-products-from-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Queue a bulk \"create new SKU.io products from unmapped SKUs\" operation over the shared toolbar selection contract. Guarded by the instance's configured field mappings. Same body and response shape as `map-to-existing-skus`, but the queued job creates a SKU.io product from each unmapped SKU's channel attributes (linking an existing product when one already has the matching SKU) and maps it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNamed route: `tiktok-shop.mappings.create-products-from-mappings` (URL is under `products/`).\n\n**Body** — exactly one of `ids` (max 1000) | `process_all` | `filters`.\n\n**Responses**: **200** queued-with-summary; **400** when no field mappings are configured, when the selection is invalid, or when more than 1000 ids are supplied.","body":{"mode":"raw","raw":"{\n  \"process_all\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/create-products-from-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","create-products-from-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"message\": \"Processing all eligible SKUs - check queue status for progress\",\n    \"status\": \"queued\",\n    \"selection_summary\": {\n      \"selection_type\": \"all_skus\",\n      \"filters_applied\": null\n    }\n  }\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","latest-sync-info"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Summary of the product catalog sync for a connection: the most recently updated product (by TikTok's update time), the total number of synced products, and when the last product sync ran.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","products","latest-sync-info"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Ceramic Mug — 12oz\",\n    \"latest_product_date\": \"2026-06-19T22:14:07+00:00\",\n    \"total_products\": 312,\n    \"last_synced_at\": \"2026-06-20T07:45:00+00:00\"\n  }\n}"}]},{"name":"List Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/locations","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","locations"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Returns all known TikTok Shop warehouses for the integration instance (from the local cache).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/locations","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","locations"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 30,\n      \"integration_instance_id\": 12,\n      \"tiktok_warehouse_id\": \"7497123456789\",\n      \"name\": \"Acme US Warehouse\",\n      \"type\": \"SALES_WAREHOUSE\",\n      \"is_default\": true\n    }\n  ]\n}"}]},{"name":"Refresh Locations from TikTok","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/locations","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","locations"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Pull the seller's warehouses from TikTok Shop into the local cache and seed the per-warehouse master-of-stock panel. Returns the number of warehouses synced.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/locations","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","locations"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouses_synced\": 3\n  },\n  \"message\": \"Refreshed 3 TikTok Shop warehouse(s).\"\n}"}]},{"name":"List Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Paginated inventory comparison for this connection — one row per SKU × TikTok warehouse. Each row pairs the SKU.io computed available quantity (`sku_quantity`) with the last-observed TikTok quantity (`sales_channel_quantity`) and derives a `status`:\n\n- `needs_recalc` — the cache is flagged for recomputation (`is_sku_recalculation_needed`).\n- `synced` — computed quantity equals the channel quantity (null treated as 0; negatives clamp-aware when negative inventory is disallowed).\n- `variance` — the two differ (see `variance` = `sku_quantity - sales_channel_quantity`).\n- `not_managed` — SKU.io is not the master of stock for this warehouse, so its inventory is neither computed nor pushed; the row is excluded from the in-sync / variance / needs-recalc counts.\n\n**Filters:** `filter[search]` (listing SKU / title / product SKU / offering name / offering SKU), `filter[status]` (synced|variance|needs_recalc; is / is_one_of / is_not), `filter[location_id]` (local warehouse PK; is / is_one_of), `filter[sku_quantity]` & `filter[sales_channel_quantity]` (numeric operators), `filter[sales_channel_quantity_updated_at]` & `filter[sales_channel_quantity_synced_at]` (datetime operators), `filter[listing_sku]`, `filter[title]`.\n\n**Sorts** (prefix `-` for DESC; default `-id`): id, sku_quantity, sales_channel_quantity, created_at, updated_at.\n\nPagination: `page`, `per_page` (default 10). Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55210,\n      \"product_listing_id\": 3301,\n      \"document_id\": 902,\n      \"listing_sku\": \"MUG-12-WHT\",\n      \"title\": \"Ceramic Mug — 12oz\",\n      \"product\": {\n        \"id\": 4521,\n        \"sku\": \"MUG-12-WHT\",\n        \"name\": \"Ceramic Mug 12oz White\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": 42,\n      \"location_name\": \"Main US Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 10,\n      \"sales_channel_quantity\": 8,\n      \"variance\": 2,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-20T07:45:00+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-20T07:50:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-20T08:10:00+00:00\",\n      \"created_at\": \"2026-03-02T18:25:00+00:00\",\n      \"updated_at\": \"2026-06-20T08:10:00+00:00\"\n    },\n    {\n      \"id\": 55211,\n      \"product_listing_id\": 3302,\n      \"document_id\": 903,\n      \"listing_sku\": \"MUG-16-BLK\",\n      \"title\": \"Ceramic Mug 16oz\",\n      \"product\": {\n        \"id\": 4522,\n        \"sku\": \"MUG-16-BLK\",\n        \"name\": \"Ceramic Mug 16oz Black\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": 43,\n      \"location_name\": \"Returns Overflow Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 0,\n      \"sales_channel_quantity\": null,\n      \"variance\": 0,\n      \"status\": \"not_managed\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-20T07:45:00+00:00\",\n      \"sales_channel_quantity_updated_at\": null,\n      \"sales_channel_quantity_synced_at\": null,\n      \"created_at\": \"2026-03-02T18:25:00+00:00\",\n      \"updated_at\": \"2026-06-20T08:10:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 9,\n  \"per_page\": 10,\n  \"total\": 84,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Get Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/summary","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","summary"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"KPI counts for the inventory page: total cache rows, in-sync count, variance count, and needs-recalculation count, the not-managed count (warehouses where SKU.io is not the master of stock — inventory is not synced for them), plus the most recent fetch (`last_fetch_at`) and push (`last_sync_at`) timestamps across this connection's rows. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/summary","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","summary"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 84,\n    \"in_sync\": 60,\n    \"with_variance\": 20,\n    \"needs_recalculation\": 4,\n    \"not_managed\": 3,\n    \"last_fetch_at\": \"2026-06-20 07:50:00\",\n    \"last_sync_at\": \"2026-06-20 08:10:00\"\n  }\n}"}]},{"name":"Recache Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/recache","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","recache"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Recompute the per-warehouse available-quantity cache for every mapped listing on this connection, applying the configured master-of-stock, buffer-stock, and min/max rules. Runs asynchronously and returns a tracked-job id you can poll via Get Recache Progress. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/recache","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","recache"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Inventory recache job has been queued\"\n}"}]},{"name":"Get Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/recache-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","recache-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]},"description":"Poll the tracked-job log for a recache job (see Recache Inventory). Returns the TrackedJobLog resource with status, progress, and completion results. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/recache-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","recache-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12345,\n    \"job_type\": \"App\\\\Models\\\\TrackedJobLog\",\n    \"queue\": \"default\",\n    \"job_name\": \"Recache TikTok Shop Inventory: My TikTok Store\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 12,\n      \"type\": \"Modules\\\\TikTokShop\\\\Entities\\\\TikTokShopIntegrationInstance\",\n      \"reference\": \"My TikTok Store\"\n    },\n    \"related_model_reference\": \"My TikTok Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T08:09:30.000000Z\",\n    \"completed_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"duration\": 30,\n    \"created_at\": \"2026-06-20T08:09:29.000000Z\",\n    \"updated_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"results\": {\n      \"step\": \"complete\",\n      \"step_message\": \"Recomputed inventory for 45 listings\",\n      \"products_processed\": 45,\n      \"total_products\": 45,\n      \"completed_at\": \"2026-06-20T08:10:00+00:00\"\n    },\n    \"total_items\": 45,\n    \"processed_items\": 45,\n    \"progress_percentage\": 100,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Sync Inventory to TikTok Shop","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Push the cached available quantities to TikTok Shop for every listing whose SKU.io quantity differs from what TikTok currently holds. Runs asynchronously and returns a tracked-job id you can poll via Get Sync Progress. Typically run after Recache Inventory. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Inventory sync job has been queued\"\n}"}]},{"name":"Get Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/sync-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","sync-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]},"description":"Poll the tracked-job log for a sync job (see Sync Inventory to TikTok Shop). Returns the TrackedJobLog resource with status, progress, and completion results. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/sync-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","sync-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12345,\n    \"job_type\": \"App\\\\Models\\\\TrackedJobLog\",\n    \"queue\": \"default\",\n    \"job_name\": \"Sync Inventory to TikTok Shop: My TikTok Store\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 12,\n      \"type\": \"Modules\\\\TikTokShop\\\\Entities\\\\TikTokShopIntegrationInstance\",\n      \"reference\": \"My TikTok Store\"\n    },\n    \"related_model_reference\": \"My TikTok Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T08:09:30.000000Z\",\n    \"completed_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"duration\": 30,\n    \"created_at\": \"2026-06-20T08:09:29.000000Z\",\n    \"updated_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"results\": {\n      \"step\": \"complete\",\n      \"step_message\": \"Pushed inventory for 20 listings\",\n      \"products_processed\": 20,\n      \"total_products\": 20,\n      \"completed_at\": \"2026-06-20T08:10:00+00:00\"\n    },\n    \"total_items\": 20,\n    \"processed_items\": 20,\n    \"progress_percentage\": 100,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Fetch Live Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","fetch-live"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Fetch live per-warehouse quantities from TikTok Shop into the sales-channel cache. TikTok has no bulk inventory-read endpoint, so this issues per-product detail GETs for every product with at least one mapped SKU. This is an inbound observation only — it writes `sales_channel_quantity` / `sales_channel_quantity_updated_at` and never the push timestamp. Runs asynchronously and returns a tracked-job id you can poll via Get Fetch Live Progress. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/fetch-live","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","fetch-live"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  },\n  \"message\": \"Fetch live inventory job has been queued\"\n}"}]},{"name":"Get Fetch Live Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/fetch-live-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","fetch-live-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]},"description":"Poll the tracked-job log for a fetch-live job (see Fetch Live Inventory). Returns the TrackedJobLog resource with status, per-product progress, and completion results. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/inventory/fetch-live-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","inventory","fetch-live-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12345,\n    \"job_type\": \"App\\\\Models\\\\TrackedJobLog\",\n    \"queue\": \"default\",\n    \"job_name\": \"Fetch Live TikTok Shop Inventory: My TikTok Store\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 12,\n      \"type\": \"Modules\\\\TikTokShop\\\\Entities\\\\TikTokShopIntegrationInstance\",\n      \"reference\": \"My TikTok Store\"\n    },\n    \"related_model_reference\": \"My TikTok Store\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-20T08:09:30.000000Z\",\n    \"completed_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"duration\": 30,\n    \"created_at\": \"2026-06-20T08:09:29.000000Z\",\n    \"updated_at\": \"2026-06-20T08:10:00.000000Z\",\n    \"results\": {\n      \"step\": \"complete\",\n      \"step_message\": \"Fetched 120 inventory levels across 45 products\",\n      \"products_processed\": 45,\n      \"total_products\": 45,\n      \"cache_entries_updated\": 120,\n      \"failed_count\": 0,\n      \"has_failures\": false,\n      \"completed_at\": \"2026-06-20T08:10:00+00:00\"\n    },\n    \"total_items\": 45,\n    \"processed_items\": 45,\n    \"progress_percentage\": 100,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"List Packages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/packages","host":["{{baseUrl}}"],"path":["api","tiktok-shop","packages"]},"description":"Paginated list of TikTok Shop packages across one or many integration instances. Includes related order summary.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/packages","host":["{{baseUrl}}"],"path":["api","tiktok-shop","packages"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"tiktok_shop_order_id\": 1234,\n      \"integration_instance_id\": 1,\n      \"package_id\": \"P-9876543210\",\n      \"tracking_number\": \"1ZTEST123456789\",\n      \"shipping_provider_id\": \"ups\",\n      \"shipping_provider_name\": \"UPS\",\n      \"package_status\": \"IN_TRANSIT\",\n      \"shipped_at\": \"2026-04-20T15:32:00Z\",\n      \"delivered_at\": null,\n      \"created_at\": \"2026-04-20T10:00:00Z\",\n      \"updated_at\": \"2026-04-20T15:32:00Z\",\n      \"order\": {\n        \"id\": 1234,\n        \"tiktok_order_id\": \"576XXXXXXXXXXX\",\n        \"integration_instance_id\": 1\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 15,\n  \"total\": 73,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://example.test/api/tiktok-shop/packages?page=1\",\n  \"last_page_url\": \"https://example.test/api/tiktok-shop/packages?page=5\",\n  \"next_page_url\": \"https://example.test/api/tiktok-shop/packages?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://example.test/api/tiktok-shop/packages\"\n}"}]},{"name":"List Pending Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/fulfillments/pending","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","fulfillments","pending"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Paginated list of SalesOrderFulfillment records awaiting TikTok tracking submission for the given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns LengthAwarePaginator of pending sales order fulfillment object."}},{"name":"Fulfillment Sync Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","fulfillments","stats"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Counts and sync-schedule note for the fulfillments page.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse:\n```json\n{\n  \"data\": {\n    \"pending_sync_count\": 0,\n    \"mismatch_count\": 0,\n    \"sync_schedule\": {\n      \"interval\": 0,\n      \"unit\": \"event\",\n      \"description\": \"Tracking is automatically submitted to TikTok Shop when an order is fulfilled in SKU.io.\"\n    }\n  }\n}\n```"}},{"name":"Submit Single Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/fulfillments/{sales_order_fulfillment_id}/submit","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","fulfillments",":sales_order_fulfillment_id","submit"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"sales_order_fulfillment_id","value":"","description":"The sales order fulfillment ID."}]},"description":"Submit one SalesOrderFulfillment's tracking to TikTok Shop.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `force_submit` (optional, bool) — bypass non-production guard.\n\nReturns 200 with `skipped_non_production: true` when not on production and `force_submit` is false. Returns 422 on TikTok submission failure.","body":{"mode":"raw","raw":"{\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Submit Bulk Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/fulfillments/submit-bulk","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","fulfillments","submit-bulk"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Submit tracking for a list of SalesOrderFulfillment IDs.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `ids` (required, `array<int>`) — must exist in `sales_order_fulfillments`.\n- `force_submit` (optional, bool)\n\nResponse `data`: `{ submitted: int, failed: int }`. `errors` lists failures per ID.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ],\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Submit All Pending Fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/fulfillments/submit-all","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","fulfillments","submit-all"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Submit tracking for every pending fulfillment for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `force_submit` (optional, bool)\n\nSame response shape as submit-bulk.","body":{"mode":"raw","raw":"{\n  \"force_submit\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/returns?filter[integration_instance_ids]={{integration_instance_id}}&per_page=15","host":["{{baseUrl}}"],"path":["api","tiktok-shop","returns"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Filter by integration instance ids (see the Filtering & Sorting guide for operators).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"List Returns\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Show Return","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/returns/{return_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","returns",":return_id"],"variable":[{"key":"return_id","value":"","description":"The return_id identifier"}]},"description":"Returns a single TikTok Shop return with the related order eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/returns/{return_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","returns",":return_id"],"variable":[{"key":"return_id","value":"","description":"The return_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 700,\n    \"tiktok_return_id\": \"5798833445566\",\n    \"return_status\": \"RETURN_REQUESTED\",\n    \"return_reason\": \"Item not as described\",\n    \"order\": {\n      \"id\": 100,\n      \"tiktok_order_id\": \"576461413164253045\"\n    }\n  }\n}"}]},{"name":"Sync Returns (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/returns/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","returns","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Dispatches a background job for the instance. Returns a tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/returns/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","returns","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9879\n  },\n  \"message\": \"Returns sync started.\"\n}"}]},{"name":"List Refunds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/refunds?filter[integration_instance_ids]={{integration_instance_id}}&per_page=15","host":["{{baseUrl}}"],"path":["api","tiktok-shop","refunds"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Filter by integration instance ids (see the Filtering & Sorting guide for operators).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"List Refunds\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Show Refund","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/refunds/{refund_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","refunds",":refund_id"],"variable":[{"key":"refund_id","value":"","description":"The refund_id identifier"}]},"description":"Returns a single TikTok Shop refund with the related order eager-loaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/refunds/{refund_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","refunds",":refund_id"],"variable":[{"key":"refund_id","value":"","description":"The refund_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 850,\n    \"tiktok_refund_id\": \"9982334455667\",\n    \"refund_status\": \"SUCCESS\",\n    \"refund_amount\": 49.99,\n    \"order\": {\n      \"id\": 100,\n      \"tiktok_order_id\": \"576461413164253045\"\n    }\n  }\n}"}]},{"name":"Sync Refunds (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/refunds/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","refunds","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Dispatches a background job for the instance. Returns a tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/refunds/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","refunds","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9880\n  },\n  \"message\": \"Refunds sync started.\"\n}"}]},{"name":"List Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/transactions?filter[integration_instance_ids]={{integration_instance_id}}&per_page=15","host":["{{baseUrl}}"],"path":["api","tiktok-shop","transactions"],"query":[{"key":"filter[integration_instance_ids]","value":"{{integration_instance_id}}","description":"Comma-separated integration instance IDs","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of TikTok Shop transactions (statement transactions) across integration instances. Supports Spatie QueryBuilder filters and sorts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAllowed filters: `integration_instance_ids` (comma-separated), `transaction_type` (exact), `currency` (exact), `tiktok_transaction_id` (exact), `adjustment_id` (exact), `associated_order_id` (exact), `related_order_id` (exact), `transaction_time_from`/`transaction_time_to` (Y-m-d or m/d/Y), `statement_time_from`/`statement_time_to`, `amount_min`/`amount_max` (numeric), `search` (matches across tiktok_transaction_id, related_order_id, adjustment_id, associated_order_id, transaction_type, settlement_id).\n\nAllowed sorts: `id`, `tiktok_transaction_time`, `statement_time`, `amount`, `net_amount`, `settlement_amount`, `fee_amount`, `created_at`, `updated_at`. Prefix with `-` for desc."}},{"name":"Get Transaction","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/transactions/{transaction_id}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","transactions",":transaction_id"],"variable":[{"key":"transaction_id","value":"","description":"The transaction ID."}]},"description":"Returns a single TikTok Shop transaction with its `integration_instance` and (when matched by `related_order_id` -> `tiktok_order_id`) `order` relations eager-loaded for the detail page. Includes native columns for money breakdown (revenue_amount, fee_amount, tax_amount, net_amount, settlement_amount, shipping_cost_amount, reserve_amount), identifiers (adjustment_id, associated_order_id), `statement_time`, and JSON sub-structures `fee_breakdown_json` / `tax_breakdown_json`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Raw Transaction from TikTok","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/transactions/{transaction_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","transactions",":transaction_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"transaction_id","value":"","description":"The transaction ID."}]},"description":"Fetches the live transaction JSON directly from the TikTok Shop Finance API for a single previously-synced transaction. It reads the parent statement's transactions via `GET /finance/202309/statements/{statement_id}/statement_transactions` (paginated via `page_token`, `sort_field=order_create_time`) and returns the entry whose id matches the stored `tiktok_transaction_id`. Mirrors the `Get Raw Order from TikTok` pattern — used by the frontend Raw Data section as a fetch-on-demand tool to inspect the current upstream payload without writing it to the database.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath params:\n- `tikTokShopIntegrationInstance` (required) — integration instance id. Must own the transaction, otherwise `403` is returned.\n- `tikTokShopTransaction` (required) — local TikTokShopTransaction id. Must have a stored `statement_id`, otherwise `422` is returned.\n\nReturns: `{ data: <raw TikTok Shop statement transaction object> | null }` (`null` when no matching row is found on the statement)."},"response":[{"name":"Successful response","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/transactions/{transaction_id}/raw","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","transactions",":transaction_id","raw"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."},{"key":"transaction_id","value":"","description":"The transaction ID."}]}},"status":"Successful response","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"7012345678901234567\",\n    \"type\": \"ORDER\",\n    \"order_id\": \"576461413038489876\",\n    \"adjustment_id\": null,\n    \"transaction_time\": 1745164200,\n    \"statement_time\": 1745250720,\n    \"currency\": \"USD\",\n    \"revenue_amount\": {\n      \"amount\": \"42.99\",\n      \"currency\": \"USD\"\n    },\n    \"fee_amount\": {\n      \"amount\": \"-3.50\",\n      \"currency\": \"USD\"\n    },\n    \"tax_amount\": {\n      \"amount\": \"-2.10\",\n      \"currency\": \"USD\"\n    },\n    \"net_amount\": {\n      \"amount\": \"37.39\",\n      \"currency\": \"USD\"\n    },\n    \"settlement_amount\": {\n      \"amount\": \"37.39\",\n      \"currency\": \"USD\"\n    },\n    \"shipping_cost_amount\": {\n      \"amount\": \"-3.00\",\n      \"currency\": \"USD\"\n    },\n    \"reserve_amount\": {\n      \"amount\": \"0.00\",\n      \"currency\": \"USD\"\n    },\n    \"fee_breakdown\": [\n      {\n        \"type\": \"PLATFORM_COMMISSION\",\n        \"amount\": {\n          \"amount\": \"-2.50\",\n          \"currency\": \"USD\"\n        }\n      },\n      {\n        \"type\": \"PAYMENT_FEE\",\n        \"amount\": {\n          \"amount\": \"-1.00\",\n          \"currency\": \"USD\"\n        }\n      }\n    ],\n    \"tax_breakdown\": [\n      {\n        \"type\": \"SALES_TAX\",\n        \"amount\": {\n          \"amount\": \"-2.10\",\n          \"currency\": \"USD\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Sync Transactions (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/transactions/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","transactions","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Dispatches a background job. Returns a tracked_job_log_id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- since (nullable, date): pull transactions since this time. Defaults to 7 days ago.\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"since\": \"2026-04-19T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/transactions/sync","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","transactions","sync"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9881\n  },\n  \"message\": \"Transactions sync started.\"\n}"}]},{"name":"List Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Returns the existing warehouse mappings, the mappable TikTok Shop warehouses for the instance, and all SKU.io warehouses.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOnly sales/pickup warehouses are returned in `tiktok_warehouses` — warehouses with `type` `RETURN_WAREHOUSE` are excluded here (they still appear on the Locations tab). Warehouses with a null `type` are kept so unclassified warehouses remain mappable.\n\nEach SKU.io warehouse includes a `display_name`: supplier warehouses are prefixed with the supplier name (e.g. \"Acme Supply Co - Main Warehouse\") so the mapping dropdown isn't a wall of identical names; non-supplier warehouses fall back to the plain name.\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 1,\n        \"integration_instance_id\": 12,\n        \"tiktok_shop_warehouse_id\": 30,\n        \"sku_io_warehouse_id\": 5\n      }\n    ],\n    \"tiktok_warehouses\": [\n      {\n        \"id\": 30,\n        \"name\": \"Acme US Warehouse\",\n        \"tiktok_warehouse_id\": \"7497123456789\",\n        \"type\": \"SALES_WAREHOUSE\"\n      }\n    ],\n    \"sku_warehouses\": [\n      {\n        \"id\": 5,\n        \"name\": \"Main Warehouse\",\n        \"display_name\": \"Acme Supply Co - Main Warehouse\"\n      }\n    ]\n  }\n}"}]},{"name":"Upsert Warehouse Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Create or update a warehouse mapping for the instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- tiktok_shop_warehouse_id (required, integer, exists tiktok_shop_warehouses.id)\n- sku_io_warehouse_id (required, integer, exists warehouses.id)\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"tiktok_shop_warehouse_id\": 30,\n  \"sku_io_warehouse_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_instance_id\": 12,\n    \"tiktok_shop_warehouse_id\": 30,\n    \"sku_io_warehouse_id\": 5\n  }\n}"}]},{"name":"Delete Warehouse Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings/{tiktokShopWarehouseId}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings",":tiktokShopWarehouseId"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"tiktokShopWarehouseId","value":"","description":"The tiktok shop warehouse ID."}]},"description":"Deletes the mapping for the given TikTok Shop warehouse id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/warehouse-mappings/{tiktokShopWarehouseId}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","warehouse-mappings",":tiktokShopWarehouseId"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"tiktokShopWarehouseId","value":"","description":"The tiktok shop warehouse ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": true\n  }\n}"}]},{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Returns existing mappings, the TikTok shipping provider list (best-effort), and all SKU.io shipping methods.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 2,\n        \"integration_instance_id\": 12,\n        \"sku_io_shipping_method_id\": 7,\n        \"tiktok_shipping_provider_id\": \"7208012345678\",\n        \"tiktok_shipping_provider_name\": \"USPS\"\n      }\n    ],\n    \"tiktok_shipping_providers\": [\n      {\n        \"id\": \"7208012345678\",\n        \"name\": \"USPS\"\n      },\n      {\n        \"id\": \"7208087654321\",\n        \"name\": \"FedEx\"\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 7,\n        \"name\": \"USPS Priority\"\n      }\n    ]\n  }\n}"}]},{"name":"Upsert Shipping Method Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Create or update a mapping between a SKU.io shipping method and a TikTok shipping provider.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- sku_io_shipping_method_id (required, integer, exists shipping_methods.id)\n- tiktok_shipping_provider_id (required, string, max 100)\n- tiktok_shipping_provider_name (nullable, string, max 255)\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_io_shipping_method_id\": 7,\n  \"tiktok_shipping_provider_id\": \"7208012345678\",\n  \"tiktok_shipping_provider_name\": \"USPS\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"sku_io_shipping_method_id\": 7,\n    \"tiktok_shipping_provider_id\": \"7208012345678\",\n    \"tiktok_shipping_provider_name\": \"USPS\"\n  }\n}"}]},{"name":"Delete Shipping Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings/{skuShippingMethodId}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings",":skuShippingMethodId"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"skuShippingMethodId","value":"","description":"The sku shipping method ID."}]},"description":"Deletes the mapping for the given SKU.io shipping method id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/shipping-method-mappings/{skuShippingMethodId}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","shipping-method-mappings",":skuShippingMethodId"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"},{"key":"skuShippingMethodId","value":"","description":"The sku shipping method ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": true\n  }\n}"}]},{"name":"List Payment Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Returns existing mappings, distinct observed TikTok payment method names (from synced orders), and all SKU.io PaymentType records.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"id\": 3,\n        \"integration_instance_id\": 12,\n        \"tiktok_payment_method_name\": \"PayPal\",\n        \"sku_io_payment_type_id\": 4\n      }\n    ],\n    \"tiktok_payment_methods\": [\n      \"Credit Card\",\n      \"PayPal\"\n    ],\n    \"sku_payment_types\": [\n      {\n        \"id\": 4,\n        \"name\": \"PayPal\"\n      },\n      {\n        \"id\": 5,\n        \"name\": \"Credit Card\"\n      }\n    ]\n  }\n}"}]},{"name":"Upsert Payment Method Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Create or update a mapping between a TikTok payment method name and a SKU.io PaymentType.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- tiktok_payment_method_name (required, string, max 150)\n- sku_io_payment_type_id (required, integer, exists payment_types.id)\n\nRequires Bearer token.","body":{"mode":"raw","raw":"{\n  \"tiktok_payment_method_name\": \"PayPal\",\n  \"sku_io_payment_type_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"tiktok_payment_method_name\": \"PayPal\",\n    \"sku_io_payment_type_id\": 4\n  }\n}"}]},{"name":"Delete Payment Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]},"description":"Deletes the mapping for a given TikTok payment method name.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- tiktok_payment_method_name (required, string)\n\nRequires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/payment-method-mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","payment-method-mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration_instance_id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"deleted\": true\n  }\n}"}]},{"name":"Get Available Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","tiktok-shop","mappings","available-fields"]},"description":"Returns the catalog of available TikTok Shop source fields (grouped by Identifiers / Product Info / Variant Details / Pricing / Media / Timestamps) and SKU.io target fields (including dynamic ProductPricingTier / SupplierPricingTier / Attribute fields). Use this to populate field selectors before configuring mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/mappings/available-fields","host":["{{baseUrl}}"],"path":["api","tiktok-shop","mappings","available-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tiktok_fields\": {\n      \"tiktok_product_id\": {\n        \"name\": \"tiktok_product_id\",\n        \"label\": \"TikTok Product ID\",\n        \"type\": \"string\",\n        \"description\": \"Unique TikTok Shop product identifier\",\n        \"group\": \"Identifiers\"\n      },\n      \"title\": {\n        \"name\": \"title\",\n        \"label\": \"Product Title\",\n        \"type\": \"string\",\n        \"group\": \"Product Info\"\n      },\n      \"seller_sku\": {\n        \"name\": \"seller_sku\",\n        \"label\": \"Seller SKU\",\n        \"type\": \"string\",\n        \"group\": \"Variant Details\"\n      },\n      \"sale_price\": {\n        \"name\": \"sale_price\",\n        \"label\": \"Sale Price\",\n        \"type\": \"decimal\",\n        \"group\": \"Pricing\"\n      }\n    },\n    \"sku_fields\": {\n      \"sku\": {\n        \"name\": \"sku\",\n        \"label\": \"SKU\",\n        \"type\": \"string\",\n        \"group\": \"Identifiers\"\n      },\n      \"item_name\": {\n        \"name\": \"item_name\",\n        \"label\": \"Item Name\",\n        \"type\": \"string\",\n        \"group\": \"Product Info\"\n      },\n      \"price.1.value\": {\n        \"name\": \"price.1.value\",\n        \"label\": \"Price (Default Tier)\",\n        \"type\": \"decimal\",\n        \"group\": \"Pricing\"\n      }\n    }\n  }\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Returns the full mapping picture for a TikTok Shop integration instance: available source/target fields, system defaults, custom (overridden) mappings persisted by the merchant, and the effective merged set used during product creation. Each mapping entry contains `listing_field` (TikTok side), `sku_field` (SKU.io side), and an optional `parsers` array of transforms (rules: `fr` find/replace, `tl` trim-left, `tr` trim-right, `append`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My TikTok Shop\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"sale_price\",\n        \"sku_field\": \"price.1.value\",\n        \"parsers\": []\n      }\n    ],\n    \"available_tiktok_fields\": {\n      \"title\": {\n        \"name\": \"title\",\n        \"label\": \"Product Title\",\n        \"type\": \"string\",\n        \"group\": \"Product Info\"\n      }\n    },\n    \"available_sku_fields\": {\n      \"item_name\": {\n        \"name\": \"item_name\",\n        \"label\": \"Item Name\",\n        \"type\": \"string\",\n        \"group\": \"Product Info\"\n      }\n    },\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      }\n    ],\n    \"custom_mappings\": [],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Replace the custom field mappings for this integration instance. Body: `mappings` (array, required) — each entry has `listing_field` (string, required), `sku_field` (string, required), and `parsers` (array, optional; each parser has `rule` one of `fr`/`tl`/`tr`/`append` and `args` shape depending on rule). The submitted set fully replaces any existing custom mappings; system defaults remain in effect for fields not included. Returns the refreshed effective mappings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"title\",\n      \"sku_field\": \"item_name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"seller_sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"sale_price\",\n      \"sku_field\": \"price.1.value\",\n      \"parsers\": [\n        {\n          \"rule\": \"fr\",\n          \"args\": {\n            \"find\": \"USD\",\n            \"replace\": \"\"\n          }\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tiktok-shop/integration-instances/{integration_instance_id}/mappings","host":["{{baseUrl}}"],"path":["api","tiktok-shop","integration-instances",":integration_instance_id","mappings"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"integration_name\": \"My TikTok Shop\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"title\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"seller_sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events"]},"description":"Paginated list of TikTok Shop webhook events across one or many integration instances.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"integration_instance_id\": 1,\n      \"topic\": \"ORDER_STATUS_CHANGE\",\n      \"unique_id\": \"576XXXXXXXXXXX\",\n      \"json_data\": {\n        \"shop_id\": \"7400000000000000000\",\n        \"type\": 1,\n        \"data\": {\n          \"order_id\": \"576XXXXXXXXXXX\",\n          \"order_status\": \"AWAITING_SHIPMENT\"\n        }\n      },\n      \"processing_status\": \"completed\",\n      \"processed_at\": \"2026-04-20T10:00:05Z\",\n      \"processing_attempts\": 1,\n      \"processing_error\": null,\n      \"created_at\": \"2026-04-20T10:00:00Z\",\n      \"updated_at\": \"2026-04-20T10:00:05Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 42\n}"}]},{"name":"Delete All Webhook Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events"]},"description":"Permanently delete ALL webhook events, optionally scoped to one or more integration instances. Cannot be undone.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All events deleted\",\n  \"deleted_count\": 44\n}"}]},{"name":"Get Webhook Event Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","stats"]},"description":"Counts of webhook events grouped by processing status (pending, processing, completed, failed) plus a total. Used to power the summary cards on the Webhooks Events tab.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_count\": 3,\n    \"processing_count\": 1,\n    \"completed_count\": 38,\n    \"failed_count\": 2,\n    \"total_count\": 44\n  }\n}"}]},{"name":"Show Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]},"description":"Show a single webhook event including its raw payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 1,\n    \"topic\": \"ORDER_STATUS_CHANGE\",\n    \"unique_id\": \"576XXXXXXXXXXX\",\n    \"json_data\": {\n      \"shop_id\": \"7400000000000000000\",\n      \"type\": 1,\n      \"data\": {\n        \"order_id\": \"576XXXXXXXXXXX\",\n        \"order_status\": \"AWAITING_SHIPMENT\"\n      }\n    },\n    \"processing_status\": \"completed\",\n    \"processed_at\": \"2026-04-20T10:00:05Z\",\n    \"processing_attempts\": 1,\n    \"processing_error\": null,\n    \"created_at\": \"2026-04-20T10:00:00Z\",\n    \"updated_at\": \"2026-04-20T10:00:05Z\"\n  }\n}"}]},{"name":"Delete Webhook Event","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]},"description":"Permanently delete a single webhook event.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Event deleted\"\n}"}]},{"name":"Process Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}/process","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent","process"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]},"description":"Re-dispatch the processing job for a webhook event without resetting its status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}/process","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent","process"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Event queued for processing\"\n}"}]},{"name":"Reprocess Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}/reprocess","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent","reprocess"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]},"description":"Reset a webhook event back to pending (clears processed_at and processing_error) and re-dispatch the processing job. Use this for failed events.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/{tikTokShopWebhookEvent}/reprocess","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events",":tikTokShopWebhookEvent","reprocess"],"variable":[{"key":"tikTokShopWebhookEvent","value":"","description":"The tik tok shop webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Event reset and queued for reprocessing\"\n}"}]},{"name":"Bulk Delete Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-delete"]},"description":"Permanently delete multiple webhook events by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- ids (required, array of integers): IDs of events to delete\n\nAuthentication: Bearer token required.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    101,\n    102,\n    103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Events deleted\",\n  \"deleted_count\": 3\n}"}]},{"name":"Bulk Process Pending Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-process-pending","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-process-pending"]},"description":"Loop pending webhook events and dispatch a background job for each. Optionally scope to specific integration instances and cap the batch with `limit` (max 500, default 100).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors Shopify's processPendingEvents bulk handler. Returns `queued_count` (number of jobs dispatched).","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1,2\",\n  \"limit\": 100\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-process-pending","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-process-pending"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"queued_count\": 17\n  },\n  \"message\": \"Pending webhook events queued for processing\"\n}"}]},{"name":"Bulk Retry Failed Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-retry-failed","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-retry-failed"]},"description":"Reset failed webhook events to pending and re-dispatch a background job for each. Optionally scope to integration instances and cap with `limit` (max 500, default 100).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMirrors Shopify's retryFailedEvents bulk handler. Returns `retried_count`.","body":{"mode":"raw","raw":"{\n  \"integration_instance_ids\": \"1\",\n  \"limit\": 100\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tiktok-shop/webhook-events/bulk-retry-failed","host":["{{baseUrl}}"],"path":["api","tiktok-shop","webhook-events","bulk-retry-failed"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"retried_count\": 8\n  },\n  \"message\": \"Failed webhook events reset and queued for retry\"\n}"}]},{"name":"Receive Webhook (TikTok → SKU.io)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/webhooks/tiktok-shop","host":["{{baseUrl}}"],"path":["webhooks","tiktok-shop"]},"description":"Global (per-environment) endpoint that receives signed webhook events from TikTok Shop — this is the URL configured on the TikTok Shop app.\n\nNo bearer auth: the request is authenticated by TikTok's HMAC signature in the `Authorization` header (HMAC-SHA256 over `app_secret + raw_body`, keyed by the app secret — sandbox or production secret chosen by the resolved instance's environment setting).\n\n**Tenant routing:** every tenant's webhooks arrive at this ONE URL. The `InitializeTenantFromWebhookPayload` middleware resolves the tenant from the payload `shop_id` (top-level or `data.shop_id`) via the central `tenant_integration_routes` registry (external_key = the instance's primary shop id), forwards to the tenant's home pod if needed, initialises tenancy, and exposes the instance to the controller.\n\n**Flow:** 400 empty body → 404 missing/unknown `shop_id` → 401 invalid signature → 422 missing `type` → 200 event persisted + processing job dispatched.\n\nTopics by `type`: 1 ORDER_STATUS_CHANGE, 2 REVERSE_STATUS_CHANGE, 5 PACKAGE_UPDATE, 7 PRODUCT_STATUS_CHANGE, 12 AUTHORIZATION_CANCELLATION; unknown types stored as TYPE_{n}.","body":{"mode":"raw","raw":"{\n  \"shop_id\": \"7495092941234567890\",\n  \"type\": 1,\n  \"tts_notification_id\": \"7development123456\",\n  \"timestamp\": 1717000000,\n  \"data\": {\n    \"order_id\": \"576461413038785752\",\n    \"order_status\": \"AWAITING_SHIPMENT\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/webhooks/tiktok-shop","host":["{{baseUrl}}"],"path":["webhooks","tiktok-shop"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"received\": true\n}"}]},{"name":"OAuth Callback","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/tiktok-shop/callback?code=AUTH_CODE_FROM_TIKTOK&state=8c7e0d12-b91c-4d2b-a6f4-9c0a2bb1f0aa","host":["{{baseUrl}}"],"path":["tiktok-shop","callback"],"query":[{"key":"code","value":"AUTH_CODE_FROM_TIKTOK","description":"Authorization code returned by TikTok","disabled":true},{"key":"state","value":"8c7e0d12-b91c-4d2b-a6f4-9c0a2bb1f0aa","description":"State UUID issued by /oauth/init","disabled":true}]},"description":"Browser redirect target after the merchant authorizes the app on TikTok. Exchanges the auth code for access/refresh tokens, persists a TikTokShopIntegrationInstance, syncs authorized shops, subscribes webhooks, dispatches the initial product + recent-order backfill on the interactive queue (a background job + a background job), and redirects into the SPA. NOT a JSON endpoint.\n\nThe single registered callback URL lives on the central apex (app.sku.io), so the callback always lands there with no tenant header. Tenancy is restored from the tenant-prefixed state (`<tenantId>_<uuid>`), and the final redirect is built with TenantUrl::to so it targets the tenant's OWN subdomain (e.g. https://siber.sku.io/v2/integrations/tiktok-shop/{id}/dashboard) — loading the SPA in tenant context instead of forcing the central 'Choose an account' picker. On invalid/expired state it redirects to the tenant subdomain's /v2/integrations/tiktok-shop/new?error=... page.\n\nNo auth middleware — the cached state UUID is the security mechanism."},"response":[{"name":"Found","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/tiktok-shop/callback?code=AUTH_CODE_FROM_TIKTOK&state=8c7e0d12-b91c-4d2b-a6f4-9c0a2bb1f0aa","host":["{{baseUrl}}"],"path":["tiktok-shop","callback"],"query":[{"key":"code","value":"AUTH_CODE_FROM_TIKTOK","description":"Authorization code returned by TikTok","disabled":true},{"key":"state","value":"8c7e0d12-b91c-4d2b-a6f4-9c0a2bb1f0aa","description":"State UUID issued by /oauth/init","disabled":true}]}},"status":"Found","code":302,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]}]},{"name":"Temu","item":[{"name":"Get Config","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/config","host":["{{baseUrl}}"],"path":["api","temu","config"]},"description":"Returns server-side capability flags used by the new-instance form on the frontend.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response fields:**\n- `can_pick_environment` (bool) — `true` on non-production servers, `false` on production. The UI uses this to decide whether to render the sandbox/production toggle on the new-instance form. On a production server the `HasIntegrationEnvironment` trait pins PRODUCTION regardless of the user's choice, so showing the toggle there would just be misleading.\n\n**Authentication:** Bearer token (Sanctum)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/config","host":["{{baseUrl}}"],"path":["api","temu","config"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"can_pick_environment\": true\n  }\n}"}]},{"name":"Initialize OAuth","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/oauth/initialize","host":["{{baseUrl}}"],"path":["api","temu","oauth","initialize"]},"description":"Starts a new Temu OAuth flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nGenerates a tenant-prefixed `state` so the OAuth callback (which lands on the central landlord domain with no tenant header) can recover tenancy from the state alone. Stores the chosen name + environment + integration_settings in a file cache for 1 hour so that `POST /api/temu/oauth/complete` can pick them back up after the merchant returns from Temu.\n\nThe returned `authorization_url` is where the frontend redirects/pops up the merchant to authorize SKU.io as a Temu app.\n\n**Request body (TemuInitializeIntegrationData):**\n- `name` (string, required) — Display name for the new integration instance.\n- `environment` (string, optional) — One of `sandbox` or `production`. Honoured only on non-production servers; on prod the `HasIntegrationEnvironment` trait pins PRODUCTION regardless. Defaults to `sandbox` on non-prod, `production` on prod.\n- `integration_settings` (object, optional) — Free-form JSON persisted on the instance. Used by the inventory + sync modules.\n\n**Response data:**\n- `state` (string) — Tenant-prefixed UUID. Round-trips through the OAuth callback and must be passed back to `oauth/complete`.\n- `authorization_url` (string) — Full Temu authorization URL with `appKey`, `redirect_uri`, and `state` query params.\n\n**Authentication:** Bearer token (Sanctum).\n\n**Throws:** `Exception` when Temu app credentials for the selected environment are not configured (missing `temu.<env>.app_key` / `app_secret`).","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme US Storefront\",\n  \"environment\": \"sandbox\",\n  \"integration_settings\": {\n    \"inventory\": {\n      \"warehouses\": []\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/oauth/initialize","host":["{{baseUrl}}"],"path":["api","temu","oauth","initialize"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"state\": \"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\",\n    \"authorization_url\": \"https://agentseller-us.temu.com/sc/seller-open/authorize?appKey=temu_app_key_demo&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fapi%2Ftemu%2Foauth%2Fcallback&state=42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\"\n  }\n}"}]},{"name":"Complete OAuth","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/oauth/complete","host":["{{baseUrl}}"],"path":["api","temu","oauth","complete"]},"description":"Exchanges the OAuth authorization code returned by Temu for an access token and creates a new `TemuIntegrationInstance` persisted with that token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe frontend calls this after Temu redirects the merchant back to `/v2/integrations/temu/callback` carrying `state`, `code`, and `callback_host`. The callback URL on the central landlord is `/api/temu/oauth/callback` (not documented here — it's a browser-redirected endpoint, not a JSON API).\n\nAfter the instance is created, initial sync jobs (warehouses, carriers, categories, products, orders) are dispatched.\n\n**Request body (raw JSON, not a FormRequest):**\n- `state` (string, required) — The state returned by `oauth/initialize`. Used to look up the stored name + environment + integration_settings from the file cache.\n- `code` (string, required) — Authorization code returned by Temu in the redirect query string.\n- `callback_host` (string, optional) — API host Temu returned on the redirect (e.g. `openapi-b-us.temu.com`). Used as the API base URL for the new instance; falls back to `config('temu.<env>.api_url')` when not present.\n\n**Response:** A 201 Created with the newly-persisted `TemuIntegrationInstance` resource. The shape is the same as `GET /api/temu/{integrationInstance}` (the Temu integration instance object which extends sales channel integration list view object).\n\n**Authentication:** Bearer token (Sanctum).\n\n**Throws:** `Exception` when `state` or `code` is missing, when the OAuth session has expired, has already been completed, or when the token exchange with Temu fails.","body":{"mode":"raw","raw":"{\n  \"state\": \"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\",\n  \"code\": \"AUTH_CODE_FROM_TEMU_REDIRECT_abc123\",\n  \"callback_host\": \"openapi-b-us.temu.com\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/oauth/complete","host":["{{baseUrl}}"],"path":["api","temu","oauth","complete"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Temu integration created successfully\",\n  \"data\": {\n    \"id\": 17,\n    \"integration_name\": \"Temu\",\n    \"sales_channel_id\": 42,\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Acme US Storefront\"\n    },\n    \"name\": \"Acme US Storefront\",\n    \"integration_settings\": {\n      \"inventory\": {\n        \"warehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"has_warehouse_mappings\": false,\n    \"has_carrier_mappings\": false,\n    \"created_at\": \"2026-06-19T18:42:11.000000Z\",\n    \"updated_at\": \"2026-06-19T18:42:11.000000Z\"\n  }\n}"}]},{"name":"Get OAuth Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/oauth/status?state=42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18","host":["{{baseUrl}}"],"path":["api","temu","oauth","status"],"query":[{"key":"state","value":"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18","description":"Tenant-prefixed state returned by /oauth/initialize.","disabled":true}]},"description":"Polled by the frontend after the OAuth popup/redirect to learn the state of the OAuth session.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed to determine whether Temu has called back yet, and what the next action is (e.g. proceed to `/oauth/complete`, or show a reconnection success toast).\n\n**Query parameters:**\n- `state` (string, required) — The state returned by `oauth/initialize`.\n\n**Response data (always returned with HTTP 200):**\n- `found` (bool) — `false` when state is missing, expired, or unknown. The remaining fields are omitted in that case (only `message` is present).\n- `completed` (bool) — `true` once `/oauth/complete` or a reconnection has marked the session as done.\n- `has_code` (bool) — `true` once the OAuth callback endpoint has received Temu's redirect and stored the authorization code in cache. The frontend uses this to know it's safe to call `/oauth/complete`.\n- `name` (string|null) — The display name the user picked at `/oauth/initialize`.\n- `message` (string, only on `found: false`) — Human-readable reason (missing parameter or expired session).\n\n**Authentication:** Bearer token (Sanctum)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/oauth/status?state=42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18","host":["{{baseUrl}}"],"path":["api","temu","oauth","status"],"query":[{"key":"state","value":"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18","description":"Tenant-prefixed state returned by /oauth/initialize.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"found\": true,\n    \"completed\": false,\n    \"has_code\": true,\n    \"name\": \"Acme US Storefront\"\n  }\n}"}]},{"name":"Sandbox Initialize","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/sandbox/initialize","host":["{{baseUrl}}"],"path":["api","temu","sandbox","initialize"]},"description":"Creates a Temu sandbox integration instance **without** going through the OAuth flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nTemu's sandbox has no OAuth — the merchant is issued a static long-lived access token through the developer portal. SKU.io reads that token (plus the sandbox `app_key` and `app_secret`) from env / Secrets Manager via the `temu.sandbox.*` config keys and persists it on the new instance at creation time. The instance is created with `environment = sandbox`, its API base URL pinned to `temu.sandbox.api_url`, and the access token serialised onto the `authenticator` column.\n\nAfter creation, the same initial sync jobs (warehouses, carriers, categories, products, orders) are dispatched as for the production OAuth flow.\n\n**Refuses to run on a production server** — even if the call somehow arrived there, the `HasIntegrationEnvironment` trait would coerce the runtime env to PRODUCTION and the saved sandbox row would be misleading.\n\n**Request body (TemuInitializeIntegrationData):**\n- `name` (string, required) — Display name for the sandbox instance. If another instance with this exact name already exists, ` (N+1)` is appended.\n- `integration_settings` (object, optional) — Free-form JSON persisted on the instance.\n- `environment` (string, optional) — Accepted but ignored — sandbox is forced.\n\n**Response:** A 201 Created with the newly-persisted `TemuIntegrationInstance` resource and a `message`.\n\n**Authentication:** Bearer token (Sanctum).\n\n**Throws:** `Exception` when called on a production server, or when `TEMU_SANDBOX_APP_KEY` / `TEMU_SANDBOX_APP_SECRET` / `TEMU_SANDBOX_ACCESS_TOKEN` are not configured.","body":{"mode":"raw","raw":"{\n  \"name\": \"Temu Sandbox\",\n  \"integration_settings\": {\n    \"inventory\": {\n      \"warehouses\": []\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/sandbox/initialize","host":["{{baseUrl}}"],"path":["api","temu","sandbox","initialize"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Temu sandbox integration created successfully\",\n  \"data\": {\n    \"id\": 18,\n    \"integration_name\": \"Temu\",\n    \"sales_channel_id\": 43,\n    \"store\": {\n      \"id\": 4,\n      \"name\": \"Temu Sandbox\"\n    },\n    \"name\": \"Temu Sandbox\",\n    \"integration_settings\": {\n      \"inventory\": {\n        \"warehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"has_warehouse_mappings\": false,\n    \"has_carrier_mappings\": false,\n    \"created_at\": \"2026-06-19T18:55:02.000000Z\",\n    \"updated_at\": \"2026-06-19T18:55:02.000000Z\"\n  }\n}"}]},{"name":"Reconnect Integration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/reconnect","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","reconnect"],"variable":[{"key":"integrationInstance","value":"17","description":"Temu integration instance ID."}]},"description":"Re-authorizes an existing `TemuIntegrationInstance` with a fresh OAuth access token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed when the original token has expired or been revoked. The frontend kicks off a normal OAuth flow (calls `/oauth/initialize` to get a state + authorization URL, sends the merchant to Temu, and the callback stores the authorization code under the same state). It then calls this endpoint to exchange that code for a new access token bound to the **existing** instance row — the row's environment, name, integration_settings, etc. are preserved.\n\nIn the typical browser-driven path the OAuth callback (`/api/temu/oauth/callback`) actually performs the reconnection itself when it detects existing instances and redirects with `isReconnect=true`. This endpoint exists for cases where the frontend wants to drive the reconnect explicitly.\n\n**Path parameters:**\n- `integrationInstance` (int, required) — The ID of the TemuIntegrationInstance to reconnect.\n\n**Request body (raw JSON):**\n- `state` (string, required) — The OAuth state from the just-completed reconnect authorization flow. Must already have a `code` stored in cache by the OAuth callback.\n\n**Response:** 200 OK with the refreshed `TemuIntegrationInstance` resource and a `message`.\n\n**Authentication:** Bearer token (Sanctum).\n\n**Throws:** `Exception` when `state` is missing, when the OAuth session has expired, has already been completed, or when Temu hasn't yet posted the authorization code for this state.","body":{"mode":"raw","raw":"{\n  \"state\": \"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/reconnect","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","reconnect"],"variable":[{"key":"integrationInstance","value":"17","description":"Temu integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Temu integration reconnected successfully\",\n  \"data\": {\n    \"id\": 17,\n    \"integration_name\": \"Temu\",\n    \"sales_channel_id\": 42,\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Acme US Storefront\"\n    },\n    \"name\": \"Acme US Storefront\",\n    \"integration_settings\": {\n      \"inventory\": {\n        \"warehouses\": []\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"has_warehouse_mappings\": true,\n    \"has_carrier_mappings\": true,\n    \"created_at\": \"2026-06-10T08:00:00.000000Z\",\n    \"updated_at\": \"2026-06-19T19:02:48.000000Z\"\n  }\n}"}]},{"name":"Test Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","test-connection"],"variable":[{"key":"integrationInstance","value":"17","description":"Temu integration instance ID."}]},"description":"Verifies that the stored Temu access token for a given integration instance is still valid by calling Temu's `getWarehouses` endpoint (the cheapest read with no required parameters).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUsed by the Integration Settings page to render a green/red status pill, and by the new-instance / reconnect flow to confirm the instance can actually talk to Temu before dispatching the initial sync jobs.\n\nThis endpoint **always returns HTTP 200** — connectivity failures are reported in the `data.success` flag, not via HTTP status.\n\n**Path parameters:**\n- `integrationInstance` (int, required) — The ID of the TemuIntegrationInstance to test.\n\n**Response data:**\n- `success` (bool) — `true` when the token is valid and Temu responded; `false` otherwise.\n- `message` (string) — Human-readable description of the outcome (e.g. `Connection successful`, `Integration instance is not authenticated`, `Connection test failed: <upstream-error>`).\n\n**Authentication:** Bearer token (Sanctum)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","test-connection"],"variable":[{"key":"integrationInstance","value":"17","description":"Temu integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Connection successful\"\n  }\n}"}]},{"name":"Get Authorization URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Builds and returns the Temu seller-consent URL for this integration instance. Direct the merchant to this URL to authorize (or re-authorize) the connection; after they approve access, Temu redirects back to the platform's OAuth callback which completes the token exchange.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe URL is assembled from the instance's configured environment (production or sandbox), the registered application key, the platform callback address, and a state value that identifies this instance. This endpoint is read-only — it makes no calls to Temu and changes no data.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/get-authorization-url","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","get-authorization-url"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"https://seller.kuajingmaihuo.com/open/auth?appKey=example-app-key&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fapi%2Ftemu%2Foauth%2Fcallback&state=acme_5\",\n  \"status\": \"success\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders?page=1&per_page=15&sort=-id&filter[search]=PO-1234&filter[archived]=active&filter[parentOrderStatus]=shipped&filter[linked]=true","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with `-` for desc. Allowed: id, parentOrderSn, parentOrderStatus, shippingMethod, expectShipLatestTime, latestDeliveryTime, parentOrderTime, total, currency, created_at, updated_at. Default: -id.","disabled":true},{"key":"filter[search]","value":"PO-1234","description":"Free-text search across parentOrderSn, Temu order id, and linked SKU sales_order_number.","disabled":true},{"key":"filter[archived]","value":"active","description":"Archived state. Accepts: 'all'|'2' (both), 'only'|'archived'|'1'|true (archived only), '' / 'active' / '0' (default — active only).","disabled":true},{"key":"filter[parentOrderStatus]","value":"shipped","description":"Exact match on Temu parent order status enum (e.g. unshipped, shipped, delivered, cancelled, partially_shipped, refunding, refunded).","disabled":true},{"key":"filter[linked]","value":"true","description":"true = orders that have a linked SKU sales order, false = orders without one.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Paginated list of Temu orders for an integration instance, powered by Spatie QueryBuilder.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupported filters:\n- `filter[search]` — searches parentOrderSn, Temu id, and linked SKU sales_order_number.\n- `filter[archived]` — 'active' (default), 'only'/'archived'/'1'/true, or 'all'/'2'.\n- `filter[linked]` — true/false; presence of a linked SKU sales order.\n- `filter[parentOrderStatus]` — exact match on the legacy dropdown enum value.\n- AdvancedFilterBuilder operators on: parentOrderSn (text), currency (text), parentOrderStatus (text), id (numeric), total (numeric), parentOrderTime (date), expectShipLatestTime (date), latestDeliveryTime (date), created_at (date), updated_at (date). Operators are appended as `.eq`, `.contains`, `.gte`, `.between`, etc.\n\nSupported sorts: id, parentOrderSn, parentOrderStatus, shippingMethod, expectShipLatestTime, latestDeliveryTime, parentOrderTime, total, currency, created_at, updated_at. Default sort is `-id`.\n\nEager-loads orderItems, integrationInstance, salesOrder.salesOrderFulfillments.\n\n**Response field:** `unmapped_line_item_count` — number of line items whose Temu product exists but has no internal SKU.io Product linked (mapping incomplete). Excludes orphan goodsIds with no TemuProduct row. Only present when orderItems are loaded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders?page=1&per_page=15&sort=-id&filter[search]=PO-1234&filter[archived]=active&filter[parentOrderStatus]=shipped&filter[linked]=true","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort field. Prefix with `-` for desc. Allowed: id, parentOrderSn, parentOrderStatus, shippingMethod, expectShipLatestTime, latestDeliveryTime, parentOrderTime, total, currency, created_at, updated_at. Default: -id.","disabled":true},{"key":"filter[search]","value":"PO-1234","description":"Free-text search across parentOrderSn, Temu order id, and linked SKU sales_order_number.","disabled":true},{"key":"filter[archived]","value":"active","description":"Archived state. Accepts: 'all'|'2' (both), 'only'|'archived'|'1'|true (archived only), '' / 'active' / '0' (default — active only).","disabled":true},{"key":"filter[parentOrderStatus]","value":"shipped","description":"Exact match on Temu parent order status enum (e.g. unshipped, shipped, delivered, cancelled, partially_shipped, refunding, refunded).","disabled":true},{"key":"filter[linked]","value":"true","description":"true = orders that have a linked SKU sales order, false = orders without one.","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 1,\n      \"parentOrderSn\": \"PO-1024-AB\",\n      \"parentOrderStatus\": \"shipped\",\n      \"shippingMethod\": \"Standard\",\n      \"customerName\": \"Jane Doe\",\n      \"orderPaymentType\": \"prepaid\",\n      \"expectShipLatestTime\": \"2025-03-04T23:59:59+00:00\",\n      \"latestDeliveryTime\": \"2025-03-10T23:59:59+00:00\",\n      \"parentOrderTime\": \"2025-03-01T12:34:56+00:00\",\n      \"total\": \"89.97\",\n      \"currency\": \"USD\",\n      \"status\": \"shipped\",\n      \"error_log\": null,\n      \"json_object\": {\n        \"parentOrderMap\": {\n          \"parentOrderSn\": \"PO-1024-AB\",\n          \"parentOrderStatus\": 2\n        }\n      },\n      \"sku_sales_order\": {\n        \"id\": 5501,\n        \"order_number\": \"SO-5501\",\n        \"order_status\": \"open\",\n        \"fulfillment_status\": \"shipped\",\n        \"payment_status\": \"paid\",\n        \"total_fulfillments_count\": 1,\n        \"submitted_fulfillments_count\": 1,\n        \"available_fulfillments_count\": 0\n      },\n      \"unmapped_line_item_count\": 1,\n      \"archived_at\": null,\n      \"created_at\": \"2025-03-01T12:35:10+00:00\",\n      \"updated_at\": \"2025-03-04T08:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 7,\n  \"per_page\": 15,\n  \"total\": 98,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Fetch a single Temu order with full nested detail. Eager-loads orderItems.product.productListing.product, orderItems.product.productListing.subscriptionOffering, and salesOrder.salesOrderFulfillments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIncludes a `line_item_products` map keyed by Temu `goodsId` — each value is a Temu product object (channel product list view shape) covering the product mapping and SKU.io linkage. Use this map to look up which SKU.io product/listing each line item resolves to without making a second request.\n\n**Response field:** `unmapped_line_item_count` — number of line items whose Temu product exists but has no internal SKU.io Product linked (mapping incomplete). Excludes orphan goodsIds with no TemuProduct row. Only present when orderItems are loaded."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"integration_instance_id\": 1,\n    \"parentOrderSn\": \"PO-1024-AB\",\n    \"parentOrderStatus\": \"shipped\",\n    \"shippingMethod\": \"Standard\",\n    \"customerName\": \"Jane Doe\",\n    \"orderPaymentType\": \"prepaid\",\n    \"expectShipLatestTime\": \"2025-03-04T23:59:59+00:00\",\n    \"latestDeliveryTime\": \"2025-03-10T23:59:59+00:00\",\n    \"parentOrderTime\": \"2025-03-01T12:34:56+00:00\",\n    \"total\": \"89.97\",\n    \"currency\": \"USD\",\n    \"status\": \"shipped\",\n    \"error_log\": null,\n    \"json_object\": {\n      \"parentOrderMap\": {\n        \"parentOrderSn\": \"PO-1024-AB\",\n        \"parentOrderStatus\": 2,\n        \"customerName\": \"Jane Doe\"\n      },\n      \"orderList\": [\n        {\n          \"goodsId\": \"401234567890\",\n          \"quantity\": 2,\n          \"goodsName\": \"Wireless Earbuds\"\n        },\n        {\n          \"goodsId\": \"401234567891\",\n          \"quantity\": 1,\n          \"goodsName\": \"Charging Cable\"\n        }\n      ]\n    },\n    \"sku_sales_order\": {\n      \"id\": 5501,\n      \"order_number\": \"SO-5501\",\n      \"order_status\": \"open\",\n      \"fulfillment_status\": \"shipped\",\n      \"payment_status\": \"paid\",\n      \"total_fulfillments_count\": 1,\n      \"submitted_fulfillments_count\": 1,\n      \"available_fulfillments_count\": 0\n    },\n    \"line_item_products\": {\n      \"401234567890\": {\n        \"id\": 7012,\n        \"integration_instance_id\": 1,\n        \"product_listing_id\": 3301,\n        \"product\": {\n          \"id\": 4501,\n          \"name\": \"Wireless Earbuds\",\n          \"sku\": \"WE-001\",\n          \"listing_id\": 3301,\n          \"default_financial_line_type_id\": 12,\n          \"default_financial_line_type\": {\n            \"id\": 12,\n            \"name\": \"Product Sales\",\n            \"classification\": \"income\"\n          }\n        },\n        \"subscription_offering\": null,\n        \"mapped_at\": \"2025-02-20T10:15:00+00:00\",\n        \"mapped_sku\": \"WE-001\",\n        \"category_name\": \"Audio\",\n        \"json_object\": {\n          \"goodsId\": \"401234567890\",\n          \"productName\": \"Wireless Earbuds\",\n          \"skcId\": \"55512345\"\n        },\n        \"created_at\": \"2025-02-15T09:00:00+00:00\",\n        \"updated_at\": \"2025-02-20T10:15:00+00:00\"\n      },\n      \"401234567891\": {\n        \"id\": 7013,\n        \"integration_instance_id\": 1,\n        \"product_listing_id\": null,\n        \"product\": null,\n        \"subscription_offering\": null,\n        \"mapped_at\": null,\n        \"mapped_sku\": null,\n        \"category_name\": \"Accessories\",\n        \"json_object\": {\n          \"goodsId\": \"401234567891\",\n          \"productName\": \"Charging Cable\",\n          \"skcId\": \"55512346\"\n        },\n        \"created_at\": \"2025-02-15T09:00:00+00:00\",\n        \"updated_at\": \"2025-02-15T09:00:00+00:00\"\n      }\n    },\n    \"unmapped_line_item_count\": 1,\n    \"archived_at\": null,\n    \"created_at\": \"2025-03-01T12:35:10+00:00\",\n    \"updated_at\": \"2025-03-04T08:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Permanently delete a Temu order. Verifies the order belongs to the supplied integration instance (returns 403 if not). Does not remove the Temu order on Temu's side — only deletes the local cached record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order deleted successfully\"\n}"}]},{"name":"Delete Linked SKU Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Delete the linked SKU.io sales order while keeping the Temu order. Returns 404 if no SKU order is linked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptional body field `archive_order` (boolean, default false): when true, also archives the Temu order after the SKU order is deleted, preventing the next refresh from immediately re-creating it."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully and Temu order archived\",\n  \"archived_order\": true\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Returns aggregate stats used by the 'Refresh from Temu' modal: total order count, count with/without a linked SKU sales order, and the latest known order (parentOrderSn, parentOrderTime, parentOrderStatus). Used by the UI to default the date range and surface sync coverage.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"PO-1024-AB\",\n    \"latest_order_date\": \"2025-03-01T12:34:56+00:00\",\n    \"latest_order_status\": \"shipped\",\n    \"total_orders\": 98,\n    \"with_sku_order\": 81,\n    \"without_sku_order\": 17\n  }\n}"}]},{"name":"Refresh Orders (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queue a tracked background job that pulls orders from Temu. Returns a `tracked_job_log_id` for the tracked job log endpoints to subscribe to.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional):\n- `mode` — one of `since_latest` (default), `from_start_date`, `date_range`, `all`.\n- `dateFrom`, `dateTo` — required when `mode=date_range`; ISO-8601 dates. `mode=from_start_date` only needs `dateFrom` (end is now). `mode=all` walks from the integration's `start_date` (or 2022-01-01) to now. `mode=since_latest` leaves the range empty so the job auto-resumes from the latest parentOrderTime + 1s.\n- `latestDate` — currently accepted for compatibility but not used by the controller.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"dateFrom\": \"2025-03-01\",\n  \"dateTo\": \"2025-03-15\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order refresh job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 8821\n  }\n}"}]},{"name":"Create SKU Orders (Bulk)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Dispatch a tracked background job that converts the selected Temu orders into SKU.io sales orders. Returns a `tracked_job_log_id` immediately so the caller can close the modal and watch progress via the global tray.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody (CreateSkuOrderFromSalesChannelData):\n- `ids` — array of Temu order ids to convert.\n- `create_all_orders` — boolean; when true, ignore `ids` and create SKU orders for every unlinked Temu order in the instance.\n- `filters` — optional filter payload. When present, the controller resolves it to a concrete list of ids via `getIdsFromFilters()` before dispatching.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — create for the given channel order IDs\n- {\"create_all_orders\": true} — create for all eligible orders on the integration instance\n- {\"create_all_orders\": true, \"filters\": {...}} — create only for orders matching the filters. The filters object accepts the same filter keys as the corresponding orders list endpoint (bare column keys, e.g. {\"order_status\": \"pending\"}) and/or a \"filter_groups\" tree (base64-encoded JSON, same format as the list endpoint). When filters match no orders, nothing is created and the response message is \"No orders to create\".\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1024,\n    1025,\n    1026\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Creating SKU orders in the background — track progress in the job tray.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8822\n  }\n}"}]},{"name":"Create Products From Order Items","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integration_instance}/orders/create-products-from-items","host":["{{baseUrl}}"],"path":["api","temu",":integration_instance","orders","create-products-from-items"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Backfill TemuProduct records for any TemuOrderItem rows that reference a `goodsId` not yet present as a product. Useful when the orders endpoint ran ahead of the products sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Looks up orphaned goodsIds, then creates stub product rows."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integration_instance}/orders/create-products-from-items","host":["{{baseUrl}}"],"path":["api","temu",":integration_instance","orders","create-products-from-items"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Created 7 products from order items.\"\n}"}]},{"name":"Refresh Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Queues a background job that pulls the latest orders from Temu and upserts them into the local order list. The job runs on a serialized queue so overlapping refreshes for the same instance cannot race. The sync window starts just after the most recent stored order (or the instance's configured start date when no orders exist yet).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAfter orders are saved, linked sales orders for the fetched page are also brought up to date. The response returns immediately; there is no job id to poll on this endpoint.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, orders will be refreshed shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Fetches one order from Temu by its parent order number, saves (or updates) it locally, and returns the stored order. Use this to re-sync a single order on demand instead of running a full refresh.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `uniqueId` (string, required) — the Temu parent order number (`parentOrderSn`), e.g. `PO-211-01823450917341234`.\n\nReturns 404 when Temu has no order with that number.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"PO-211-01823450917341234\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","refresh-order"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 5,\n    \"parentOrderSn\": \"PO-211-01823450917341234\",\n    \"parentOrderStatus\": 2,\n    \"shippingMethod\": \"Standard\",\n    \"customerName\": \"John Smith\",\n    \"orderPaymentType\": \"PREPAID\",\n    \"expectShipLatestTime\": \"2026-07-08T00:00:00.000000Z\",\n    \"latestDeliveryTime\": \"2026-07-15T00:00:00.000000Z\",\n    \"parentOrderTime\": \"2026-07-04T18:22:31.000000Z\",\n    \"total\": \"38.97\",\n    \"currency\": \"USD\",\n    \"status\": null,\n    \"error_log\": null,\n    \"json_object\": {\n      \"parentOrderSn\": \"PO-211-01823450917341234\",\n      \"parentOrderStatus\": 2,\n      \"regionId\": 211\n    },\n    \"archived_at\": null,\n    \"created_at\": \"2026-07-04T18:30:02.000000Z\",\n    \"updated_at\": \"2026-07-06T09:12:44.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Update SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Re-applies the latest stored Temu order data onto the linked SKU sales orders — statuses, cancellations and fulfillment-relevant changes are translated into update actions and processed per order. Orders without a linked sales order are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `update_all_orders` (boolean, required) — when `true`, processes every eligible order for the instance.\n- `ids` (array of integers, optional) — specific Temu order ids to process.\n- `filters` (string, optional) — a serialized filter expression; when provided it is resolved to a set of order ids before processing.\n- `use_jobs` (boolean, default `true`) — accepted for cross-channel compatibility; Temu processes the update synchronously within the request.\n\nProcessing happens in chunks, so very large selections can take a while to respond.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"update_all_orders\": false,\n  \"ids\": [\n    101,\n    102\n  ],\n  \"use_jobs\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/update-sku-orders","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","update-sku-orders"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Sku.io sales orders successfully updated\",\n  \"status\": \"success\"\n}"}]},{"name":"Archive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Archive a single Temu order. Returns 403 if the order does not belong to the integration instance. The `archived` flag in the response indicates whether the call actually changed state (false means it was already archived).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Unarchive a single Temu order. Returns 403 if the order does not belong to the integration instance. The `unarchived` flag is false when the order was already active.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Archive multiple orders in one call. Iterates the matched rows in chunks of 100.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `ids` — array of integer order ids (required unless `apply_to_all` is true).\n- `apply_to_all` — boolean; when true, archives every currently non-archived order in the instance (ids are ignored).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1024,\n    1025,\n    1026\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Unarchive multiple orders in one call. Iterates the matched rows in chunks of 100.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `ids` — array of integer order ids (required unless `apply_to_all` is true).\n- `apply_to_all` — boolean; when true, unarchives every currently archived order in the instance (ids are ignored).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1024,\n    1025,\n    1026\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders unarchived successfully\",\n  \"unarchived_count\": 3\n}"}]},{"name":"Get Raw Order (from Temu API)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Live-fetch the raw Temu order payload by `parentOrderSn` directly from Temu's API (bypasses the local cache). Returns 403 if the order does not belong to the integration instance, or 500 with the underlying error message if Temu's API call fails.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","raw"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"parentOrderMap\": {\n      \"parentOrderSn\": \"PO-1024-AB\",\n      \"parentOrderStatus\": 2,\n      \"parentOrderTime\": 1740830096,\n      \"customerName\": \"Jane Doe\",\n      \"shippingMethod\": \"Standard\",\n      \"orderAmount\": 8997,\n      \"currency\": \"USD\"\n    },\n    \"orderList\": [\n      {\n        \"orderSn\": \"O-1024-1\",\n        \"goodsId\": \"401234567890\",\n        \"skcId\": \"55512345\",\n        \"quantity\": 2,\n        \"goodsName\": \"Wireless Earbuds\"\n      }\n    ]\n  }\n}"}]},{"name":"Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/activity-log?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Paginated activity log entries for this Temu order, sourced from Spatie ActivityLog.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/orders/{order}/activity-log?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","orders",":order","activity-log"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9301,\n      \"description\": \"Order created from Temu\",\n      \"event\": \"created\",\n      \"causer\": {\n        \"id\": 12,\n        \"name\": \"Sync Worker\"\n      },\n      \"properties\": {\n        \"parentOrderSn\": \"PO-1024-AB\"\n      },\n      \"created_at\": \"2025-03-01T12:35:10+00:00\"\n    },\n    {\n      \"id\": 9302,\n      \"description\": \"SKU sales order linked\",\n      \"event\": \"updated\",\n      \"causer\": {\n        \"id\": 3,\n        \"name\": \"Jane Doe\"\n      },\n      \"properties\": {\n        \"sales_order_id\": 5501\n      },\n      \"created_at\": \"2025-03-01T12:40:22+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products?page=1&per_page=15&sort=-id","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"sort","value":"-id","description":"Allowed sorts: id, skuId, goodsId, goodsName, skuStatus, catType, created_at, updated_at. Prefix with - for descending.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of Temu products for an integration instance. Powered by Spatie QueryBuilder with grouped advanced filters.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products?page=1&per_page=15&sort=-id","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"sort","value":"-id","description":"Allowed sorts: id, skuId, goodsId, goodsName, skuStatus, catType, created_at, updated_at. Prefix with - for descending.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"skuId\": \"172800123456789\",\n      \"goodsId\": \"60112233445566\",\n      \"goodsName\": \"Wireless Earbuds Pro - Black\",\n      \"category_name\": \"Electronics > Audio > Earbuds\",\n      \"integration_instance_id\": 12,\n      \"product_listing_id\": 553,\n      \"product\": {\n        \"id\": 91,\n        \"name\": \"Earbuds Pro\",\n        \"sku\": \"SKU-EARBUDS-PRO\",\n        \"listing_id\": 553,\n        \"default_financial_line_type_id\": 4,\n        \"default_financial_line_type\": {\n          \"id\": 4,\n          \"name\": \"Product Sales\",\n          \"classification\": \"income\"\n        }\n      },\n      \"subscription_offering\": null,\n      \"mapped_at\": \"2026-05-12T14:21:08.000000Z\",\n      \"mapped_sku\": \"SKU-EARBUDS-PRO\",\n      \"json_object\": {\n        \"goodsId\": \"60112233445566\",\n        \"goodsName\": \"Wireless Earbuds Pro - Black\",\n        \"outGoodsSn\": \"SKU-EARBUDS-PRO\",\n        \"price\": 39.99,\n        \"quantity\": 120,\n        \"status4VO\": \"ON_SALE\",\n        \"retailPrice\": {\n          \"amount\": 39.99,\n          \"currency\": \"USD\"\n        }\n      },\n      \"created_at\": \"2026-05-10T08:11:45.000000Z\",\n      \"updated_at\": \"2026-06-18T19:44:02.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 7,\n  \"per_page\": 15,\n  \"total\": 102,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"https://app.sku.io/api/temu/12/products?page=1\",\n  \"last_page_url\": \"https://app.sku.io/api/temu/12/products?page=7\",\n  \"next_page_url\": \"https://app.sku.io/api/temu/12/products?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"https://app.sku.io/api/temu/12/products\",\n  \"links\": []\n}"}]},{"name":"Show Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Fetch a single Temu product with its mapping, integration instance, and full json_object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"skuId\": \"172800123456789\",\n    \"goodsId\": \"60112233445566\",\n    \"goodsName\": \"Wireless Earbuds Pro - Black\",\n    \"category_name\": \"Electronics > Audio > Earbuds\",\n    \"integration_instance_id\": 12,\n    \"product_listing_id\": 553,\n    \"product\": {\n      \"id\": 91,\n      \"name\": \"Earbuds Pro\",\n      \"sku\": \"SKU-EARBUDS-PRO\",\n      \"listing_id\": 553\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-05-12T14:21:08.000000Z\",\n    \"mapped_sku\": \"SKU-EARBUDS-PRO\",\n    \"json_object\": {\n      \"goodsId\": \"60112233445566\",\n      \"goodsName\": \"Wireless Earbuds Pro - Black\",\n      \"outGoodsSn\": \"SKU-EARBUDS-PRO\",\n      \"price\": 39.99,\n      \"quantity\": 120,\n      \"status4VO\": \"ON_SALE\"\n    },\n    \"created_at\": \"2026-05-10T08:11:45.000000Z\",\n    \"updated_at\": \"2026-06-18T19:44:02.000000Z\"\n  }\n}"}]},{"name":"Export Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/export","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","export"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Downloads every imported Temu product listing for the integration instance as a spreadsheet file (newest first), including mapping details for listings linked to internal products. Nested values such as the raw listing payload are serialized to JSON strings within their cells.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe export always covers all products for the instance — list filters are not applied. Requesting an export when the instance has no products returns an error.\n\nAuthentication: Requires Bearer token."}},{"name":"Check Archiveable Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Pre-validates a set of Temu products for archiving without changing anything. For each product the response says whether it can be archived and, if not, why. A product cannot be archived while it appears on imported Temu orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n\n- `ids` (array of integers, required unless `mode` is used) — product ids belonging to this integration instance.\n- `mode` (string) — set to `all` to check every product for the instance.\n\nResponse items contain `id`, `archiveable` (boolean) and `reason` (`false` when archiveable, otherwise a comma-separated string of reasons).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/archiveable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","archiveable"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"archiveable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 13,\n      \"archiveable\": false,\n      \"reason\": \"Sales Channel Product has Sales Channel Orders\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Check Deleteable Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Pre-validates a set of Temu products for deletion without changing anything. For each product the response says whether it can be deleted; Temu products currently have no delete restrictions, so every requested product is reported as deleteable.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n\n- `ids` (array of integers, required unless `mode` is used) — product ids belonging to this integration instance.\n- `mode` (string) — set to `all` to check every product for the instance.\n\nResponse items contain `id`, `deleteable` (boolean) and `reason` (`false` when deleteable).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/deleteable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","deleteable"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12,\n      \"deleteable\": true,\n      \"reason\": false\n    },\n    {\n      \"id\": 13,\n      \"deleteable\": true,\n      \"reason\": false\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Archive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Archives the selected Temu products, hiding them from the default product list. Products that appear on imported Temu orders are silently skipped — use the archiveable check endpoint first to see which products qualify.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n\n- `ids` (array of integers, required unless `mode` is used) — product ids belonging to this integration instance.\n- `mode` (string) — set to `all` to archive every eligible product for the instance.\n\nAuthentication: Requires Bearer token.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/archive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","archive"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products archived successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Unarchive Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Restores previously archived Temu products so they appear in the default product list again.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n\n- `ids` (array of integers, required unless `mode` is used) — product ids belonging to this integration instance.\n- `mode` (string) — set to `all` to unarchive every product for the instance.\n\nAuthentication: Requires Bearer token.\n\nBulk selection contract:\n- {\"ids\": [1, 2]} — act on the given channel product IDs\n- {\"mode\": \"all\"} — act on all products for the integration instance\n- {\"apply_to_all\": true, \"filters\": {...}} — act only on products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). With apply_to_all and no filters, all products for the instance are targeted.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/unarchive","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","unarchive"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products unarchived successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Delete Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Permanently deletes the selected Temu products from the local catalog. Any product-listing mappings tied to those products are removed first, so linked internal products lose their Temu listing association. The listings on Temu itself are not affected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body — one of:\n\n- `ids` (array of integers, required unless `mode` is used) — product ids belonging to this integration instance.\n- `mode` (string) — set to `all` to delete every product for the instance.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    14\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/delete","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","delete"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products deleted successfully.\",\n  \"status\": \"success\"\n}"}]},{"name":"Refresh Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Dispatches a tracked background job to pull products from Temu. Returns a tracked_job_log_id the UI uses to surface progress via the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPayload fields (all optional):\n- mode: one of since_latest | full_catalog | date_range\n- dateFrom / dateTo: ISO date strings used with date_range\n- latestDate: ISO date used with since_latest","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"dateFrom\": null,\n  \"dateTo\": null,\n  \"latestDate\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product refresh job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  }\n}"}]},{"name":"Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns totals + most-recently-updated product info for the Refresh-from-Temu modal header. Counts exclude archived rows.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Wireless Earbuds Pro - Black\",\n    \"latest_product_date\": \"2026-06-18T19:44:02.000000Z\",\n    \"total_products\": 102,\n    \"mapped_products\": 67,\n    \"unmapped_products\": 35,\n    \"last_synced_at\": \"2026-06-18T19:44:02.000000Z\"\n  }\n}"}]},{"name":"Get Raw Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Calls Temu's bg.local.goods.detail.query directly and returns the raw payload for the on-demand viewer. 403 if the product does not belong to the given integration instance; 500 if the upstream call fails.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"goodsId\": \"60112233445566\",\n      \"goodsName\": \"Wireless Earbuds Pro - Black\",\n      \"outGoodsSn\": \"SKU-EARBUDS-PRO\",\n      \"catId\": 1180,\n      \"catName\": \"Earbuds\",\n      \"status4VO\": \"ON_SALE\",\n      \"skuInfoList\": [\n        {\n          \"skuId\": \"172800123456789\",\n          \"price\": 39.99,\n          \"quantity\": 120\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Refresh Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Queues a background job that pulls the product catalog from Temu and upserts the listings locally. The job runs on a serialized queue so overlapping refreshes for the same instance cannot race. Depending on the instance's auto-link and auto-create settings, newly imported listings may be linked to existing internal products by SKU or have internal products created for them automatically.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response returns immediately; there is no job id to poll on this endpoint.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, products will be refreshed shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Refresh Single Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."},{"key":"product","value":"12","description":"The product ID."}]},"description":"Fetches one product directly from Temu's API, persists the updated data, and returns the refreshed listing — synchronously, without queuing a catalog-wide refresh.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nError cases:\n\n- 403 when the product does not belong to this integration instance.\n- 404 when Temu returns no data for the product.\n- 500 when the Temu API call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","refresh"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."},{"key":"product","value":"12","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 5,\n    \"product_listing_id\": 88,\n    \"product\": {\n      \"id\": 341,\n      \"name\": \"Black Cotton T-Shirt\",\n      \"sku\": \"TSHIRT-BLK-L\",\n      \"default_financial_line_type_id\": 2,\n      \"default_financial_line_type\": {\n        \"id\": 2,\n        \"name\": \"Product Sales\",\n        \"classification\": \"revenue\"\n      },\n      \"listing_id\": 88\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-05-14T10:02:31.000000Z\",\n    \"mapped_sku\": \"TSHIRT-BLK-L\",\n    \"json_object\": {\n      \"goodsId\": \"601099512340411\",\n      \"goodsName\": \"Black Cotton T-Shirt\",\n      \"skuId\": \"17592186044417\",\n      \"outGoodsSn\": \"TSHIRT-BLK-L\",\n      \"price\": \"12.99\",\n      \"quantity\": 240\n    },\n    \"updated_at\": \"2026-07-06T09:41:12.000000Z\",\n    \"created_at\": \"2026-04-30T07:18:44.000000Z\",\n    \"category_name\": \"Apparel\",\n    \"skuId\": \"17592186044417\",\n    \"goodsId\": \"601099512340411\",\n    \"goodsName\": \"Black Cotton T-Shirt\",\n    \"thumbUrl\": \"https://img.kwcdn.com/product/thumb/601099512340411.jpg\",\n    \"skuStatus\": \"ACTIVE\",\n    \"catType\": \"0\"\n  },\n  \"message\": \"Product refreshed from Temu\"\n}"}]},{"name":"Smart Match","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Find SKU product matches for a Temu product. Tries exact SKU (outGoodsSn first, then skuId) and fuzzy goodsName matches. Empty body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 91,\n      \"sku\": \"SKU-EARBUDS-PRO\",\n      \"name\": \"Earbuds Pro\",\n      \"barcode\": 123456789012,\n      \"price\": 39.99,\n      \"type\": \"simple\",\n      \"match_type\": \"sku\"\n    },\n    \"barcode_match\": null,\n    \"similar_matches\": [\n      {\n        \"id\": 134,\n        \"sku\": \"SKU-EARBUDS-LITE\",\n        \"name\": \"Earbuds Lite\",\n        \"barcode\": null,\n        \"price\": 19.99,\n        \"type\": \"simple\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Map Product to SKU Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Map a single Temu product to either a SKU product (product_id) OR a subscription offering (subscription_offering_id). Exactly one of the two is required.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPayload:\n- product_id (integer, required_without subscription_offering_id) — must exist in products.id\n- subscription_offering_id (integer, required_without product_id) — must exist in subscription_offerings.id\n\nCreates or updates the underlying product_listing and queues a job to re-map any open sales order lines.","body":{"mode":"raw","raw":"{\n  \"product_id\": 91\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"skuId\": \"172800123456789\",\n    \"goodsId\": \"60112233445566\",\n    \"goodsName\": \"Wireless Earbuds Pro - Black\",\n    \"integration_instance_id\": 12,\n    \"product_listing_id\": 553,\n    \"product\": {\n      \"id\": 91,\n      \"name\": \"Earbuds Pro\",\n      \"sku\": \"SKU-EARBUDS-PRO\",\n      \"listing_id\": 553\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-06-19T10:15:42.000000Z\",\n    \"mapped_sku\": \"SKU-EARBUDS-PRO\"\n  },\n  \"message\": \"Product mapped successfully.\"\n}"}]},{"name":"Unmap Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Removes the product_listing linking this Temu product to a SKU product/offering. Returns 422 if the product has no current mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"skuId\": \"172800123456789\",\n    \"goodsId\": \"60112233445566\",\n    \"goodsName\": \"Wireless Earbuds Pro - Black\",\n    \"integration_instance_id\": 12,\n    \"product_listing_id\": null,\n    \"product\": null,\n    \"subscription_offering\": null,\n    \"mapped_at\": null,\n    \"mapped_sku\": null\n  },\n  \"message\": \"Product unmapped successfully.\"\n}"}]},{"name":"Create SKU Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Create a new SKU product from a Temu product and immediately link it via product_listing.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf an existing SKU product with a matching sku (outGoodsSn or skuId) is found, the response sets `linked_existing: true` and links to that record instead of creating a duplicate.\n\nReturns 422 if the Temu product is already mapped (caller must unmap first).\n\nPayload (optional, used by the create-from-Temu form):\n- field_mappings (object) — map of SKU product field => Temu source key (persisted via DataImportMapping when sent in bulk via createSkuProducts).\n- save_as_default (boolean) — persist the provided field_mappings as the integration default.","body":{"mode":"raw","raw":"{\n  \"field_mappings\": {\n    \"sku\": \"outGoodsSn\",\n    \"name\": \"goodsName\",\n    \"price\": \"price\",\n    \"barcode\": \"upc\"\n  },\n  \"save_as_default\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"skuId\": \"172800123456789\",\n    \"goodsId\": \"60112233445566\",\n    \"goodsName\": \"Wireless Earbuds Pro - Black\",\n    \"integration_instance_id\": 12,\n    \"product_listing_id\": 554,\n    \"product\": {\n      \"id\": 92,\n      \"name\": \"Wireless Earbuds Pro - Black\",\n      \"sku\": \"SKU-EARBUDS-PRO\",\n      \"listing_id\": 554\n    },\n    \"subscription_offering\": null,\n    \"mapped_at\": \"2026-06-19T10:18:11.000000Z\",\n    \"mapped_sku\": \"SKU-EARBUDS-PRO\"\n  },\n  \"linked_existing\": false,\n  \"message\": \"SKU product created and mapped successfully.\"\n}"}]},{"name":"Bulk Map Products","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Maps Temu listings to internal products by SKU in bulk. Each mapping entry links one Temu listing (identified by its Temu goods id) to the internal product whose SKU matches `mapped_sku`. After mapping, any imported order lines that were previously unmatched are re-linked to the newly mapped products in the background.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `mapping` (array, required, min 1) — each entry:\n  - `sales_channel_listing_id` (string, required) — the Temu goods id of the listing.\n  - `mapped_sku` (string or null, required) — SKU of the internal product to map to. Passing `null` (or an empty string) together with an existing `product_listing_id` removes that mapping.\n  - `product_listing_id` (integer or null, optional) — id of an existing listing mapping, used when updating or removing a mapping.\n  - `subscription_offering_id` (integer or null, optional) — map the listing to a subscription offering instead of a product.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mapping\": [\n    {\n      \"sales_channel_listing_id\": \"601099512340411\",\n      \"mapped_sku\": \"TSHIRT-BLK-L\",\n      \"product_listing_id\": null,\n      \"subscription_offering_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","map"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": \"Successfully mapped sales channel products to sku products\",\n  \"status\": \"success\"\n}"}]},{"name":"Bulk Create SKU Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Creates internal SKU products from Temu listings and links them, running as a queued background job. If a listing's candidate SKU already exists internally, the listing is linked to the existing product instead of creating a duplicate. Field mappings configured for the instance control how listing fields populate the new products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `create_all_products` (boolean, required) — when `true`, processes every listing for the instance.\n- `ids` (array of integers) — specific Temu product ids; required when `create_all_products` is `false` and no `filters` are supplied.\n- `filters` (string, optional) — serialized filter expression, resolved to a set of ids before the job is dispatched.\n- `mappings` (array, optional) — field mappings to persist before creation; each entry has `listing_field` (string), `sku_field` (string) and `parsers` (array of `{rule, args}` transforms).\n- `initial_mapping` (boolean, default `false`).\n\nThe response returns immediately with a `tracked_job_log_id` that can be used to follow the job's progress.\n\nAuthentication: Requires Bearer token.\n\nBulk selection contract:\n- {\"create_all_products\": false, \"ids\": [1, 2]} — create for the given channel product IDs\n- {\"create_all_products\": true} — create for all unmapped products on the integration instance\n- {\"create_all_products\": true, \"filters\": {...}} — create only for products matching the filters. The filters object accepts the same filter keys as the corresponding products list endpoint (bare column keys) and/or a \"filter_groups\" tree (base64-encoded JSON). When filters match no products, nothing is created and the response message is \"No products to create\".\n- create_all_products is required; ids is required when create_all_products is false and no filters are sent.\n- Legacy {\"conjunction\", \"filterSet\"} filter payloads are rejected with 422.","body":{"mode":"raw","raw":"{\n  \"create_all_products\": false,\n  \"ids\": [\n    12,\n    13\n  ],\n  \"initial_mapping\": false,\n  \"mappings\": [\n    {\n      \"listing_field\": \"goodsName\",\n      \"sku_field\": \"item_name\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/create-sku-products","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","create-sku-products"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Creating SKU products in the background.\",\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Import Product Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Imports listing-to-product mappings from a previously uploaded CSV file, running as a queued background job on a serialized queue. The CSV must contain a column with the Temu goods id (the listing's unique field) and a `mapped_sku` column identifying the internal product each listing maps to.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `original_name` (string, required) — the file name as originally uploaded.\n- `stored_name` (string, required) — the server-side stored file name returned by the file upload endpoint.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"original_name\": \"temu-mappings.csv\",\n  \"stored_name\": \"01J8ZK3W9GVXPTF2ab.csv\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/import-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","import-mappings"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to queue, mappings will be imported shortly.\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Orders for Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]},"description":"Paginated list of Temu orders that contain this product (matched by goodsId), newest first by parentOrderTime. 403 if the product does not belong to the integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/{product}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products",":product","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"product","value":"","description":"The product ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7781,\n      \"parentOrderSn\": \"PO-2026-0001234\",\n      \"parentOrderTime\": \"2026-06-17T09:42:11.000000Z\",\n      \"parentOrderStatus\": \"SHIPPED\",\n      \"integration_instance_id\": 12,\n      \"json_object\": {\n        \"parentOrderSn\": \"PO-2026-0001234\",\n        \"orderList\": []\n      },\n      \"created_at\": \"2026-06-17T09:44:00.000000Z\",\n      \"updated_at\": \"2026-06-18T12:01:18.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1,\n  \"first_page_url\": \"https://app.sku.io/api/temu/12/products/1024/orders?page=1\",\n  \"last_page_url\": \"https://app.sku.io/api/temu/12/products/1024/orders?page=1\",\n  \"next_page_url\": null,\n  \"prev_page_url\": null,\n  \"path\": \"https://app.sku.io/api/temu/12/products/1024/orders\",\n  \"links\": []\n}"}]},{"name":"List Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of SalesOrderFulfillment records for the given Temu integration instance. Per-page default is 10. Supports Spatie QueryBuilder filters (filter[...]), sorts (sort=...), and grouped advanced filters (filter_groups).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4521,\n      \"fulfillment_number\": \"FUL-4521\",\n      \"sales_order_id\": 9912,\n      \"fulfillment_sequence\": 1,\n      \"fulfillment_type\": \"manual\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_link\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"cost\": \"5.99\",\n      \"fulfilled_at\": \"2026-06-18T14:32:11.000000Z\",\n      \"submitted_to_sales_channel_at\": \"2026-06-18T14:32:45.000000Z\",\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"physical\"\n      },\n      \"requested_shipping_method\": \"UPS Ground\",\n      \"fulfilled_shipping_method\": \"UPS Ground\",\n      \"fulfilled_quantity\": 2,\n      \"sales_order\": {\n        \"id\": 9912,\n        \"sales_order_number\": \"SO-9912\",\n        \"order_status\": \"shipped\",\n        \"temu_order\": {\n          \"id\": 33012,\n          \"parentOrderSn\": \"PO123456789012345\"\n        }\n      },\n      \"created_at\": \"2026-06-18T14:30:00.000000Z\",\n      \"updated_at\": \"2026-06-18T14:32:45.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 3,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/fulfillments?page=3\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/fulfillments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/fulfillments?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-a.test/api/temu/1/fulfillments?page=2\",\n  \"path\": \"https://sku-a.test/api/temu/1/fulfillments\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 27\n}"}]},{"name":"Show Fulfillment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/{fulfillment}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments",":fulfillment"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"fulfillment","value":"","description":"The fulfillment ID."}]},"description":"Returns a single fulfillment with lines, warehouse/carrier mapping flags, API call logs, and the warehouse/carrier display-name maps used by the UI. Returns 404 if the fulfillment does not belong to the given Temu integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/{fulfillment}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments",":fulfillment"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"fulfillment","value":"","description":"The fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4521,\n    \"fulfillment_number\": \"FUL-4521\",\n    \"sales_order_id\": 9912,\n    \"fulfillment_sequence\": 1,\n    \"fulfillment_type\": \"manual\",\n    \"status\": \"fulfilled\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_link\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n    \"cost\": \"5.99\",\n    \"fulfilled_at\": \"2026-06-18T14:32:11.000000Z\",\n    \"submitted_to_sales_channel_at\": \"2026-06-18T14:32:45.000000Z\",\n    \"warehouse\": {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\",\n      \"type\": \"physical\"\n    },\n    \"requested_shipping_method\": \"UPS Ground\",\n    \"fulfilled_shipping_method\": \"UPS Ground\",\n    \"fulfilled_quantity\": 2,\n    \"sales_order\": {\n      \"id\": 9912,\n      \"sales_order_number\": \"SO-9912\",\n      \"order_status\": \"shipped\",\n      \"temu_order\": {\n        \"id\": 33012,\n        \"parentOrderSn\": \"PO123456789012345\"\n      }\n    },\n    \"created_at\": \"2026-06-18T14:30:00.000000Z\",\n    \"updated_at\": \"2026-06-18T14:32:45.000000Z\",\n    \"fulfillment_lines\": [\n      {\n        \"id\": 8801,\n        \"quantity\": 2,\n        \"sku\": \"SKU-RED-M\",\n        \"product_name\": \"Red T-Shirt (Medium)\"\n      }\n    ],\n    \"user\": {\n      \"id\": 7,\n      \"name\": \"Operations Bot\"\n    },\n    \"warehouse_mapped\": true,\n    \"carrier_mapped\": true,\n    \"api_logs\": [\n      {\n        \"id\": 552201,\n        \"request_url\": \"https://openapi.temu.com/openapi/router\",\n        \"request_method\": \"POST\",\n        \"request_body\": \"{\\\"request\\\":{\\\"sendRequestList\\\":[{\\\"selfShippingWarehouseId\\\":\\\"WH001\\\",\\\"carrierId\\\":1001,\\\"trackingNumber\\\":\\\"1Z999AA10123456784\\\"}]}}\",\n        \"response_status\": 200,\n        \"response_body\": \"{\\\"success\\\":true,\\\"result\\\":{\\\"successList\\\":[\\\"PO123456789012345\\\"]}}\",\n        \"request_timestamp\": \"2026-06-18T14:32:44.500000Z\",\n        \"response_timestamp\": \"2026-06-18T14:32:45.100000Z\",\n        \"duration\": 600,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"carrier_name\": \"UPS\"\n      }\n    ]\n  }\n}"}]},{"name":"Submit Fulfillment to Temu","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Registered by the shared salesChannel route macro (POST /api/temu/{integrationInstance}/fulfill). Submits an existing SalesOrderFulfillment to Temu. Temu does NOT auto-generate tracking — a carrier tracking number must already be stored on the fulfillment OR be supplied here in the request body (it will be persisted).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- sales_order_fulfillment_id (required, integer, must exist in sales_order_fulfillments)\n- tracking_number (nullable, string, max 255)","body":{"mode":"raw","raw":"{\n  \"sales_order_fulfillment_id\": 4521,\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfill","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfill"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully submitted to Temu.\",\n  \"data\": null\n}"}]},{"name":"Get Shipment Status","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/shipment-status","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","shipment-status"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Fetches the current shipment/tracking status from Temu for a single child order (orderSn) belonging to a parent order (parentOrderSn). Proxies bg.logistics.shipment.get on the Temu Open Platform.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- parent_order_sn (required, string)\n- order_sn (required, string)","body":{"mode":"raw","raw":"{\n  \"parent_order_sn\": \"PO123456789012345\",\n  \"order_sn\": \"OO987654321098765\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/shipment-status","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","shipment-status"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"errorCode\": 1000000,\n  \"errorMsg\": \"Success\",\n  \"result\": {\n    \"parentOrderSn\": \"PO123456789012345\",\n    \"orderSn\": \"OO987654321098765\",\n    \"shipmentStatus\": \"DELIVERED\",\n    \"trackingNumber\": \"1Z999AA10123456784\",\n    \"carrierId\": 1001,\n    \"carrierName\": \"UPS\",\n    \"shippedAt\": 1750250400,\n    \"deliveredAt\": 1750500000\n  }\n}"}]},{"name":"Update Shipping Type","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/update-shipping-type","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","update-shipping-type"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Updates the carrier and tracking number for a shipment that has already been submitted. Used when the original carrier doesn't pick up the package within 48 hours and the seller needs to switch carriers without recreating the shipment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- parent_order_sn (required, string)\n- order_sn (required, string)\n- carrier_id (required, integer — Temu logisticsServiceProviderId)\n- tracking_number (required, string, max 255)","body":{"mode":"raw","raw":"{\n  \"parent_order_sn\": \"PO123456789012345\",\n  \"order_sn\": \"OO987654321098765\",\n  \"carrier_id\": 1001,\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/update-shipping-type","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","update-shipping-type"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"errorCode\": 1000000,\n  \"errorMsg\": \"Success\",\n  \"result\": {\n    \"parentOrderSn\": \"PO123456789012345\",\n    \"orderSn\": \"OO987654321098765\",\n    \"updated\": true\n  }\n}"}]},{"name":"Get Unshipped Packages","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/unshipped-packages","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","unshipped-packages"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns the list of child orders (packages) within a parent order that have not yet been confirmed as shipped on Temu. Used to drive the partial-shipment / multi-package UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- parent_order_sn (required, string)","body":{"mode":"raw","raw":"{\n  \"parent_order_sn\": \"PO123456789012345\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/unshipped-packages","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","unshipped-packages"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"errorCode\": 1000000,\n  \"errorMsg\": \"Success\",\n  \"result\": {\n    \"parentOrderSn\": \"PO123456789012345\",\n    \"unshippedPackageList\": [\n      {\n        \"orderSn\": \"OO987654321098766\",\n        \"skcId\": 5500123,\n        \"productSkuId\": 7700456,\n        \"productSkuName\": \"Red T-Shirt (Medium)\",\n        \"quantity\": 2\n      }\n    ]\n  }\n}"}]},{"name":"Confirm Shipped Package","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/confirm-shipped-package","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","confirm-shipped-package"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Confirms one or more packages within a parent order as shipped on Temu, supplying the carrier tracking number for each child order. Required because Temu does NOT auto-generate tracking — sellers must supply tracking for every package before Temu treats the parent order as shipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- parent_order_sn (required, string)\n- package_list (required, array)\n- package_list.*.orderSn (required, string)\n- package_list.*.trackingNumber (required, string)","body":{"mode":"raw","raw":"{\n  \"parent_order_sn\": \"PO123456789012345\",\n  \"package_list\": [\n    {\n      \"orderSn\": \"OO987654321098765\",\n      \"trackingNumber\": \"1Z999AA10123456784\"\n    },\n    {\n      \"orderSn\": \"OO987654321098766\",\n      \"trackingNumber\": \"1Z999AA10123456785\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/confirm-shipped-package","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","confirm-shipped-package"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"errorCode\": 1000000,\n  \"errorMsg\": \"Success\",\n  \"result\": {\n    \"parentOrderSn\": \"PO123456789012345\",\n    \"confirmedList\": [\n      {\n        \"orderSn\": \"OO987654321098765\",\n        \"trackingNumber\": \"1Z999AA10123456784\",\n        \"status\": \"SHIPPED\"\n      }\n    ],\n    \"failedList\": []\n  }\n}"}]},{"name":"Get Fulfillment Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Returns lightweight fulfillment counters for the integration instance:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `pending_submit_count` — fulfillments belonging to this channel's sales orders that have not yet been submitted to Temu.\n- `submit_mode` — always `manual` for Temu: every fulfillment must be submitted explicitly with a carrier-issued tracking number; there is no automatic shipment sync.\n- `submit_mode_description` — human-readable explanation of the submit mode.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/stats","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments","stats"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"pending_submit_count\": 7,\n    \"submit_mode\": \"manual\",\n    \"submit_mode_description\": \"Each fulfillment must be submitted manually with a carrier-issued tracking number — Temu does not auto-sync.\"\n  }\n}"}]},{"name":"Get Fulfillment Preflight Result","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/{fulfillment}/preflight","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments",":fulfillment","preflight"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."},{"key":"fulfillment","value":"9214","description":"The fulfillment ID."}]},"description":"Validates a stored fulfillment against Temu's shipment-confirmation requirements before submission. Temu requires three values per package — a mapped carrier, a mapped warehouse, and a tracking number — all of which must be configured on the platform side. This endpoint reports exactly which requirements are unmet so submission failures can be prevented up front.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n\n- `can_submit` (boolean) — `true` when every requirement is satisfied.\n- `blockers` (array) — one entry per unmet requirement: `field` (`carrier`, `warehouse` or `tracking_number`), a human-readable `message`, and `fix_path` (a relative in-app settings path where the mapping can be corrected, or `null` when the fix is on the fulfillment itself).\n- `resolved` (object) — the values that would be sent to Temu: `carrier_id` (Temu logistics provider id), `warehouse_id` (Temu warehouse id string), `tracking_number`. Unresolvable values are `null`.\n\nReturns 404 when the fulfillment does not belong to this integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/{fulfillment}/preflight","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments",":fulfillment","preflight"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."},{"key":"fulfillment","value":"9214","description":"The fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"can_submit\": false,\n    \"blockers\": [\n      {\n        \"field\": \"tracking_number\",\n        \"message\": \"A tracking number is required by Temu. Enter the carrier-issued tracking number before submitting.\",\n        \"fix_path\": null\n      }\n    ],\n    \"resolved\": {\n      \"carrier_id\": 331,\n      \"warehouse_id\": \"WH-3341992291\",\n      \"tracking_number\": null\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Preview Fulfillment Preflight","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/preflight-preview","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments","preflight-preview"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Runs the same Temu shipment-confirmation checks as the stored-fulfillment preflight, but against raw input values instead of a persisted fulfillment. Use this to validate a fulfillment while it is still being composed, before anything is saved.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body (all fields optional — omitted values are reported as blockers):\n\n- `warehouse_id` (integer) — local warehouse id; must be mapped to a Temu warehouse.\n- `shipping_method_id` (integer) — local shipping method id; must be mapped to a Temu carrier.\n- `tracking_number` (string, max 255) — carrier-issued tracking number.\n\nThe response shape matches the stored-fulfillment preflight: `can_submit`, `blockers` (each with `field`, `message`, `fix_path`), and `resolved` (`carrier_id`, `warehouse_id`, `tracking_number`).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 2,\n  \"shipping_method_id\": 14,\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/fulfillments/preflight-preview","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","fulfillments","preflight-preview"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"can_submit\": true,\n    \"blockers\": [],\n    \"resolved\": {\n      \"carrier_id\": 331,\n      \"warehouse_id\": \"WH-3341992291\",\n      \"tracking_number\": \"1Z999AA10123456784\"\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses"],"query":[{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of TemuWarehouse records for the given integration instance. Includes the mapped local Warehouse (when set) via the `warehouse` relation. Per-page default is 15.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses"],"query":[{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 17,\n      \"integration_instance_id\": 1,\n      \"local_warehouse_id\": 12,\n      \"warehouseName\": \"US East Fulfillment Center\",\n      \"warehouseId\": \"WH-US-EAST-001\",\n      \"warehouseBrand\": \"SKU Operations\",\n      \"regionId1\": \"211\",\n      \"defaultWarehouse\": true,\n      \"json_object\": {\n        \"warehouseAddress\": {\n          \"countryCode\": \"US\",\n          \"province\": \"NJ\",\n          \"city\": \"Newark\",\n          \"postCode\": \"07102\"\n        }\n      },\n      \"created_at\": \"2026-05-12T10:14:22.000000Z\",\n      \"updated_at\": \"2026-06-18T09:01:45.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu US Production\"\n      },\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Main Warehouse\",\n        \"type\": \"physical\"\n      }\n    },\n    {\n      \"id\": 18,\n      \"integration_instance_id\": 1,\n      \"local_warehouse_id\": null,\n      \"warehouseName\": \"US West Fulfillment Center\",\n      \"warehouseId\": \"WH-US-WEST-001\",\n      \"warehouseBrand\": null,\n      \"regionId1\": \"211\",\n      \"defaultWarehouse\": false,\n      \"json_object\": {},\n      \"created_at\": \"2026-05-12T10:14:23.000000Z\",\n      \"updated_at\": \"2026-05-12T10:14:23.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu US Production\"\n      },\n      \"warehouse\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/warehouses?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/warehouses?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/warehouses?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-a.test/api/temu/1/warehouses\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Download Warehouses (Sync from Temu)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/download-locations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","download-locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Synchronously dispatches a background job against the Temu Open API to refresh the TemuWarehouse cache for this integration instance. Returns the refreshed list of Temu warehouses along with the local inventory warehouses configured on the instance for the mapping UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/download-locations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","download-locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"temuLocations\": [\n      {\n        \"id\": 17,\n        \"integration_instance_id\": 1,\n        \"local_warehouse_id\": 12,\n        \"warehouseName\": \"US East Fulfillment Center\",\n        \"warehouseId\": \"WH-US-EAST-001\",\n        \"warehouseBrand\": \"SKU Operations\",\n        \"regionId1\": \"211\",\n        \"defaultWarehouse\": true,\n        \"json_object\": {\n          \"warehouseAddress\": {\n            \"countryCode\": \"US\",\n            \"province\": \"NJ\",\n            \"city\": \"Newark\"\n          }\n        },\n        \"created_at\": \"2026-05-12T10:14:22.000000Z\",\n        \"updated_at\": \"2026-06-19T08:02:11.000000Z\"\n      }\n    ],\n    \"inventoryLocations\": [\n      {\n        \"id\": 12,\n        \"name\": \"Main Warehouse\"\n      },\n      {\n        \"id\": 14,\n        \"name\": \"West Coast DC\"\n      }\n    ]\n  }\n}"}]},{"name":"Map Warehouse to Local Warehouse","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses/{temu_warehouse}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses",":temu_warehouse","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"temu_warehouse","value":"","description":"The temu warehouse ID."}]},"description":"Sets `local_warehouse_id` on the TemuWarehouse record so fulfillments routed to this Temu warehouse pull stock from the chosen local Warehouse.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `warehouse_id` — nullable integer, must exist in `warehouses`. Pass `null` to clear the mapping.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses/{temu_warehouse}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses",":temu_warehouse","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"temu_warehouse","value":"","description":"The temu warehouse ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 17,\n    \"integration_instance_id\": 1,\n    \"local_warehouse_id\": 12,\n    \"warehouseName\": \"US East Fulfillment Center\",\n    \"warehouseId\": \"WH-US-EAST-001\",\n    \"warehouseBrand\": \"SKU Operations\",\n    \"regionId1\": \"211\",\n    \"defaultWarehouse\": true,\n    \"json_object\": {\n      \"warehouseAddress\": {\n        \"countryCode\": \"US\",\n        \"province\": \"NJ\",\n        \"city\": \"Newark\"\n      }\n    },\n    \"created_at\": \"2026-05-12T10:14:22.000000Z\",\n    \"updated_at\": \"2026-06-19T08:10:01.000000Z\"\n  },\n  \"message\": \"Warehouse mapping updated successfully\"\n}"}]},{"name":"Check Mapping by Local Warehouse","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses/by-warehouse/{warehouse_id}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses","by-warehouse",":warehouse_id"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"warehouse_id","value":"","description":"The warehouse ID."}]},"description":"Reverse lookup — given a local Warehouse ID, returns the TemuWarehouse it is mapped to (if any). Used by the fulfillment UI to warn users before submission when a local warehouse has no Temu mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/warehouses/by-warehouse/{warehouse_id}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","warehouses","by-warehouse",":warehouse_id"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"warehouse_id","value":"","description":"The warehouse ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouse\": {\n      \"id\": 17,\n      \"integration_instance_id\": 1,\n      \"local_warehouse_id\": 12,\n      \"warehouseName\": \"US East Fulfillment Center\",\n      \"warehouseId\": \"WH-US-EAST-001\",\n      \"warehouseBrand\": \"SKU Operations\",\n      \"regionId1\": \"211\",\n      \"defaultWarehouse\": true,\n      \"json_object\": {},\n      \"created_at\": \"2026-05-12T10:14:22.000000Z\",\n      \"updated_at\": \"2026-06-19T08:10:01.000000Z\"\n    },\n    \"is_mapped\": true\n  }\n}"}]},{"name":"List Carriers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers"],"query":[{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of TemuCarrier records for the given integration instance. Includes the mapped local ShippingMethod (when set) via the `shipping_method` relation. Per-page default is 15.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers"],"query":[{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 31,\n      \"integration_instance_id\": 1,\n      \"logisticsServiceProviderId\": 1001,\n      \"logisticsServiceProviderName\": \"UPS\",\n      \"logisticsBrandName\": \"UPS Ground\",\n      \"ship_to_country_id\": 211,\n      \"local_shipping_method_id\": 7,\n      \"created_at\": \"2026-05-12T10:18:01.000000Z\",\n      \"updated_at\": \"2026-06-15T14:32:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu US Production\"\n      },\n      \"shipping_method\": {\n        \"id\": 7,\n        \"name\": \"UPS Ground\",\n        \"carrier\": \"UPS\"\n      }\n    },\n    {\n      \"id\": 32,\n      \"integration_instance_id\": 1,\n      \"logisticsServiceProviderId\": 1002,\n      \"logisticsServiceProviderName\": \"USPS\",\n      \"logisticsBrandName\": \"USPS Priority\",\n      \"ship_to_country_id\": 211,\n      \"local_shipping_method_id\": null,\n      \"created_at\": \"2026-05-12T10:18:02.000000Z\",\n      \"updated_at\": \"2026-05-12T10:18:02.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu US Production\"\n      },\n      \"shipping_method\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/carriers?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/carriers?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/carriers?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://sku-a.test/api/temu/1/carriers\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Download Carriers (Sync from Temu)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/download-carriers","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","download-carriers"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Synchronously dispatches a background job against the Temu Open API to refresh the TemuCarrier cache for the requested region (default US=211). When `region_id=all`, dispatches once per supported region. Returns the refreshed list of TemuCarrier records together with the regions that were downloaded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/download-carriers","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","download-carriers"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"carriers\": [\n      {\n        \"id\": 31,\n        \"integration_instance_id\": 1,\n        \"logisticsServiceProviderId\": 1001,\n        \"logisticsServiceProviderName\": \"UPS\",\n        \"logisticsBrandName\": \"UPS Ground\",\n        \"ship_to_country_id\": 211,\n        \"local_shipping_method_id\": 7,\n        \"created_at\": \"2026-05-12T10:18:01.000000Z\",\n        \"updated_at\": \"2026-06-19T08:14:30.000000Z\"\n      },\n      {\n        \"id\": 32,\n        \"integration_instance_id\": 1,\n        \"logisticsServiceProviderId\": 1002,\n        \"logisticsServiceProviderName\": \"USPS\",\n        \"logisticsBrandName\": \"USPS Priority\",\n        \"ship_to_country_id\": 211,\n        \"local_shipping_method_id\": null,\n        \"created_at\": \"2026-05-12T10:18:02.000000Z\",\n        \"updated_at\": \"2026-06-19T08:14:30.000000Z\"\n      }\n    ],\n    \"regions_downloaded\": [\n      211\n    ]\n  }\n}"}]},{"name":"Map Carrier to Shipping Method","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers/{temu_carrier_id}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers",":temu_carrier_id","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"temu_carrier_id","value":"","description":"The temu carrier ID."}]},"description":"Sets `local_shipping_method_id` on the TemuCarrier record so that submitting a fulfillment with the chosen shipping method routes to this Temu carrier (logisticsServiceProviderId).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `shipping_method_id` — nullable integer, must exist in `shipping_methods`. Pass `null` to clear the mapping.\n\nReturns 404 if the TemuCarrier does not belong to the supplied integration instance.","body":{"mode":"raw","raw":"{\n  \"shipping_method_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers/{temu_carrier_id}/map","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers",":temu_carrier_id","map"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"temu_carrier_id","value":"","description":"The temu carrier ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 31,\n    \"integration_instance_id\": 1,\n    \"logisticsServiceProviderId\": 1001,\n    \"logisticsServiceProviderName\": \"UPS\",\n    \"logisticsBrandName\": \"UPS Ground\",\n    \"ship_to_country_id\": 211,\n    \"local_shipping_method_id\": 7,\n    \"created_at\": \"2026-05-12T10:18:01.000000Z\",\n    \"updated_at\": \"2026-06-19T08:20:45.000000Z\",\n    \"shipping_method\": {\n      \"id\": 7,\n      \"name\": \"UPS Ground\",\n      \"carrier\": \"UPS\"\n    }\n  },\n  \"message\": \"Carrier mapping updated successfully\"\n}"}]},{"name":"Check Mapping by Shipping Method","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers/by-shipping-method/{shipping_method_id}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers","by-shipping-method",":shipping_method_id"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"shipping_method_id","value":"","description":"The shipping method ID."}]},"description":"Reverse lookup — given a local ShippingMethod ID, returns the TemuCarrier it is mapped to (if any). Used by the fulfillment UI to warn users before submission when a shipping method has no Temu carrier mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/carriers/by-shipping-method/{shipping_method_id}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","carriers","by-shipping-method",":shipping_method_id"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"shipping_method_id","value":"","description":"The shipping method ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"carrier\": {\n      \"id\": 31,\n      \"integration_instance_id\": 1,\n      \"logisticsServiceProviderId\": 1001,\n      \"logisticsServiceProviderName\": \"UPS\",\n      \"logisticsBrandName\": \"UPS Ground\",\n      \"ship_to_country_id\": 211,\n      \"local_shipping_method_id\": 7,\n      \"created_at\": \"2026-05-12T10:18:01.000000Z\",\n      \"updated_at\": \"2026-06-19T08:20:45.000000Z\"\n    },\n    \"is_mapped\": true\n  }\n}"}]},{"name":"Get Available Fields","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings/available-fields","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings","available-fields"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns the catalog of available Temu product fields (grouped by Basic Info, Pricing & Inventory, Dimensions & Weight) and SKU.io product fields available for mapping. Powers the field-mapping configuration UI dropdowns.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings/available-fields","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings","available-fields"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"temu_fields\": [\n      {\n        \"id\": \"skuId\",\n        \"name\": \"SKU ID\",\n        \"group\": \"Basic Info\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"goodsId\",\n        \"name\": \"Goods ID\",\n        \"group\": \"Basic Info\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"goodsName\",\n        \"name\": \"Goods Name\",\n        \"group\": \"Basic Info\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"thumbUrl\",\n        \"name\": \"Thumbnail URL\",\n        \"group\": \"Basic Info\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"skuStatus\",\n        \"name\": \"SKU Status\",\n        \"group\": \"Basic Info\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"priceAmount\",\n        \"name\": \"Price\",\n        \"group\": \"Pricing & Inventory\",\n        \"type\": \"decimal\"\n      },\n      {\n        \"id\": \"priceCurrency\",\n        \"name\": \"Currency\",\n        \"group\": \"Pricing & Inventory\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"quantity\",\n        \"name\": \"Quantity\",\n        \"group\": \"Pricing & Inventory\",\n        \"type\": \"integer\"\n      },\n      {\n        \"id\": \"weight\",\n        \"name\": \"Weight\",\n        \"group\": \"Dimensions & Weight\",\n        \"type\": \"decimal\"\n      },\n      {\n        \"id\": \"length\",\n        \"name\": \"Length\",\n        \"group\": \"Dimensions & Weight\",\n        \"type\": \"decimal\"\n      },\n      {\n        \"id\": \"width\",\n        \"name\": \"Width\",\n        \"group\": \"Dimensions & Weight\",\n        \"type\": \"decimal\"\n      },\n      {\n        \"id\": \"height\",\n        \"name\": \"Height\",\n        \"group\": \"Dimensions & Weight\",\n        \"type\": \"decimal\"\n      }\n    ],\n    \"sku_fields\": [\n      {\n        \"id\": \"sku\",\n        \"name\": \"SKU\",\n        \"description\": \"Stock keeping unit identifier\",\n        \"required\": true\n      },\n      {\n        \"id\": \"item_name\",\n        \"name\": \"Product Name\",\n        \"description\": \"Main product name\",\n        \"required\": true\n      },\n      {\n        \"id\": \"barcode\",\n        \"name\": \"Barcode\",\n        \"description\": \"Product barcode (UPC/EAN)\",\n        \"required\": false\n      },\n      {\n        \"id\": \"mpn\",\n        \"name\": \"MPN\",\n        \"description\": \"Manufacturer part number\",\n        \"required\": false\n      },\n      {\n        \"id\": \"brand\",\n        \"name\": \"Brand\",\n        \"description\": \"Product brand or manufacturer\",\n        \"required\": false\n      },\n      {\n        \"id\": \"price\",\n        \"name\": \"Price\",\n        \"description\": \"Selling price\",\n        \"required\": false\n      },\n      {\n        \"id\": \"weight\",\n        \"name\": \"Weight\",\n        \"description\": \"Product weight\",\n        \"required\": false\n      },\n      {\n        \"id\": \"length\",\n        \"name\": \"Length\",\n        \"description\": \"Product length dimension\",\n        \"required\": false\n      },\n      {\n        \"id\": \"width\",\n        \"name\": \"Width\",\n        \"description\": \"Product width dimension\",\n        \"required\": false\n      },\n      {\n        \"id\": \"height\",\n        \"name\": \"Height\",\n        \"description\": \"Product height dimension\",\n        \"required\": false\n      },\n      {\n        \"id\": \"image\",\n        \"name\": \"Primary Image\",\n        \"description\": \"Primary product image URL\",\n        \"required\": false\n      },\n      {\n        \"id\": \"other_images\",\n        \"name\": \"Additional Images\",\n        \"description\": \"Additional product image URLs\",\n        \"required\": false\n      }\n    ]\n  }\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns the saved listing field-mapping configuration for this Temu integration instance. Each entry pairs a Temu field (`listing_field`) with a SKU.io field (`sku_field`) and may include optional parsers that transform the value during import.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"listing_field\": \"skuId\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"goodsName\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"priceAmount\",\n        \"sku_field\": \"price\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"thumbUrl\",\n        \"sku_field\": \"image\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"goodsName\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [\n          {\n            \"rule\": \"fr\",\n            \"args\": {\n              \"find\": \"Brand:\",\n              \"replace\": \"\"\n            }\n          }\n        ]\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Persist the listing field-mapping configuration for this Temu integration instance (model = `listings` in `integration_field_mappings`). Replaces the existing mapping for the instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `mappings` — required array\n- `mappings.*.listing_field` — required string (Temu field id from the available-fields catalog)\n- `mappings.*.sku_field` — required string (SKU.io field id from the available-fields catalog)\n- `mappings.*.parsers` — optional array of parser rules\n- `mappings.*.parsers.*.rule` — required when `parsers` is supplied; must be one of `fr` (find-replace), `tl` (trim-left), `tr` (trim-right), `append`\n- `mappings.*.parsers.*.args` — optional array of parser arguments","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"skuId\",\n      \"sku_field\": \"sku\"\n    },\n    {\n      \"listing_field\": \"goodsName\",\n      \"sku_field\": \"item_name\"\n    },\n    {\n      \"listing_field\": \"priceAmount\",\n      \"sku_field\": \"price\"\n    },\n    {\n      \"listing_field\": \"thumbUrl\",\n      \"sku_field\": \"image\"\n    },\n    {\n      \"listing_field\": \"goodsName\",\n      \"sku_field\": \"brand\",\n      \"parsers\": [\n        {\n          \"rule\": \"fr\",\n          \"args\": {\n            \"find\": \"Brand:\",\n            \"replace\": \"\"\n          }\n        },\n        {\n          \"rule\": \"tl\"\n        }\n      ]\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/field-mappings","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","field-mappings"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"mappings\": [\n      {\n        \"listing_field\": \"skuId\",\n        \"sku_field\": \"sku\"\n      },\n      {\n        \"listing_field\": \"goodsName\",\n        \"sku_field\": \"item_name\"\n      },\n      {\n        \"listing_field\": \"priceAmount\",\n        \"sku_field\": \"price\"\n      },\n      {\n        \"listing_field\": \"thumbUrl\",\n        \"sku_field\": \"image\"\n      },\n      {\n        \"listing_field\": \"goodsName\",\n        \"sku_field\": \"brand\",\n        \"parsers\": [\n          {\n            \"rule\": \"fr\",\n            \"args\": {\n              \"find\": \"Brand:\",\n              \"replace\": \"\"\n            }\n          },\n          {\n            \"rule\": \"tl\"\n          }\n        ]\n      }\n    ]\n  },\n  \"message\": \"Field mappings saved successfully\"\n}"}]},{"name":"List Inventory (Comparison)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated inventory comparison — one row per SKU x Temu warehouse from sales_channel_product_inventory_caches. Joins productListing -> salesChannelProduct/product/subscriptionOffering and resolves the Temu warehouse name via temu_warehouses.warehouseId. Default per_page is 10; default sort is -id. Restricted to warehouses belonging to this integration instance. Supports Spatie QueryBuilder filters (filter[...]), sorts (sort=...), and grouped advanced filters (filter_groups).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"product_listing_id\": 5521,\n      \"document_id\": 8801,\n      \"listing_sku\": \"TEMU-RED-M\",\n      \"title\": \"Red T-Shirt (Medium)\",\n      \"product\": {\n        \"id\": 3312,\n        \"sku\": \"SKU-RED-M\",\n        \"name\": \"Red T-Shirt (Medium)\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"WH001\",\n      \"location_name\": \"Main Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 42,\n      \"sales_channel_quantity\": 42,\n      \"variance\": 0,\n      \"status\": \"synced\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-18T14:00:00+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-18T13:55:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-18T14:02:00+00:00\",\n      \"created_at\": \"2026-05-01T09:00:00+00:00\",\n      \"updated_at\": \"2026-06-18T14:02:00+00:00\"\n    },\n    {\n      \"id\": 90212,\n      \"product_listing_id\": 5522,\n      \"document_id\": 8802,\n      \"listing_sku\": \"TEMU-BLU-L\",\n      \"title\": \"Blue T-Shirt (Large)\",\n      \"product\": {\n        \"id\": 3313,\n        \"sku\": \"SKU-BLU-L\",\n        \"name\": \"Blue T-Shirt (Large)\"\n      },\n      \"subscription_offering\": null,\n      \"location_id\": \"WH001\",\n      \"location_name\": \"Main Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 17,\n      \"sales_channel_quantity\": 20,\n      \"variance\": -3,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sku_quantity_updated_at\": \"2026-06-18T14:00:00+00:00\",\n      \"sales_channel_quantity_updated_at\": \"2026-06-18T13:55:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-06-17T10:00:00+00:00\",\n      \"created_at\": \"2026-05-01T09:00:00+00:00\",\n      \"updated_at\": \"2026-06-18T14:00:00+00:00\"\n    },\n    {\n      \"id\": 90213,\n      \"product_listing_id\": 5523,\n      \"document_id\": 8803,\n      \"listing_sku\": \"TEMU-GRN-S\",\n      \"title\": \"Green T-Shirt (Small)\",\n      \"product\": null,\n      \"subscription_offering\": {\n        \"id\": 71,\n        \"name\": \"Monthly Tee Club\",\n        \"sku\": \"OFFER-TEE-MONTH\"\n      },\n      \"location_id\": \"WH002\",\n      \"location_name\": \"Overflow Warehouse\",\n      \"location_is_active\": true,\n      \"sku_quantity\": 0,\n      \"sales_channel_quantity\": null,\n      \"variance\": 0,\n      \"status\": \"needs_recalc\",\n      \"is_sku_recalculation_needed\": true,\n      \"sku_quantity_updated_at\": null,\n      \"sales_channel_quantity_updated_at\": null,\n      \"sales_channel_quantity_synced_at\": null,\n      \"created_at\": \"2026-06-10T09:00:00+00:00\",\n      \"updated_at\": \"2026-06-10T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/inventory?page=1\",\n  \"from\": 1,\n  \"last_page\": 5,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/inventory?page=5\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/inventory?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/inventory?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-a.test/api/temu/1/inventory?page=2\",\n  \"path\": \"https://sku-a.test/api/temu/1/inventory\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 48\n}"}]},{"name":"Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Aggregate inventory statistics for the integration: total rows, in-sync count, variance count, needs-recalc count, plus the latest fetch and sync timestamps across all cached rows for Temu warehouses owned by this integration. Returns zeros and null timestamps when no warehouses are mapped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 48,\n    \"in_sync\": 39,\n    \"with_variance\": 6,\n    \"needs_recalculation\": 3,\n    \"last_fetch_at\": \"2026-06-18T13:55:00.000000Z\",\n    \"last_sync_at\": \"2026-06-18T14:02:00.000000Z\"\n  }\n}"}]},{"name":"List Locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns every Temu warehouse for this integration instance — used to populate the location filter in the inventory UI. `id` is the external Temu warehouseId (also the value used in filter[location_id]), `is_active` reflects the warehouse's defaultWarehouse flag.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/locations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","locations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"WH001\",\n      \"name\": \"Main Warehouse\",\n      \"is_active\": true\n    },\n    {\n      \"id\": \"WH002\",\n      \"name\": \"Overflow Warehouse\",\n      \"is_active\": false\n    }\n  ]\n}"}]},{"name":"Recache Inventory (Recompute SKU.io Quantities)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Queues a background job, which (1) rebuilds `integration_settings.inventory.locations` from temu_warehouses (preserving user-edited masterOfStock and inventoryModificationRules) and (2) recomputes the `sku_quantity` column on every sales_channel_product_inventory_caches row for this integration. Request body is empty. Returns the tracked_job_log_id used to poll progress via the recache-progress endpoint or the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory recache job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 778812\n  }\n}"}]},{"name":"Recache Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]},"description":"Polls the TrackedJobLog row produced by Recache Inventory. Returns 404 if no log exists for the supplied id. The frontend tracked job log endpoints reads `progress_percentage`, `status`, `processed_items` / `total_items` and `messages`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/recache-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","recache-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 778812,\n    \"job_type\": \"Modules\\\\Temu\\\\Jobs\\\\TemuRecacheInventoryTrackedJob\",\n    \"queue\": \"default\",\n    \"job_name\": \"Temu Inventory Recache: Main Temu Store\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": \"Modules\\\\Temu\\\\Entities\\\\TemuIntegrationInstance\",\n      \"reference\": \"Main Temu Store\"\n    },\n    \"related_model_reference\": \"Main Temu Store\",\n    \"messages\": [\n      \"Recomputing sku_quantity for 48 cached rows...\"\n    ],\n    \"attempted_at\": \"2026-06-19T15:00:00.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-19T14:59:59.000000Z\",\n    \"updated_at\": \"2026-06-19T15:00:05.000000Z\",\n    \"results\": null,\n    \"total_items\": 48,\n    \"processed_items\": 22,\n    \"progress_percentage\": 45,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Sync Inventory to Temu (Push)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Queues a background job which pushes the cached SKU.io `sku_quantity` values up to Temu via the Temu inventory API. Request body is empty. Returns the tracked_job_log_id used to poll progress via the sync-progress endpoint or the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","sync"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync job has been queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 778820\n  }\n}"}]},{"name":"Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]},"description":"Polls the TrackedJobLog row produced by Sync Inventory to Temu. Returns 404 if no log exists for the supplied id. When the job is complete, `results` includes per-item push outcomes (successes, failures with messages).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/inventory/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","inventory","sync-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 778820,\n    \"job_type\": \"Modules\\\\Temu\\\\Jobs\\\\TemuSyncInventoryTrackedJob\",\n    \"queue\": \"default\",\n    \"job_name\": \"Temu Inventory Sync: Main Temu Store\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 1,\n      \"type\": \"Modules\\\\Temu\\\\Entities\\\\TemuIntegrationInstance\",\n      \"reference\": \"Main Temu Store\"\n    },\n    \"related_model_reference\": \"Main Temu Store\",\n    \"messages\": [\n      \"Pushed 48 inventory records to Temu (47 succeeded, 1 failed).\"\n    ],\n    \"attempted_at\": \"2026-06-19T15:05:00.000000Z\",\n    \"completed_at\": \"2026-06-19T15:06:12.000000Z\",\n    \"duration\": 72,\n    \"created_at\": \"2026-06-19T15:04:59.000000Z\",\n    \"updated_at\": \"2026-06-19T15:06:12.000000Z\",\n    \"results\": {\n      \"total_pushed\": 48,\n      \"succeeded\": 47,\n      \"failed_count\": 1,\n      \"has_failures\": true,\n      \"failures\": [\n        {\n          \"listing_sku\": \"TEMU-BLU-L\",\n          \"location_id\": \"WH001\",\n          \"message\": \"Temu API: invalid skuId\"\n        }\n      ]\n    },\n    \"total_items\": 48,\n    \"processed_items\": 48,\n    \"progress_percentage\": 100,\n    \"progress_mode\": \"items\",\n    \"stages\": null\n  }\n}"}]},{"name":"Sync Inventory to Temu","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Computes the current sellable stock for mapped Temu listings and pushes the quantities to Temu synchronously. Listings whose cached quantities are stale are recalculated first, then the updated numbers are submitted to Temu's inventory API and the local sync cache is refreshed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n\n- `ids` (array of integers, optional) — product-listing ids to sync. Omit to sync every mapped listing for the instance.\n\nThe call is a no-op (still returning the success message) when this platform is not configured as the master of stock for the instance, or when no eligible listings are found.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    88,\n    89\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/products/sync-inventory","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","products","sync-inventory"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully submitted to sales channel.\",\n  \"status\": \"success\"\n}"}]},{"name":"List Webhook Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns every supported event code with its current local subscription state (`is_enabled`, `subscribed_at`). Drives the Configuration tab in the settings UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"configurations\": [\n      {\n        \"event_code\": \"bg.order.created\",\n        \"label\": \"Order Created\",\n        \"description\": \"Fires when a new order is placed on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.order.updated\",\n        \"label\": \"Order Updated\",\n        \"description\": \"Fires when an existing order is updated on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.order.cancelled\",\n        \"label\": \"Order Cancelled\",\n        \"description\": \"Fires when an order is cancelled on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.order.shipped\",\n        \"label\": \"Order Shipped\",\n        \"description\": \"Fires when an order has been marked as shipped on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.order.delivered\",\n        \"label\": \"Order Delivered\",\n        \"description\": \"Fires when an order has been delivered to the customer.\",\n        \"is_enabled\": false,\n        \"subscribed_at\": null\n      },\n      {\n        \"event_code\": \"bg.product.created\",\n        \"label\": \"Product Created\",\n        \"description\": \"Fires when a new product is created on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.product.updated\",\n        \"label\": \"Product Updated\",\n        \"description\": \"Fires when a product is updated on Temu.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.product.deleted\",\n        \"label\": \"Product Deleted\",\n        \"description\": \"Fires when a product is removed from Temu.\",\n        \"is_enabled\": false,\n        \"subscribed_at\": null\n      },\n      {\n        \"event_code\": \"bg.inventory.updated\",\n        \"label\": \"Inventory Updated\",\n        \"description\": \"Fires when Temu updates the available stock for a product.\",\n        \"is_enabled\": true,\n        \"subscribed_at\": \"2026-06-15T10:22:11+00:00\"\n      },\n      {\n        \"event_code\": \"bg.aftersales.created\",\n        \"label\": \"After-Sales Request\",\n        \"description\": \"Fires when a buyer initiates a return, refund, or other after-sales action.\",\n        \"is_enabled\": false,\n        \"subscribed_at\": null\n      }\n    ]\n  }\n}"}]},{"name":"Enable All Webhook Subscriptions","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/enable-all","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations","enable-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Dispatches a background job to subscribe the shop to every event code in TemuEventCodeEnum. Runs through the Tracked Job pattern — frontend should call `notifyJobStarted` and watch the tracked job log endpoints for completion. Response includes the `tracked_job_log_id`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/enable-all","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations","enable-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook subscription job dispatched\",\n  \"data\": {\n    \"tracked_job_log_id\": 88123\n  }\n}"}]},{"name":"Enable Webhook Subscription","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/{eventCode}/enable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations",":eventCode","enable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"eventCode","value":"","description":"The event code ID."}]},"description":"Subscribes the shop to a single event code via `bg.tmc.message.update`. Idempotent — returns success even if already enabled. Returns 500 if Temu rejects the subscription or the event code is invalid.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/{eventCode}/enable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations",":eventCode","enable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"eventCode","value":"","description":"The event code ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook enabled successfully\",\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook enabled successfully\",\n    \"webhook\": {\n      \"id\": 412,\n      \"integration_instance_id\": 1,\n      \"event_code\": \"bg.order.created\",\n      \"subscribed_at\": \"2026-06-18T16:05:11.000000Z\",\n      \"created_at\": \"2026-06-18T16:05:11.000000Z\",\n      \"updated_at\": \"2026-06-18T16:05:11.000000Z\"\n    },\n    \"created\": true\n  }\n}"}]},{"name":"Disable Webhook Subscription","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/{eventCode}/disable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations",":eventCode","disable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"eventCode","value":"","description":"The event code ID."}]},"description":"Unsubscribes the shop from a single event code via `bg.tmc.message.update` (cancel list), then deletes the local `temu_webhooks` row. Idempotent — succeeds even if already disabled. If Temu reports the subscription is already gone (error code 110020009 / 'not found') it is treated as success.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhooks/configurations/{eventCode}/disable","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhooks","configurations",":eventCode","disable"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"eventCode","value":"","description":"The event code ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook disabled successfully\",\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Webhook disabled successfully\",\n    \"deleted\": true\n  }\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of webhook events for the given integration instance. Uses Spatie QueryBuilder with shared `getWebhookEventAllowedFilters` (text/numeric/datetime filters + AdvancedSearch) and supports grouped advanced filters via `filter_groups`. Default sort is `-created_at`, default per_page is 10. Returns Temu webhook event object payloads (truncates `processing_error` to 200 chars + ellipsis).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 99012,\n      \"event_code\": \"bg.order.created\",\n      \"event_label\": \"Order Created\",\n      \"message_id\": \"MSG-AB12CD34EF\",\n      \"unique_id\": \"PO123456789012345\",\n      \"processing_status\": \"processed\",\n      \"processing_attempts\": 1,\n      \"last_processing_attempt_at\": \"2026-06-18T16:21:08.000000Z\",\n      \"processing_error\": null,\n      \"payload_date\": \"2026-06-18T16:20:58.000000Z\",\n      \"created_at\": \"2026-06-18T16:21:02.000000Z\",\n      \"processed_at\": \"2026-06-18T16:21:09.000000Z\",\n      \"processing_completed_at\": \"2026-06-18T16:21:09.000000Z\",\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu Main Shop\"\n      }\n    },\n    {\n      \"id\": 99011,\n      \"event_code\": \"bg.inventory.updated\",\n      \"event_label\": \"Inventory Updated\",\n      \"message_id\": \"MSG-AB12CD34EE\",\n      \"unique_id\": \"112233445566\",\n      \"processing_status\": \"failed\",\n      \"processing_attempts\": 2,\n      \"last_processing_attempt_at\": \"2026-06-18T16:18:45.000000Z\",\n      \"processing_error\": \"{\\\"error\\\":\\\"SKU not found for productSkcId 112233445566\\\",\\\"file\\\":\\\"/var/www/Modules/Temu/Managers/...\",\n      \"payload_date\": \"2026-06-18T16:18:30.000000Z\",\n      \"created_at\": \"2026-06-18T16:18:32.000000Z\",\n      \"processed_at\": null,\n      \"processing_completed_at\": null,\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu Main Shop\"\n      }\n    },\n    {\n      \"id\": 99010,\n      \"event_code\": \"bg.order.shipped\",\n      \"event_label\": \"Order Shipped\",\n      \"message_id\": \"MSG-AB12CD34ED\",\n      \"unique_id\": \"PO123456789012340\",\n      \"processing_status\": \"pending\",\n      \"processing_attempts\": 0,\n      \"last_processing_attempt_at\": null,\n      \"processing_error\": null,\n      \"payload_date\": \"2026-06-18T16:15:11.000000Z\",\n      \"created_at\": \"2026-06-18T16:15:14.000000Z\",\n      \"processed_at\": null,\n      \"processing_completed_at\": null,\n      \"integration_instance\": {\n        \"id\": 1,\n        \"name\": \"Temu Main Shop\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/webhook-events?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/webhook-events?page=12\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/webhook-events?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/webhook-events?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-a.test/api/temu/1/webhook-events?page=2\",\n  \"path\": \"https://sku-a.test/api/temu/1/webhook-events\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 117\n}"}]},{"name":"Get Processing Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","stats"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Aggregate counts by processing_status for the given integration instance. Drives the summary cards above the events table.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/stats","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","stats"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"pending_count\": 12,\n    \"processing_count\": 1,\n    \"processed_count\": 98,\n    \"failed_count\": 6,\n    \"total_count\": 117\n  },\n  \"integration_instance\": {\n    \"id\": 1,\n    \"name\": \"Temu Main Shop\"\n  }\n}"}]},{"name":"Process Pending Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/process","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","process"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Processes pending webhook events for the instance. Both body fields are optional:\n- `event_code` (string, nullable) — restrict to a single event code. Must be one of the TemuEventCodeEnum values (validated server-side).\n- `limit` (int, nullable, 1-100) — cap the number of events processed in this call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"event_code\": \"bg.order.created\",\n  \"limit\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/process","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","process"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed_count\": 11,\n    \"failed_count\": 1,\n    \"message\": \"Processed 12 webhook event(s)\"\n  },\n  \"message\": \"Processing completed successfully\"\n}"}]},{"name":"Retry Failed Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/retry-failed","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","retry-failed"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Resets failed events (where `processing_attempts < 3`) back to pending then processes them again.\n- `limit` (int, nullable, 1-100) — cap the number of failed events retried in this call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"limit\": 25\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/retry-failed","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","retry-failed"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed_count\": 5,\n    \"failed_count\": 1,\n    \"message\": \"Processed 6 webhook event(s)\"\n  },\n  \"message\": \"Retry completed successfully\"\n}"}]},{"name":"Get Event Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]},"description":"Full event payload including `json_data` (the raw decoded TMC message), `processing_error` (full text, not truncated), and timing metadata. Backs the event detail drawer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 99012,\n    \"integration_instance_id\": 1,\n    \"event_code\": \"bg.order.created\",\n    \"event_label\": \"Order Created\",\n    \"message_id\": \"MSG-AB12CD34EF\",\n    \"unique_id\": \"PO123456789012345\",\n    \"processing_status\": \"processed\",\n    \"processing_attempts\": 1,\n    \"last_processing_attempt_at\": \"2026-06-18T16:21:08.000000Z\",\n    \"processing_started_at\": \"2026-06-18T16:21:08.000000Z\",\n    \"processing_completed_at\": \"2026-06-18T16:21:09.000000Z\",\n    \"processing_error\": null,\n    \"payload_date\": \"2026-06-18T16:20:58.000000Z\",\n    \"created_at\": \"2026-06-18T16:21:02.000000Z\",\n    \"processed_at\": \"2026-06-18T16:21:09.000000Z\",\n    \"json_data\": {\n      \"parentOrderSn\": \"PO123456789012345\",\n      \"orderStatus\": 1,\n      \"eventTime\": 1750000858,\n      \"messageTime\": 1750000858,\n      \"orderList\": [\n        {\n          \"orderSn\": \"ORD123456789012345\",\n          \"productSkuId\": \"SKU-RED-M\",\n          \"quantity\": 2,\n          \"price\": \"19.99\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Process Event By Id","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}/process","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId","process"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]},"description":"Processes a single webhook event by id. No-op if the event is already in the processed state (returns success with `event already processed` message). Does NOT reset state — use `/reprocess` to force a re-run on a processed event.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}/process","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId","process"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"event_id\": 99010,\n    \"success\": true,\n    \"message\": \"Event processed successfully\"\n  },\n  \"message\": \"Event processing completed successfully\"\n}"}]},{"name":"Reprocess Event By Id","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}/reprocess","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId","reprocess"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]},"description":"Forces a re-run of the event even if previously processed — resets the row to pending (clearing `processing_error`) and processes it again. Used by the 'Reprocess' action in the per-row menu.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/webhook-events/{eventId}/reprocess","host":["{{baseUrl}}"],"path":["api","temu","webhook-events",":eventId","reprocess"],"variable":[{"key":"eventId","value":"","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"event_id\": 99012,\n    \"success\": true,\n    \"message\": \"Event reprocessed successfully\"\n  },\n  \"message\": \"Event reprocessing completed successfully\"\n}"}]},{"name":"Bulk Reprocess Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/webhook-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","temu","webhook-events","bulk-reprocess"]},"description":"Resets each event in `event_ids` to pending and processes it again.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `event_ids` (array, required unless `apply_to_all=true`) — each id must exist in `temu_webhook_events`.\n- `apply_to_all` (bool, optional) — when true, ignores `event_ids` and resolves the id set from `filters` scoped to `integration_instance_id`.\n- `integration_instance_id` (int, required if `apply_to_all=true`) — the instance whose events to resolve.\n- `filters` (object, optional) — Spatie filter set forwarded to the repository's `getWebhookEventAllowedFilters()`.\n\nReturns `processed_count: 0, failed_count: 0` if the resolved id set is empty.","body":{"mode":"raw","raw":"{\n  \"event_ids\": [\n    99010,\n    99011,\n    99012\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/webhook-events/bulk-reprocess","host":["{{baseUrl}}"],"path":["api","temu","webhook-events","bulk-reprocess"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"processed_count\": 3,\n    \"failed_count\": 0,\n    \"message\": \"Processed 3 webhook event(s)\"\n  },\n  \"message\": \"Bulk reprocessing completed successfully\"\n}"}]},{"name":"Bulk Delete Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","temu","webhook-events","bulk-delete"]},"description":"Deletes the given webhook events. Requires `confirmation: \"YES\"`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation:\n- `event_ids` (array, required unless `apply_to_all=true`) — each id must exist in `temu_webhook_events`.\n- `apply_to_all` (bool, optional) — when true, resolves the id set from `filters` scoped to `integration_instance_id`.\n- `integration_instance_id` (int, required if `apply_to_all=true`).\n- `filters` (object, optional) — Spatie filter set forwarded to the repository.\n- `confirmation` (string, required) — must equal `YES` exactly.\n\nReturns `deleted_count: 0` if the resolved id set is empty."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/webhook-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","temu","webhook-events","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"deleted_count\": 3\n  },\n  \"message\": \"3 webhook event(s) deleted successfully\"\n}"}]},{"name":"Delete All Events (per instance)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/delete-all","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","delete-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Hard-deletes every webhook event row for the given integration instance. Requires `confirmation: \"YES\"`. Returns the total `deleted_count`. Use with caution — there is no soft-delete on `temu_webhook_events`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/webhook-events/delete-all","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","webhook-events","delete-all"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"deleted_count\": 117\n  },\n  \"message\": \"117 webhook event(s) deleted successfully\"\n}"}]},{"name":"List Parent After-Sales","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/parent-after-sales?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","parent-after-sales"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of TemuParentAfterSale records (returns + refunds) for the given Temu integration instance. Per-page default is 15. Uses Spatie QueryBuilder with grouped filter support — `filter[...]`, `sort=...`, and grouped advanced filters via `filter_groups` are all accepted. Default sort is `-updateTime`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/parent-after-sales?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","parent-after-sales"],"query":[{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 814,\n      \"integration_instance_id\": 1,\n      \"parentAfterSalesId\": \"PAS17234560019887421\",\n      \"parentOrderSn\": \"PO123456789012345\",\n      \"parentAfterSalesStatus\": 4,\n      \"parentAfterSalesStatusLabel\": \"Refund Completed\",\n      \"afterSalesStatusGroups\": [\n        {\n          \"value\": \"completed\",\n          \"label\": \"Completed\"\n        }\n      ],\n      \"afterSalesReasonCode\": 1002,\n      \"currency\": \"USD\",\n      \"refundAmount\": 1599,\n      \"refundAmountDecimal\": 15.99,\n      \"applyTime\": \"2026-06-12T17:42:11+00:00\",\n      \"updateTime\": \"2026-06-15T09:18:03+00:00\",\n      \"created_at\": \"2026-06-12T17:50:00+00:00\",\n      \"updated_at\": \"2026-06-15T09:18:30+00:00\"\n    },\n    {\n      \"id\": 813,\n      \"integration_instance_id\": 1,\n      \"parentAfterSalesId\": \"PAS17234551112233440\",\n      \"parentOrderSn\": \"PO998877665544332\",\n      \"parentAfterSalesStatus\": 2,\n      \"parentAfterSalesStatusLabel\": \"Under Review\",\n      \"afterSalesStatusGroups\": [\n        {\n          \"value\": \"in_progress\",\n          \"label\": \"In Progress\"\n        }\n      ],\n      \"afterSalesReasonCode\": 2003,\n      \"currency\": \"USD\",\n      \"refundAmount\": 2499,\n      \"refundAmountDecimal\": 24.99,\n      \"applyTime\": \"2026-06-14T03:11:55+00:00\",\n      \"updateTime\": \"2026-06-14T20:02:17+00:00\",\n      \"created_at\": \"2026-06-14T03:12:30+00:00\",\n      \"updated_at\": \"2026-06-14T20:02:30+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku-a.test/api/temu/1/parent-after-sales?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"https://sku-a.test/api/temu/1/parent-after-sales?page=4\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/parent-after-sales?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://sku-a.test/api/temu/1/parent-after-sales?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://sku-a.test/api/temu/1/parent-after-sales?page=2\",\n  \"path\": \"https://sku-a.test/api/temu/1/parent-after-sales\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 58\n}"}]},{"name":"Refresh Parent After-Sales","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/parent-after-sales/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","parent-after-sales","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Dispatches a background job to pull recent after-sales (returns/refunds) from the Temu API and upsert them into temu_parent_after_sales. Returns immediately with a tracked_job_log_id so the frontend can poll the job-tray composable. Body: { days_updated?: int } — defaults to 30 days when omitted.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"days_updated\": 30\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/parent-after-sales/refresh","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","parent-after-sales","refresh"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"queued\": true,\n    \"tracked_job_log_id\": 9421\n  },\n  \"message\": \"Returns refresh queued — track progress in the job tray\",\n  \"success\": true\n}"}]},{"name":"Query Pre-Start-Date Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders?created_at_min=2026-05-01","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2026-05-01","description":"REQUIRED. Lower bound for parent order creation. Must be strictly BEFORE the configured inventory_start_date.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Paginates through the Temu API (up to 10 pages of 100) for orders updated/created in the requested window, filters down to orders whose parentOrderTime is strictly before the configured inventory_start_date, and decorates each candidate with eligibility flags (eligible, already_imported, ineligible_reason). Returns 422 via the FormRequest if inventory_start_date is not set or if the date range is not strictly before it.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders?created_at_min=2026-05-01","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders"],"query":[{"key":"created_at_min","value":"2026-05-01","description":"REQUIRED. Lower bound for parent order creation. Must be strictly BEFORE the configured inventory_start_date.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"parentOrderSn\": \"PO111122223333444\",\n      \"parentOrderTime\": 1746115200000,\n      \"parent_order_created_at\": \"2026-05-02T00:00:00+00:00\",\n      \"parentOrderStatus\": 4,\n      \"orderAmount\": 4599,\n      \"currency\": \"USD\",\n      \"itemCount\": 2,\n      \"eligible\": true,\n      \"already_imported\": false,\n      \"ineligible_reason\": null\n    },\n    {\n      \"parentOrderSn\": \"PO555566667777888\",\n      \"parentOrderTime\": 1746374400000,\n      \"parent_order_created_at\": \"2026-05-05T00:00:00+00:00\",\n      \"parentOrderStatus\": 4,\n      \"orderAmount\": 1899,\n      \"currency\": \"USD\",\n      \"itemCount\": 1,\n      \"eligible\": false,\n      \"already_imported\": true,\n      \"ineligible_reason\": \"Order already exists locally\"\n    }\n  ],\n  \"inventory_start_date\": \"2026-06-01\",\n  \"meta\": {\n    \"total_queried\": 2,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 1\n  }\n}"}]},{"name":"Search Pre-Start-Date Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders/search?search_by=parent_order_sn&search_term=PO111122223333444","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"parent_order_sn","description":"REQUIRED. Only 'parent_order_sn' is supported today.","disabled":true},{"key":"search_term","value":"PO111122223333444","description":"REQUIRED. The Temu parent order SN to look up. 1-255 chars.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Calls the Temu order detail endpoint for a single parent_order_sn, filters out any result whose parentOrderTime is on/after the inventory_start_date, and decorates the result with eligibility flags. Empty `data` if the order is not found, not pre-start-date, or the upstream call errors. Returns 422 if inventory_start_date is not configured.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders/search?search_by=parent_order_sn&search_term=PO111122223333444","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders","search"],"query":[{"key":"search_by","value":"parent_order_sn","description":"REQUIRED. Only 'parent_order_sn' is supported today.","disabled":true},{"key":"search_term","value":"PO111122223333444","description":"REQUIRED. The Temu parent order SN to look up. 1-255 chars.","disabled":true}],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"parentOrderSn\": \"PO111122223333444\",\n      \"parentOrderTime\": 1746115200000,\n      \"parent_order_created_at\": \"2026-05-02T00:00:00+00:00\",\n      \"parentOrderStatus\": 4,\n      \"orderAmount\": 4599,\n      \"currency\": \"USD\",\n      \"itemCount\": 2,\n      \"eligible\": true,\n      \"already_imported\": false,\n      \"ineligible_reason\": null\n    }\n  ],\n  \"inventory_start_date\": \"2026-06-01\",\n  \"meta\": {\n    \"total_queried\": 1,\n    \"eligible_count\": 1,\n    \"already_imported_count\": 0\n  }\n}"}]},{"name":"Import Pre-Start-Date Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Import selected pre-start-date orders from Temu by their parent order SNs. Each order is fetched from the Temu API and written so it shows up in the local order list, flagged as a pre-start-date import.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBecause each order requires its own throttled Temu API call, the import runs asynchronously as a queued background job. The request returns immediately with a tracked job log id that can be polled to follow the import's progress.\n\n**Requires the local inventory_start_date to be set** — returns 422 otherwise.\n\n**Request Body:**\n- `parent_order_sns` (required, array of strings, 1-10,000 entries) — Temu parent order SNs to import.\n\n**Behavior:**\n- Runs as a background import — the request returns right away with a tracked job log id; the orders are fetched and stored asynchronously\n- Orders that already exist locally are flagged as pre-start-date imports instead of being re-imported\n\n**Response:**\n- `data.tracked_job_log_id` - id of the tracked job log; poll it to follow import progress\n- `message` - human-readable confirmation of how many orders are being imported","body":{"mode":"raw","raw":"{\n  \"parent_order_sns\": [\n    \"PO111122223333444\",\n    \"PO555566667777888\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/pre-start-date-orders/import","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","pre-start-date-orders","import"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Importing 2 pre-start-date orders.\"\n}"}]},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu","host":["{{baseUrl}}"],"path":["api","temu"]},"description":"Lists every Temu integration instance on the account. Returns all instances in a single response with no pagination, so callers can populate pickers or iterate instances without paging.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach instance includes its display name, the linked sales channel and store, the effective integration settings, and two convenience booleans (`has_warehouse_mappings`, `has_carrier_mappings`) indicating whether at least one Temu warehouse or carrier has been mapped to a local warehouse or shipping method — both mappings are prerequisites for submitting fulfillments to Temu.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu","host":["{{baseUrl}}"],"path":["api","temu"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"integration_name\": \"Temu\",\n      \"sales_channel_id\": 12,\n      \"store\": {\n        \"id\": 3,\n        \"name\": \"Main Store\"\n      },\n      \"has_warehouse_mappings\": true,\n      \"has_carrier_mappings\": true,\n      \"name\": \"Temu US\",\n      \"integration_settings\": {\n        \"start_date\": \"2025-01-01\",\n        \"store_id\": 3,\n        \"auto_link_products\": true,\n        \"auto_create_products\": false\n      },\n      \"is_automatic_sync_enabled\": true,\n      \"created_at\": \"2025-11-02T14:21:05.000000Z\",\n      \"updated_at\": \"2026-06-30T08:12:44.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu","host":["{{baseUrl}}"],"path":["api","temu"]},"description":"Creates a Temu integration instance directly from the supplied settings and credentials, and creates the linked sales channel record in the same transaction. Most production connections are established through the OAuth flow instead (`POST /api/temu/oauth/initialize` followed by `POST /api/temu/oauth/complete`), which populates the connection credentials automatically — use this endpoint when you already hold valid credentials.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n\n- `name` (string, required) — must be unique across all integration instances.\n- `integration_id` (integer, required) — id of the Temu integration definition.\n- `connection_settings` (object, optional) — `appKey`, `appSecret`, `url`, `accessToken`, `expiresAt` (all nullable strings).\n- `integration_settings` (object, required):\n  - `start_date` (string, required) — orders before this date are not imported.\n  - `store_id` (integer, required) — must reference an existing store.\n  - `auto_link_products` (boolean, default `true`), `auto_create_products` (boolean, default `false`).\n  - Optional accounting fields: `sales_nominal_code_id`, `cogs_nominal_code_id`, `shipping_revenue_nominal_code_id`, `shipping_refund_nominal_code_id`, `sales_returns_allowances_nominal_code_id` (nullable integers referencing nominal codes), `sync_sales_order_invoices_to_accounting`, `sync_sales_credit_to_accounting` (booleans).\n  - Optional `pricing` and `inventory` objects, `emailCustomers` (boolean), `proforma_marketplace_cost_percentage`, `proforma_payment_cost_percentage` (nullable numbers).\n- `is_automatic_sync_enabled` (boolean, default `false`).\n- `environment` (string, optional) — `production` or `sandbox`. On production servers the environment is always pinned to `production`.\n\nThe response returns the created instance. Note that the API normalizes all success status codes to 200.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Temu US\",\n  \"integration_id\": 42,\n  \"connection_settings\": {\n    \"appKey\": \"example-app-key\",\n    \"appSecret\": \"example-app-secret\",\n    \"url\": null,\n    \"accessToken\": \"example-access-token\",\n    \"expiresAt\": \"2026-12-31T00:00:00Z\"\n  },\n  \"integration_settings\": {\n    \"start_date\": \"2025-01-01\",\n    \"store_id\": 3,\n    \"auto_link_products\": true,\n    \"auto_create_products\": false\n  },\n  \"is_automatic_sync_enabled\": false,\n  \"environment\": \"production\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/temu","host":["{{baseUrl}}"],"path":["api","temu"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Temu US\",\n    \"integration_id\": 42,\n    \"connection_settings\": {\n      \"appKey\": \"example-app-key\",\n      \"appSecret\": \"example-app-secret\",\n      \"url\": null,\n      \"accessToken\": \"example-access-token\",\n      \"expiresAt\": \"2026-12-31T00:00:00Z\"\n    },\n    \"integration_settings\": {\n      \"start_date\": \"2025-01-01\",\n      \"store_id\": 3,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"environment\": \"production\",\n    \"created_at\": \"2026-07-06T10:15:02.000000Z\",\n    \"updated_at\": \"2026-07-06T10:15:02.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Returns a single Temu integration instance with its linked sales channel and store, effective settings, and the warehouse/carrier mapping indicators.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"integration_name\": \"Temu\",\n    \"sales_channel_id\": 12,\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Main Store\"\n    },\n    \"has_warehouse_mappings\": true,\n    \"has_carrier_mappings\": true,\n    \"name\": \"Temu US\",\n    \"integration_settings\": {\n      \"start_date\": \"2025-01-01\",\n      \"store_id\": 3,\n      \"auto_link_products\": true,\n      \"auto_create_products\": false\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2025-11-02T14:21:05.000000Z\",\n    \"updated_at\": \"2026-06-30T08:12:44.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Updates a Temu integration instance. All body fields are optional — only supply the fields you want to change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `name` (string) — new display name.\n- `connection_settings` (object) — `appKey`, `appSecret`, `url`, `accessToken`, `expiresAt`.\n- `integration_settings` (object) — same fields as on create (`start_date`, `store_id`, `auto_link_products`, `auto_create_products`, nominal code ids, `pricing`, `inventory`, `emailCustomers`, proforma cost percentages, accounting sync toggles). With PUT the supplied `integration_settings` object is merged against the stored settings at the top level; PATCH additionally deep-merges nested objects (JSON Merge Patch semantics), except that `inventory` lists are always replaced wholesale.\n- `is_automatic_sync_enabled` (boolean).\n\nSide effects when specific settings change:\n\n- `start_date` — the instance re-anchors its order sync window.\n- `store_id` — the linked sales channel is repointed to the new store.\n- `pricing.masterOfPrice.name` — a background job recalculates cached listing prices.\n- `inventory` — the channel inventory cache is invalidated and rebuilt.\n- Accounting sync toggles — linked accounting transactions are re-evaluated for sync eligibility.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Temu US (renamed)\",\n  \"integration_settings\": {\n    \"start_date\": \"2025-03-01\",\n    \"store_id\": 3,\n    \"auto_link_products\": true,\n    \"auto_create_products\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"integration_name\": \"Temu\",\n    \"sales_channel_id\": 12,\n    \"store\": {\n      \"id\": 3,\n      \"name\": \"Main Store\"\n    },\n    \"has_warehouse_mappings\": true,\n    \"has_carrier_mappings\": true,\n    \"name\": \"Temu US (renamed)\",\n    \"integration_settings\": {\n      \"start_date\": \"2025-03-01\",\n      \"store_id\": 3,\n      \"auto_link_products\": true,\n      \"auto_create_products\": true\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2025-11-02T14:21:05.000000Z\",\n    \"updated_at\": \"2026-07-06T10:22:41.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Deletes a Temu integration instance. The deletion runs as a queued background job because it cascades widely: the instance's imported orders and products, webhook subscriptions and stored webhook events, API logs, saved import mappings, and the linked sales channel are all removed.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe endpoint responds immediately; the actual removal completes shortly afterwards in the background.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"List Activity Log Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]},"description":"Returns the paginated change history recorded against a Temu integration instance, newest first. Each entry describes one recorded event (for example a settings update) with its structured `properties` payload and the name of the user who caused it (null for system-initiated changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupported filters:\n\n- `filter[event]` — event type, e.g. `created`, `updated`, `deleted`, `bulk_upsert`.\n- `filter[source]` — originating process recorded on the entry, e.g. `manual`.\n- `filter[batch_uuid]` — return only entries belonging to one bulk-operation batch.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/temu/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","temu",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90412,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"properties\": {\n        \"attributes\": {\n          \"is_automatic_sync_enabled\": true\n        },\n        \"old\": {\n          \"is_automatic_sync_enabled\": false\n        }\n      },\n      \"causer_name\": \"Jane Doe\",\n      \"created_at\": \"2026-06-28T15:42:10.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/temu/5/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"https://example.sku.io/api/temu/5/activity-log?page=4\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.sku.io/api/temu/5/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.sku.io/api/temu/5/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://example.sku.io/api/temu/5/activity-log?page=2\",\n  \"path\": \"https://example.sku.io/api/temu/5/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 58\n}"}]}]},{"name":"Square","item":[{"name":"List instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances","host":["{{baseUrl}}"],"path":["api","square","instances"]},"description":"List every Square integration instance for the current tenant.\n\n**Authentication:** Bearer token required."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/instances","host":["{{baseUrl}}"],"path":["api","square","instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Main Street Coffee Co.\",\n      \"environment\": \"sandbox\",\n      \"is_authorized\": true,\n      \"auth_method\": \"oauth\",\n      \"granted_scopes\": [\n        \"MERCHANT_PROFILE_READ\",\n        \"ITEMS_READ\",\n        \"ORDERS_READ\",\n        \"PAYMENTS_READ\",\n        \"CUSTOMERS_READ\",\n        \"INVENTORY_READ\",\n        \"PAYMENTS_WRITE\"\n      ],\n      \"payments_enabled\": true,\n      \"token_expires_at\": \"2026-08-07T18:24:11+00:00\",\n      \"merchant_id\": \"MLKV1XY23ABCD\",\n      \"order_import_start_date\": \"2026-06-01\",\n      \"default_return_warehouse_id\": 3,\n      \"order_sync_watermark_at\": \"2026-07-08T10:15:00+00:00\",\n      \"locations_count\": 2,\n      \"catalog_items_count\": 312,\n      \"orders_count\": 1284,\n      \"created_at\": \"2026-07-01T13:50:16+00:00\",\n      \"updated_at\": \"2026-07-08T10:15:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/instances","host":["{{baseUrl}}"],"path":["api","square","instances"]},"description":"Create a new Square integration instance. For v1, provide a personal access token from the Square Developer Console; OAuth is pending business verification.\n\n**Body fields:**\n- `name` (required) — instance display name\n- `environment` (optional) — `sandbox` | `production`, default `sandbox`\n- `access_token` (optional) — personal access token; if omitted, falls back to the tenant's default sandbox token from Secrets Manager\n- `auth_method` (optional) — `manual` | `oauth`\n- `merchant_id` (optional)\n- `order_import_start_date` (optional, YYYY-MM-DD)\n- `default_return_warehouse_id` (optional, integer)","body":{"mode":"raw","raw":"{\n  \"name\": \"My Square Sandbox\",\n  \"environment\": \"sandbox\",\n  \"access_token\": \"EAAAlxxV7_3x0NGlDRTxU1n2nPuBW9T1fN74XVOfBUJcZ8CMz0LSfj2UdNd-zG0a\",\n  \"auth_method\": \"manual\",\n  \"merchant_id\": \"MLXX0EXAMPLE\",\n  \"order_import_start_date\": \"2026-06-01\",\n  \"default_return_warehouse_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/instances","host":["{{baseUrl}}"],"path":["api","square","instances"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Main Street Coffee Co.\",\n    \"environment\": \"sandbox\",\n    \"is_authorized\": true,\n    \"auth_method\": \"manual\",\n    \"granted_scopes\": [],\n    \"payments_enabled\": false,\n    \"token_expires_at\": null,\n    \"merchant_id\": \"MLKV1XY23ABCD\",\n    \"order_import_start_date\": \"2026-06-01\",\n    \"default_return_warehouse_id\": 3,\n    \"order_sync_watermark_at\": \"2026-07-08T10:15:00+00:00\",\n    \"locations_count\": 0,\n    \"catalog_items_count\": 0,\n    \"orders_count\": 0,\n    \"created_at\": \"2026-07-01T13:50:16+00:00\",\n    \"updated_at\": \"2026-07-08T10:15:00+00:00\"\n  }\n}"}]},{"name":"Get instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Fetch a single Square integration instance by ID."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Main Street Coffee Co.\",\n    \"environment\": \"sandbox\",\n    \"is_authorized\": true,\n    \"auth_method\": \"oauth\",\n    \"granted_scopes\": [\n      \"MERCHANT_PROFILE_READ\",\n      \"ITEMS_READ\",\n      \"ORDERS_READ\",\n      \"PAYMENTS_READ\",\n      \"CUSTOMERS_READ\",\n      \"INVENTORY_READ\",\n      \"PAYMENTS_WRITE\"\n    ],\n    \"payments_enabled\": true,\n    \"token_expires_at\": \"2026-08-07T18:24:11+00:00\",\n    \"merchant_id\": \"MLKV1XY23ABCD\",\n    \"order_import_start_date\": \"2026-06-01\",\n    \"default_return_warehouse_id\": 3,\n    \"order_sync_watermark_at\": \"2026-07-08T10:15:00+00:00\",\n    \"locations_count\": 2,\n    \"catalog_items_count\": 312,\n    \"orders_count\": 1284,\n    \"created_at\": \"2026-07-01T13:50:16+00:00\",\n    \"updated_at\": \"2026-07-08T10:15:00+00:00\"\n  }\n}"}]},{"name":"Update instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Update an existing instance. All fields are optional — only fields present in the body are changed.\n\n`payments_enabled` (boolean, optional) — toggles register card processing for this account. Auto-set to true when an OAuth grant includes PAYMENTS_WRITE.","body":{"mode":"raw","raw":"{\n  \"name\": \"Renamed Square Instance\",\n  \"order_import_start_date\": \"2026-07-01\",\n  \"payments_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Main Street Coffee Co.\",\n    \"environment\": \"sandbox\",\n    \"is_authorized\": true,\n    \"auth_method\": \"oauth\",\n    \"granted_scopes\": [\n      \"MERCHANT_PROFILE_READ\",\n      \"ITEMS_READ\",\n      \"ORDERS_READ\",\n      \"PAYMENTS_READ\",\n      \"CUSTOMERS_READ\",\n      \"INVENTORY_READ\",\n      \"PAYMENTS_WRITE\"\n    ],\n    \"payments_enabled\": true,\n    \"token_expires_at\": \"2026-08-07T18:24:11+00:00\",\n    \"merchant_id\": \"MLKV1XY23ABCD\",\n    \"order_import_start_date\": \"2026-06-01\",\n    \"default_return_warehouse_id\": 3,\n    \"order_sync_watermark_at\": \"2026-07-08T10:15:00+00:00\",\n    \"locations_count\": 2,\n    \"catalog_items_count\": 312,\n    \"orders_count\": 1284,\n    \"created_at\": \"2026-07-01T13:50:16+00:00\",\n    \"updated_at\": \"2026-07-08T10:15:00+00:00\"\n  }\n}"}]},{"name":"Delete instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Delete an integration instance. Also removes all synced Square orders, catalog items, locations, and webhook events for this instance. Linked SKU sales orders themselves are preserved."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Deleted\"\n}"}]},{"name":"Test connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","test-connection"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Call `/v2/merchants/me` on Square using the stored access token. Latches the returned `merchant_id` onto the instance if it isn't already set."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/test-connection","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","test-connection"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"ok\": true,\n  \"message\": \"Connection to Square verified.\",\n  \"merchant\": {\n    \"id\": \"MLXX0EXAMPLE\",\n    \"business_name\": \"Example Co\",\n    \"country\": \"US\"\n  }\n}"}]},{"name":"Sync (locations + catalog + orders)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/sync","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","sync"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Dispatches a background sync job for the instance. Returns immediately with a tracked_job_log_id.\n\n**Body:**\n- `scope` (optional) — `all` (default), `locations`, `catalog`, or `orders`\n- `start_at` (optional, ISO 8601) — override the watermark for the orders phase","body":{"mode":"raw","raw":"{\n  \"scope\": \"all\",\n  \"start_at\": \"2026-06-01T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/sync","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","sync"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4211\n  },\n  \"message\": \"Square all sync queued.\"\n}"}]},{"name":"Get OAuth authorize URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/oauth/authorize-url","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","oauth","authorize-url"],"variable":[{"key":"squareIntegrationInstance","value":"1","description":"The square integration instance ID."}]},"description":"Builds the Square OAuth authorization URL for this instance. Redirect the merchant's browser to the returned `authorization_url`; after they approve, Square redirects back and the connection is stored automatically with the granted scopes.\n\nThe requested scope set always includes the standard sales-channel read scopes plus any scopes the instance was already granted (Square replaces the grant with exactly what is requested, so re-authorizing never narrows an existing grant).\n\nPass `capabilities=payments` to additionally request `PAYMENTS_READ`/`PAYMENTS_WRITE` so the account can process register card payments. Use the same parameter to widen an existing channel-only connection (incremental re-consent).\n\nWhen payment scopes are granted, `payments_enabled` is set on the instance automatically."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/oauth/authorize-url","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","oauth","authorize-url"],"variable":[{"key":"squareIntegrationInstance","value":"1","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorization_url\": \"https://connect.squareupsandbox.com/oauth2/authorize?client_id=sq0idb-XXXX&scope=MERCHANT_PROFILE_READ+ITEMS_READ+ORDERS_READ+PAYMENTS_READ+CUSTOMERS_READ+INVENTORY_READ&session=false&state=tenant_abc123\",\n    \"requested_scopes\": [\n      \"MERCHANT_PROFILE_READ\",\n      \"ITEMS_READ\",\n      \"ORDERS_READ\",\n      \"PAYMENTS_READ\",\n      \"CUSTOMERS_READ\",\n      \"INVENTORY_READ\"\n    ]\n  }\n}"}]},{"name":"List locations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/locations","host":["{{baseUrl}}"],"path":["api","square","locations"]},"description":"Paginated list of Square locations across all instances (or filter by `filter[integration_instance_id]`).\n\n**Filters:** `filter[integration_instance_id]`, `filter[status]` (ACTIVE/INACTIVE), `filter[search]` (name / square_location_id / city), `filter[mapped]` (true/false).\n\n**Allowed sorts:** `id`, `name`, `status`, `created_at`, `updated_at`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/locations","host":["{{baseUrl}}"],"path":["api","square","locations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"integration_instance_id\": 1,\n      \"square_location_id\": \"L2XXXXX7A\",\n      \"name\": \"Main Street Store\",\n      \"status\": \"ACTIVE\",\n      \"type\": \"PHYSICAL\",\n      \"address\": {\n        \"address1\": \"123 Main St\",\n        \"city\": \"Denver\",\n        \"province\": \"CO\",\n        \"zip\": \"80202\",\n        \"country_code\": \"US\"\n      },\n      \"phone\": \"+1-555-123-4567\",\n      \"currency_code\": \"USD\",\n      \"timezone\": \"America/Denver\",\n      \"warehouse_id\": 5,\n      \"warehouse\": {\n        \"id\": 5,\n        \"name\": \"Main Warehouse\"\n      },\n      \"created_at\": \"2026-07-01T10:05:00.000000Z\",\n      \"updated_at\": \"2026-07-01T10:05:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Update location mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/locations/{squareLocation}","host":["{{baseUrl}}"],"path":["api","square","locations",":squareLocation"],"variable":[{"key":"squareLocation","value":"","description":"The square location ID."}]},"description":"Point a Square location at a SKU warehouse. Pass `warehouse_id: null` to unmap.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/square/locations/{squareLocation}","host":["{{baseUrl}}"],"path":["api","square","locations",":squareLocation"],"variable":[{"key":"squareLocation","value":"","description":"The square location ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"integration_instance_id\": 1,\n    \"square_location_id\": \"L2XXXXX7A\",\n    \"name\": \"Main Street Store\",\n    \"status\": \"ACTIVE\",\n    \"type\": \"PHYSICAL\",\n    \"address\": {\n      \"address1\": \"123 Main St\",\n      \"city\": \"Denver\",\n      \"province\": \"CO\",\n      \"zip\": \"80202\",\n      \"country_code\": \"US\"\n    },\n    \"phone\": \"+1-555-123-4567\",\n    \"currency_code\": \"USD\",\n    \"timezone\": \"America/Denver\",\n    \"warehouse_id\": 5,\n    \"warehouse\": {\n      \"id\": 5,\n      \"name\": \"Main Warehouse\"\n    },\n    \"created_at\": \"2026-07-01T10:05:00.000000Z\",\n    \"updated_at\": \"2026-07-01T10:05:00.000000Z\"\n  }\n}"}]},{"name":"Sync locations","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/locations/sync","host":["{{baseUrl}}"],"path":["api","square","locations","sync"]},"description":"Synchronously call Square's `/v2/locations` and upsert `square_locations` rows.\n\n`integration_instance_id` (integer, required) — returns 422 when missing.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/locations/sync","host":["{{baseUrl}}"],"path":["api","square","locations","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Synced 3 location(s) from Square.\",\n  \"count\": 3\n}"}]},{"name":"List catalog items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/catalog","host":["{{baseUrl}}"],"path":["api","square","catalog"]},"description":"Paginated list of Square catalog variations across all instances.\n\n**Filters:** `filter[integration_instance_id]`, `filter[type]`, `filter[is_deleted]`, `filter[mapped]` (true/false), `filter[search]` (name / sku / square_catalog_object_id).\n\n**Allowed sorts:** `id`, `name`, `sku`, `price`, `created_at`, `updated_at`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/catalog","host":["{{baseUrl}}"],"path":["api","square","catalog"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"integration_instance_id\": 1,\n      \"square_catalog_object_id\": \"AAAA00000000000BBBBBBBB\",\n      \"square_variation_id\": \"AAAA00000000000BBBBBBBB\",\n      \"square_parent_id\": \"PPPP00000000000CCCCCCCC\",\n      \"type\": \"ITEM_VARIATION\",\n      \"sku\": \"TEE-BLK-M\",\n      \"name\": \"Cotton T-Shirt - Medium Black\",\n      \"description\": \"100% cotton, unisex fit\",\n      \"category\": \"Apparel\",\n      \"price\": 24.99,\n      \"currency_code\": \"USD\",\n      \"is_deleted\": false,\n      \"square_updated_at\": \"2026-06-28T14:12:33+00:00\",\n      \"product_id\": 987,\n      \"product\": {\n        \"id\": 987,\n        \"sku\": \"TEE-BLK-M\",\n        \"name\": \"Cotton T-Shirt - M/Black\",\n        \"reference\": \"TEE-BLK-M\",\n        \"link_route\": \"/products/987\"\n      },\n      \"created_at\": \"2026-07-01T10:10:00.000000Z\",\n      \"updated_at\": \"2026-07-01T10:10:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get latest catalog sync info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/catalog/latest-sync-info?integration_instance_id=1","host":["{{baseUrl}}"],"path":["api","square","catalog","latest-sync-info"],"query":[{"key":"integration_instance_id","value":"1","description":"The Square integration instance to inspect (required).","disabled":true}]},"description":"Latest-sync summary for an instance's catalog: the most recently updated item plus total / mapped / unmapped product counts. Useful before queuing a refresh to decide whether a `since_latest` sync is sufficient.\n\nRoute name: square.catalog.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/catalog/latest-sync-info?integration_instance_id=1","host":["{{baseUrl}}"],"path":["api","square","catalog","latest-sync-info"],"query":[{"key":"integration_instance_id","value":"1","description":"The Square integration instance to inspect (required).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Blue Ceramic Mug - Large\",\n    \"latest_product_date\": \"2026-07-06T18:24:11+00:00\",\n    \"total_products\": 312,\n    \"mapped_products\": 268,\n    \"unmapped_products\": 44\n  }\n}"}]},{"name":"Update catalog mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/catalog/{squareCatalogItem}","host":["{{baseUrl}}"],"path":["api","square","catalog",":squareCatalogItem"],"variable":[{"key":"squareCatalogItem","value":"","description":"The square catalog item ID."}]},"description":"Point a Square catalog variation at a SKU Product. Pass `product_id: null` to unmap.","body":{"mode":"raw","raw":"{\n  \"product_id\": 987\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/square/catalog/{squareCatalogItem}","host":["{{baseUrl}}"],"path":["api","square","catalog",":squareCatalogItem"],"variable":[{"key":"squareCatalogItem","value":"","description":"The square catalog item ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 1,\n    \"square_catalog_object_id\": \"AAAA00000000000BBBBBBBB\",\n    \"square_variation_id\": \"AAAA00000000000BBBBBBBB\",\n    \"square_parent_id\": \"PPPP00000000000CCCCCCCC\",\n    \"type\": \"ITEM_VARIATION\",\n    \"sku\": \"TEE-BLK-M\",\n    \"name\": \"Cotton T-Shirt - Medium Black\",\n    \"description\": \"100% cotton, unisex fit\",\n    \"category\": \"Apparel\",\n    \"price\": 24.99,\n    \"currency_code\": \"USD\",\n    \"is_deleted\": false,\n    \"square_updated_at\": \"2026-06-28T14:12:33+00:00\",\n    \"product_id\": 987,\n    \"product\": {\n      \"id\": 987,\n      \"sku\": \"TEE-BLK-M\",\n      \"name\": \"Cotton T-Shirt - M/Black\",\n      \"reference\": \"TEE-BLK-M\",\n      \"link_route\": \"/products/987\"\n    },\n    \"created_at\": \"2026-07-01T10:10:00.000000Z\",\n    \"updated_at\": \"2026-07-01T10:10:00.000000Z\"\n  }\n}"}]},{"name":"Sync catalog","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/catalog/sync","host":["{{baseUrl}}"],"path":["api","square","catalog","sync"]},"description":"Synchronously call Square's `/v2/catalog/list` (cursor-paginated) and upsert `square_catalog_items` rows.\n\n`integration_instance_id` (integer, required) — returns 422 when missing.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/catalog/sync","host":["{{baseUrl}}"],"path":["api","square","catalog","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Synced 214 catalog variation(s) from Square.\",\n  \"count\": 214\n}"}]},{"name":"List orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/orders","host":["{{baseUrl}}"],"path":["api","square","orders"]},"description":"Paginated list of Square orders across all instances.\n\n**Filters:** `filter[integration_instance_id]`, `filter[state]` (OPEN/COMPLETED/CANCELED), `filter[channel_source]` (pos/online/marketplace/unknown), `filter[is_pos]` (true/false), `filter[sync_status]` (pending/synced/failed), `filter[search]` (square_order_id / customer_email / customer_name), `filter[date_from]` / `filter[date_to]` (ISO 8601).\n\n**Allowed sorts:** `id`, `square_created_at`, `square_updated_at`, `total`, `state`, `sync_status`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/orders","host":["{{baseUrl}}"],"path":["api","square","orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 128,\n      \"integration_instance_id\": 1,\n      \"square_order_id\": \"ORDER123XYZ\",\n      \"square_location_id\": \"L2XXXXX7A\",\n      \"state\": \"COMPLETED\",\n      \"source_name\": \"Point of Sale\",\n      \"channel_source\": \"pos\",\n      \"is_pos\": true,\n      \"customer_id\": null,\n      \"customer_email\": \"walk.in@example.com\",\n      \"customer_name\": null,\n      \"subtotal\": 49.98,\n      \"tax_total\": 4,\n      \"discount_total\": 0,\n      \"service_charge_total\": 0,\n      \"tip_total\": 5,\n      \"total\": 58.98,\n      \"currency_code\": \"USD\",\n      \"square_created_at\": \"2026-07-01T15:23:00+00:00\",\n      \"square_updated_at\": \"2026-07-01T15:24:12+00:00\",\n      \"closed_at\": \"2026-07-01T15:24:12+00:00\",\n      \"fulfillment_state\": \"COMPLETED\",\n      \"sync_status\": \"synced\",\n      \"sync_error\": null,\n      \"last_synced_at\": \"2026-07-01T15:25:00+00:00\",\n      \"sales_order_id\": 5501,\n      \"sales_order\": {\n        \"id\": 5501,\n        \"sales_order_number\": \"ORDER123XYZ\",\n        \"link_route\": \"/orders/5501\"\n      },\n      \"line_items\": [\n        {\n          \"id\": 501,\n          \"uid\": \"uid-line-1\",\n          \"sku\": \"TEE-BLK-M\",\n          \"name\": \"Cotton T-Shirt\",\n          \"variation_name\": \"Medium / Black\",\n          \"quantity\": 2,\n          \"base_price\": 24.99,\n          \"gross_sales\": 49.98,\n          \"total_tax\": 4,\n          \"total_discount\": 0,\n          \"total\": 58.98,\n          \"currency_code\": \"USD\",\n          \"square_catalog_object_id\": \"AAAA00000000000BBBBBBBB\"\n        }\n      ],\n      \"created_at\": \"2026-07-01T15:23:05.000000Z\",\n      \"updated_at\": \"2026-07-01T15:25:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 25,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get latest order sync info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/orders/latest-sync-info?integration_instance_id=1","host":["{{baseUrl}}"],"path":["api","square","orders","latest-sync-info"],"query":[{"key":"integration_instance_id","value":"1","description":"The Square integration instance to inspect (required).","disabled":true}]},"description":"Latest-sync summary for an instance's orders: the most recently updated synced order and the total number of orders stored. Useful before queuing a refresh to decide whether a `since_latest` sync is sufficient.\n\nRoute name: square.orders.latest-sync-info"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/orders/latest-sync-info?integration_instance_id=1","host":["{{baseUrl}}"],"path":["api","square","orders","latest-sync-info"],"query":[{"key":"integration_instance_id","value":"1","description":"The Square integration instance to inspect (required).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_id\": \"CAISENgvlJ6jLWAzERDzjyHVybY\",\n    \"latest_order_date\": \"2026-07-06T18:24:11+00:00\",\n    \"total_orders\": 1284\n  }\n}"}]},{"name":"Get order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/orders/{squareOrder}","host":["{{baseUrl}}"],"path":["api","square","orders",":squareOrder"],"variable":[{"key":"squareOrder","value":"","description":"The square order ID."}]},"description":"Fetch one Square order with its line items and linked SKU sales order.\n\nWhen the order has been promoted, `sales_order` includes the SKU sales order's order/fulfillment/payment statuses, a `link_route` to its detail page, and its `fulfillments` (tracking number, warehouse, shipping method, and fulfilled line items). `raw_data` (the full Square API payload) is only included on this single-order endpoint, not on the list."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/orders/{squareOrder}","host":["{{baseUrl}}"],"path":["api","square","orders",":squareOrder"],"variable":[{"key":"squareOrder","value":"","description":"The square order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 128,\n    \"integration_instance_id\": 1,\n    \"square_order_id\": \"CAISENgvlJ6jLWAzERDzjyHVybY\",\n    \"square_location_id\": \"L2XXXXX7A\",\n    \"state\": \"COMPLETED\",\n    \"source_name\": \"Point of Sale\",\n    \"channel_source\": \"pos\",\n    \"is_pos\": true,\n    \"customer_id\": \"8FMBVGB0Q3GVWMYE86HB4X8H70\",\n    \"customer_email\": \"jane@example.com\",\n    \"customer_name\": \"Jane Doe\",\n    \"subtotal\": 45,\n    \"tax_total\": 3.94,\n    \"discount_total\": 0,\n    \"service_charge_total\": 0,\n    \"tip_total\": 5,\n    \"total\": 53.94,\n    \"currency_code\": \"USD\",\n    \"square_created_at\": \"2026-07-05T14:03:22+00:00\",\n    \"square_updated_at\": \"2026-07-05T14:05:10+00:00\",\n    \"closed_at\": \"2026-07-05T14:05:10+00:00\",\n    \"fulfillment_state\": \"COMPLETED\",\n    \"sync_status\": \"synced\",\n    \"sync_error\": null,\n    \"last_synced_at\": \"2026-07-06T18:24:11+00:00\",\n    \"sales_order_id\": 918,\n    \"sales_order\": {\n      \"id\": 918,\n      \"sales_order_number\": \"SO-000918\",\n      \"order_status\": \"completed\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"payment_status\": \"paid\",\n      \"link_route\": \"/orders/sales-orders/918\",\n      \"fulfillments\": [\n        {\n          \"id\": 501,\n          \"status\": \"fulfilled\",\n          \"fulfillment_type\": \"shipping\",\n          \"tracking_number\": \"1Z999AA10123456784\",\n          \"cost\": 7.25,\n          \"fulfilled_at\": \"2026-07-05T16:10:00.000000Z\",\n          \"submitted_to_sales_channel_at\": null,\n          \"warehouse\": {\n            \"id\": 3,\n            \"name\": \"Main Warehouse\"\n          },\n          \"shipping_method\": {\n            \"id\": 2,\n            \"name\": \"UPS Ground\"\n          },\n          \"line_items\": [\n            {\n              \"id\": 1203,\n              \"quantity\": 2,\n              \"product_name\": \"Blue Ceramic Mug - Large\",\n              \"sku\": \"MUG-BLU-L\"\n            }\n          ]\n        }\n      ]\n    },\n    \"line_items\": [\n      {\n        \"id\": 77,\n        \"uid\": \"8CBRDDGRrM6cSf3HpiUmwB\",\n        \"sku\": \"MUG-BLU-L\",\n        \"name\": \"Blue Ceramic Mug\",\n        \"variation_name\": \"Large\",\n        \"quantity\": 2,\n        \"base_price\": 22.5,\n        \"gross_sales\": 45,\n        \"total_tax\": 3.94,\n        \"total_discount\": 0,\n        \"total\": 48.94,\n        \"currency_code\": \"USD\",\n        \"square_catalog_object_id\": \"W62UWFY35CWMYGVWK6TWJDNI\"\n      }\n    ],\n    \"raw_data\": {\n      \"id\": \"CAISENgvlJ6jLWAzERDzjyHVybY\",\n      \"location_id\": \"L2XXXXX7A\",\n      \"state\": \"COMPLETED\"\n    },\n    \"created_at\": \"2026-07-05T14:06:00+00:00\",\n    \"updated_at\": \"2026-07-06T18:24:11+00:00\"\n  }\n}"}]},{"name":"Sync orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/orders/sync","host":["{{baseUrl}}"],"path":["api","square","orders","sync"]},"description":"Queues a background sync of Square orders for the instance, then promotes new orders to SKU sales orders. Returns a tracked job log id that can be used to follow progress.\n\n`mode` is optional: `since_latest` (default) resumes from the persisted sync watermark; `all` re-syncs from the instance's order import start date. `date_from` (optional, date) overrides the window start.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 1,\n  \"mode\": \"since_latest\",\n  \"date_from\": \"2026-07-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/orders/sync","host":["{{baseUrl}}"],"path":["api","square","orders","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 3151\n  },\n  \"message\": \"Square orders sync started.\"\n}"}]},{"name":"Submit fulfillments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/square/orders/submit-fulfillments","host":["{{baseUrl}}"],"path":["api","square","orders","submit-fulfillments"]},"description":"Push pending fulfillment tracking back to Square for online orders shipped in SKU. Each eligible fulfillment updates the Square order's shipment fulfillment to COMPLETED with carrier, tracking number, tracking URL, and shipped-at time.\n\n`integration_instance_id` (integer, required) — the Square connection to submit for.\n`fulfillment_ids` (array of integers, optional) — submit only these fulfillments; omit to sweep every eligible pending fulfillment on the connection.\n\nOnly fulfillments that are fulfilled, carry a tracking number, are not pickups, and have not already been submitted are pushed. Point-of-sale orders are never pushed — they are handed over at the register.\n\nPending fulfillments are also submitted automatically every 10 minutes. Requires the ORDERS_WRITE OAuth scope.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 1,\n  \"fulfillment_ids\": [\n    12,\n    13\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/orders/submit-fulfillments","host":["{{baseUrl}}"],"path":["api","square","orders","submit-fulfillments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 fulfillment(s) submitted to Square.\",\n  \"submitted\": 2,\n  \"skipped\": 0,\n  \"failed\": 0,\n  \"errors\": []\n}"}]},{"name":"Receive webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/square","host":["{{baseUrl}}"],"path":["api","webhooks","square"]},"description":"**Public endpoint** — no bearer required. Square posts here for every subscribed event.\n\n**Required header:** `X-Square-HmacSha256-Signature` (Square signs `notification_url + raw_body` with the subscription's signature key; verified per-instance).\n\n**Handled event families:** `order.*` (refetches the order and promotes), `refund.*` (recorded in v1; sales-credit reconciliation lands in a follow-up), `inventory.*` / `catalog.*` (marked ignored — served by the scheduled sync commands).","body":{"mode":"raw","raw":"{\n  \"merchant_id\": \"MLXX0EXAMPLE\",\n  \"type\": \"order.updated\",\n  \"event_id\": \"5e77f748-3aaf-4d05-8b16-1a3c9d3b3b41\",\n  \"created_at\": \"2026-07-01T15:24:12Z\",\n  \"data\": {\n    \"type\": \"order\",\n    \"id\": \"ORDER123XYZ\",\n    \"object\": {\n      \"order_updated\": {\n        \"order_id\": \"ORDER123XYZ\",\n        \"state\": \"COMPLETED\"\n      }\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhooks/square","host":["{{baseUrl}}"],"path":["api","webhooks","square"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"accepted\",\n  \"event_id\": 942\n}"}]},{"name":"List payouts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/payouts","host":["{{baseUrl}}"],"path":["api","square","payouts"]},"description":"List Square payouts (deposit/settlement batches) — the money Square transferred to the seller's bank account. Each payout aggregates the charges, refunds, and fees settled in that deposit; use it to reconcile channel revenue against bank deposits.\n\nAmounts are integer minor units (cents).\n\nRequires the PAYOUTS_READ OAuth scope on the connected Square account."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/payouts","host":["{{baseUrl}}"],"path":["api","square","payouts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 14,\n      \"integration_instance_id\": 3,\n      \"square_payout_id\": \"po_a1b2c3d4-5678-90ab-cdef-111213141516\",\n      \"square_location_id\": \"L3PKY0ZZZ8Q1D\",\n      \"status\": \"PAID\",\n      \"type\": \"BATCH\",\n      \"amount\": 45000,\n      \"currency_code\": \"USD\",\n      \"arrival_date\": \"2026-07-09\",\n      \"end_to_end_id\": \"T2X9AB34CD\",\n      \"square_created_at\": \"2026-07-08T04:10:00+00:00\",\n      \"square_updated_at\": \"2026-07-08T09:30:00+00:00\",\n      \"entries_synced_at\": \"2026-07-08T10:00:12+00:00\",\n      \"entries_count\": 38,\n      \"created_at\": \"2026-07-08T10:00:11+00:00\",\n      \"updated_at\": \"2026-07-08T10:00:12+00:00\",\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"Main Street Coffee Co.\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku1.test/api/square/payouts?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku1.test/api/square/payouts?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku1.test/api/square/payouts\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get payout","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/payouts/{squarePayout}","host":["{{baseUrl}}"],"path":["api","square","payouts",":squarePayout"],"variable":[{"key":"squarePayout","value":"","description":"The square payout ID."}]},"description":"Get a single Square payout, including its entry count and the connected Square account.\n\nAmounts are integer minor units (cents)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/payouts/{squarePayout}","host":["{{baseUrl}}"],"path":["api","square","payouts",":squarePayout"],"variable":[{"key":"squarePayout","value":"","description":"The square payout ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 14,\n    \"integration_instance_id\": 3,\n    \"square_payout_id\": \"po_a1b2c3d4-5678-90ab-cdef-111213141516\",\n    \"square_location_id\": \"L3PKY0ZZZ8Q1D\",\n    \"status\": \"PAID\",\n    \"type\": \"BATCH\",\n    \"amount\": 45000,\n    \"currency_code\": \"USD\",\n    \"arrival_date\": \"2026-07-09\",\n    \"end_to_end_id\": \"T2X9AB34CD\",\n    \"square_created_at\": \"2026-07-08T04:10:00+00:00\",\n    \"square_updated_at\": \"2026-07-08T09:30:00+00:00\",\n    \"entries_synced_at\": \"2026-07-08T10:00:12+00:00\",\n    \"entries_count\": 38,\n    \"created_at\": \"2026-07-08T10:00:11+00:00\",\n    \"updated_at\": \"2026-07-08T10:00:12+00:00\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"Main Street Coffee Co.\"\n    }\n  }\n}"}]},{"name":"List payout entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/square/payouts/{squarePayout}/entries","host":["{{baseUrl}}"],"path":["api","square","payouts",":squarePayout","entries"],"variable":[{"key":"squarePayout","value":"","description":"The square payout ID."}]},"description":"List the individual entries of one payout — each charge, refund, fee, or adjustment that was settled in the deposit, with gross/fee/net amounts and the Square payment it relates to.\n\nAmounts are integer minor units (cents)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/square/payouts/{squarePayout}/entries","host":["{{baseUrl}}"],"path":["api","square","payouts",":squarePayout","entries"],"variable":[{"key":"squarePayout","value":"","description":"The square payout ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 301,\n      \"square_payout_id\": 14,\n      \"square_payout_entry_id\": \"poe_9f8e7d6c-5432-10fe-dcba-212223242526\",\n      \"type\": \"CHARGE\",\n      \"effective_at\": \"2026-07-08T03:22:41+00:00\",\n      \"gross_amount\": 2500,\n      \"fee_amount\": 73,\n      \"net_amount\": 2427,\n      \"currency_code\": \"USD\",\n      \"square_payment_id\": \"pmt_1A2B3C4D5E6F\",\n      \"square_refund_id\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku1.test/api/square/payouts?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku1.test/api/square/payouts?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku1.test/api/square/payouts\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Sync payouts","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","payouts","sync"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]},"description":"Start a background sync of payouts (and their entries) from Square for this connection. Payouts download per location from the last sync watermark; entries are refetched only when a payout changed. Returns a tracked job id for monitoring progress.\n\nPayouts also refresh automatically every hour."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/square/instances/{squareIntegrationInstance}/payouts/sync","host":["{{baseUrl}}"],"path":["api","square","instances",":squareIntegrationInstance","payouts","sync"],"variable":[{"key":"squareIntegrationInstance","value":"","description":"The square integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 981\n  },\n  \"message\": \"Square payouts sync started.\"\n}"}]}]},{"name":"Magento 1","item":[{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances","host":["{{baseUrl}}"],"path":["api","magento1","instances"]},"description":"Lists every Magento 1 integration instance on the account. Returns all instances in a single response with no pagination, so callers can populate pickers or iterate instances without paging.\n\nEach instance includes its display name, connection status, the store base URL and API user. The SOAP API key is never returned — the `api_key_set` boolean indicates only whether one is stored. Each instance also reports the import start date, the inventory push rules, mirrored order and product counts, and the timestamps of the most recent order and product syncs (derived from the newest mirrored record, since Magento 1 has no sync cursor).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances","host":["{{baseUrl}}"],"path":["api","magento1","instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Acme Storefront\",\n      \"is_configured\": true,\n      \"connection_status\": \"Ready\",\n      \"is_automatic_sync_enabled\": true,\n      \"store_base_url\": \"https://store.example.com\",\n      \"api_user\": \"sku_integration\",\n      \"api_key_set\": true,\n      \"start_date\": \"2026-01-01\",\n      \"inventory\": {\n        \"masterOfStock\": \"sku.io\",\n        \"inventoryModificationRules\": {\n          \"maxRuleType\": \"None\",\n          \"minRuleType\": \"None\"\n        },\n        \"selectedWarehouses\": [\n          1,\n          4\n        ]\n      },\n      \"last_orders_sync\": \"2026-07-07T18:42:10+00:00\",\n      \"last_products_sync\": \"2026-07-07T18:40:03+00:00\",\n      \"orders_count\": 128,\n      \"products_count\": 342,\n      \"created_at\": \"2026-06-15T09:12:00+00:00\",\n      \"updated_at\": \"2026-07-07T18:42:10+00:00\",\n      \"refunds\": {\n        \"allow_refunds_from_sku\": false\n      }\n    }\n  ]\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances","host":["{{baseUrl}}"],"path":["api","magento1","instances"]},"description":"Creates a Magento 1 integration instance from the supplied SOAP credentials and settings, and creates the linked sales channel record in the same request.\n\nRequest body fields:\n\n- `name` (string, required) — display name for the connection.\n- `connection_settings` (object, required):\n  - `store_base_url` (string, required) — the store's base URL (any trailing slash is stripped).\n  - `api_user` (string, required) — the SOAP API user name.\n  - `api_key` (string, required) — the SOAP API key. Stored server-side and never returned.\n- `start_date` (string, optional) — date (`YYYY-MM-DD`); orders placed before it are not imported.\n- `inventory` (object, optional):\n  - `masterOfStock` (string) — `sku.io` or `Neither`.\n  - `inventoryModificationRules` (object) — `maxRuleType`, `minRuleType` (strings) with optional `maxRuleTypeValue`, `minRuleTypeValue`, `subtractBufferStock` (numbers).\n  - `selectedWarehouses` (array of integers) — ids of warehouses whose stock feeds the store.\n\nThe response returns the created instance. Note that the API normalizes success status codes to 200.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme Storefront\",\n  \"connection_settings\": {\n    \"store_base_url\": \"https://store.example.com\",\n    \"api_user\": \"sku_integration\",\n    \"api_key\": \"your-soap-api-key\"\n  },\n  \"start_date\": \"2026-01-01\",\n  \"inventory\": {\n    \"masterOfStock\": \"sku.io\",\n    \"inventoryModificationRules\": {\n      \"maxRuleType\": \"None\",\n      \"minRuleType\": \"None\"\n    },\n    \"selectedWarehouses\": [\n      1,\n      4\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances","host":["{{baseUrl}}"],"path":["api","magento1","instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Acme Storefront\",\n    \"is_configured\": true,\n    \"connection_status\": \"Ready\",\n    \"is_automatic_sync_enabled\": true,\n    \"store_base_url\": \"https://store.example.com\",\n    \"api_user\": \"sku_integration\",\n    \"api_key_set\": true,\n    \"start_date\": \"2026-01-01\",\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"inventoryModificationRules\": {\n        \"maxRuleType\": \"None\",\n        \"minRuleType\": \"None\"\n      },\n      \"selectedWarehouses\": [\n        1,\n        4\n      ]\n    },\n    \"last_orders_sync\": \"2026-07-07T18:42:10+00:00\",\n    \"last_products_sync\": \"2026-07-07T18:40:03+00:00\",\n    \"orders_count\": 128,\n    \"products_count\": 342,\n    \"created_at\": \"2026-06-15T09:12:00+00:00\",\n    \"updated_at\": \"2026-07-07T18:42:10+00:00\",\n    \"refunds\": {\n      \"allow_refunds_from_sku\": false\n    }\n  }\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns a single Magento 1 integration instance by id, including its connection status, settings, mirrored order and product counts, and last-sync timestamps. The SOAP API key is never returned — only `api_key_set` indicates whether one is stored.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Acme Storefront\",\n    \"is_configured\": true,\n    \"connection_status\": \"Ready\",\n    \"is_automatic_sync_enabled\": true,\n    \"store_base_url\": \"https://store.example.com\",\n    \"api_user\": \"sku_integration\",\n    \"api_key_set\": true,\n    \"start_date\": \"2026-01-01\",\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"inventoryModificationRules\": {\n        \"maxRuleType\": \"None\",\n        \"minRuleType\": \"None\"\n      },\n      \"selectedWarehouses\": [\n        1,\n        4\n      ]\n    },\n    \"last_orders_sync\": \"2026-07-07T18:42:10+00:00\",\n    \"last_products_sync\": \"2026-07-07T18:40:03+00:00\",\n    \"orders_count\": 128,\n    \"products_count\": 342,\n    \"created_at\": \"2026-06-15T09:12:00+00:00\",\n    \"updated_at\": \"2026-07-07T18:42:10+00:00\",\n    \"refunds\": {\n      \"allow_refunds_from_sku\": false\n    }\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Updates a Magento 1 integration instance. All fields are optional — only the keys you send are changed. Credentials are merged, so omitting `connection_settings.api_key` keeps the stored key intact rather than clearing it.\n\nRequest body fields (all optional):\n\n- `name` (string), `is_automatic_sync_enabled` (boolean).\n- `connection_settings` (object) — any of `store_base_url`, `api_user`, `api_key`.\n- `start_date` (string, `YYYY-MM-DD`, nullable).\n- `inventory` (object) — same shape as on create.\n- `refunds` (object) — outbound refund settings: `allow_refunds_from_sku` (boolean, default `false`) enables issuing refunds to Magento 1 from SKU. Refunds are recorded as **offline credit memos** on the Magento order — no money moves on the channel; the customer must be refunded through the payment processor separately.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme Storefront (US)\",\n  \"is_automatic_sync_enabled\": true,\n  \"connection_settings\": {\n    \"store_base_url\": \"https://store.example.com\",\n    \"api_user\": \"sku_integration\"\n  },\n  \"start_date\": \"2026-01-01\",\n  \"inventory\": {\n    \"masterOfStock\": \"sku.io\",\n    \"inventoryModificationRules\": {\n      \"maxRuleType\": \"None\",\n      \"minRuleType\": \"None\"\n    },\n    \"selectedWarehouses\": [\n      1,\n      4\n    ]\n  },\n  \"refunds\": {\n    \"allow_refunds_from_sku\": false\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Acme Storefront (US)\",\n    \"is_configured\": true,\n    \"connection_status\": \"Ready\",\n    \"is_automatic_sync_enabled\": true,\n    \"store_base_url\": \"https://store.example.com\",\n    \"api_user\": \"sku_integration\",\n    \"api_key_set\": true,\n    \"start_date\": \"2026-01-01\",\n    \"inventory\": {\n      \"masterOfStock\": \"sku.io\",\n      \"inventoryModificationRules\": {\n        \"maxRuleType\": \"None\",\n        \"minRuleType\": \"None\"\n      },\n      \"selectedWarehouses\": [\n        1,\n        4\n      ]\n    },\n    \"last_orders_sync\": \"2026-07-07T18:42:10+00:00\",\n    \"last_products_sync\": \"2026-07-07T18:40:03+00:00\",\n    \"orders_count\": 128,\n    \"products_count\": 342,\n    \"created_at\": \"2026-06-15T09:12:00+00:00\",\n    \"updated_at\": \"2026-07-07T18:42:10+00:00\",\n    \"refunds\": {\n      \"allow_refunds_from_sku\": false\n    }\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Deletes a Magento 1 integration instance and cleans up its linked sales channel, mirrored orders and products, and mapping records.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Integration deleted successfully\"\n}"}]},{"name":"Get Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Paginated change history for orders belonging to this integration instance. Each entry records a change event (created, updated, etc.), who made it, and a JSON `properties` payload holding the before/after attributes and the source of the change. Since Magento 1 is polled rather than pushing webhooks, this is the closest thing to a per-store event feed. Authenticate with a Personal Access Token (PAT) Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/activity-log","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","activity-log"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 884213,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Magento1Order\",\n      \"subject_id\": 5120,\n      \"properties\": {\n        \"source\": \"sync\",\n        \"attributes\": {\n          \"status\": \"complete\",\n          \"state\": \"complete\"\n        },\n        \"old\": {\n          \"status\": \"processing\",\n          \"state\": \"processing\"\n        }\n      },\n      \"batch_uuid\": \"9b2d1f4a-3c7e-4a2b-8f6d-1e2a3b4c5d6e\",\n      \"causer_name\": \"Sync Service\",\n      \"created_at\": \"2026-07-08T09:14:22.000000Z\"\n    },\n    {\n      \"id\": 884198,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"Magento1Order\",\n      \"subject_id\": 5120,\n      \"properties\": {\n        \"source\": \"sync\",\n        \"attributes\": {\n          \"magento_increment_id\": \"100004521\",\n          \"status\": \"processing\"\n        }\n      },\n      \"batch_uuid\": null,\n      \"causer_name\": null,\n      \"created_at\": \"2026-07-08T08:51:03.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 15,\n  \"total\": 174,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts a background pull of orders from the Magento 1 store into SKU.io. Returns a `tracked_job_log_id` you can poll for progress. Only one order sync runs per instance at a time — a second request while one is running is ignored.\n\nBody (all optional): `mode` — one of `since_latest` (resume from the last synced order; default), `from_start_date` (re-sweep from `dateFrom` up to now), or `date_range` (only orders within `[dateFrom, dateTo]`). `dateFrom`/`dateTo` — ISO-8601 dates, required for `from_start_date` (from) and `date_range` (both). `dateMethod` — `created` or `updated`, which order timestamp a `date_range` sweep filters on (default `updated`).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"dateFrom\": \"2026-01-01\",\n  \"dateTo\": \"2026-02-01\",\n  \"dateMethod\": \"updated\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 91427\n  },\n  \"message\": \"Order sync started\"\n}"}]},{"name":"Sync Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-products","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts a background pull of products from the Magento 1 store into SKU.io. Returns a `tracked_job_log_id` you can poll for progress. Only one product sync runs per instance at a time.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-products","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-products"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 91427\n  },\n  \"message\": \"Product sync started\"\n}"}]},{"name":"Sync Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-inventory","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts an inventory push from SKU.io to the Magento 1 store. The push fans out into batched jobs, so no `tracked_job_log_id` is returned — the response only confirms the push was queued. Inventory is pushed only from production environments and only for instances with inventory sync enabled; elsewhere the push is skipped.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/sync-inventory","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","sync-inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory sync started\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","orders"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope orders to (required — without it an empty page is returned)","disabled":true}]},"description":"Lists Magento 1 orders for one integration instance (the local mirror of orders pulled from the store). Scope with the `instance_id` query param — without it an empty page is returned so another store's orders never leak. Paginated (default 15/page).\n\nAllowed sorts: id, magento_created_at, magento_updated_at, grand_total, subtotal, status. Prefix with - for descending. Default: -magento_created_at.\n\nAdvanced filters (Spatie QueryBuilder): filter[search] (matches id, increment_id, external_order_id, customer email/first/last name); filter[increment_id], filter[external_order_id], filter[status], filter[state], filter[order_currency_code], filter[shipping_method] (text: supports .is / .contains / .starts_with / .ends_with tree operators); filter[grand_total], filter[subtotal], filter[tax_amount], filter[shipping_amount], filter[discount_amount] (numeric comparisons); filter[magento_created_at], filter[magento_updated_at], filter[created_at], filter[updated_at] (datetime ranges); filter[has_sku_order]=true|false (whether a SKU sales order is linked); filter[has_unmapped_items]=true|false (whether any line's Magento product is not linked to a SKU.io product); filter[archived]=only|all (default omitted = Active/non-archived only).\n\nEach line item includes the linked SKU.io product (via the Magento product → product listing mapping) when one exists.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/orders?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","orders"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope orders to (required — without it an empty page is returned)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3391,\n      \"integration_instance_id\": 3,\n      \"increment_id\": \"100004821\",\n      \"external_order_id\": \"4821\",\n      \"status\": \"processing\",\n      \"state\": \"processing\",\n      \"customer_email\": \"jane.doe@example.com\",\n      \"customer_firstname\": \"Jane\",\n      \"customer_lastname\": \"Doe\",\n      \"order_currency_code\": \"USD\",\n      \"grand_total\": \"54.1000\",\n      \"subtotal\": \"49.9800\",\n      \"tax_amount\": \"4.1200\",\n      \"shipping_amount\": \"5.0000\",\n      \"discount_amount\": \"0.0000\",\n      \"shipping_method\": \"flatrate_flatrate\",\n      \"shipping_description\": \"Flat Rate - Fixed\",\n      \"magento_created_at\": \"2026-07-01T14:22:05+00:00\",\n      \"magento_updated_at\": \"2026-07-02T09:10:44+00:00\",\n      \"order_items\": [\n        {\n          \"id\": 55012,\n          \"item_id\": 88231,\n          \"product_id\": 4471,\n          \"product_type\": \"simple\",\n          \"sku\": \"WIDGET-BLUE-M\",\n          \"name\": \"Blue Widget - Medium\",\n          \"magento_product_id\": 14471,\n          \"magento_product_route\": \"/integrations/magento1/products/14471\",\n          \"qty_ordered\": 2,\n          \"qty_shipped\": 2,\n          \"qty_canceled\": 0,\n          \"qty_refunded\": 0,\n          \"qty_invoiced\": 2,\n          \"price\": \"24.9900\",\n          \"row_total\": \"49.9800\",\n          \"tax_amount\": \"4.1200\",\n          \"discount_amount\": \"0.0000\",\n          \"sku_product_id\": 8817,\n          \"sku_product_route\": \"/products/8817\",\n          \"sku_product\": {\n            \"id\": 8817,\n            \"sku\": \"SKU-WIDGET-BLUE-M\",\n            \"name\": \"Blue Widget (Medium)\",\n            \"type\": \"standard\"\n          }\n        }\n      ],\n      \"sales_order\": {\n        \"id\": 120544,\n        \"sales_order_number\": \"SO-120544\",\n        \"order_status\": \"processing\",\n        \"fulfillment_status\": \"unfulfilled\",\n        \"payment_status\": \"paid\"\n      },\n      \"created_at\": \"2026-07-01T14:25:11+00:00\",\n      \"archived_at\": null,\n      \"is_archived\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 15,\n  \"total\": 174,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/magento1/orders?page=1\",\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/magento1/orders?page=12\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/magento1/orders?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/magento1/orders\",\n  \"links\": []\n}"}]},{"name":"Get Order Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/filter-options?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","orders","filter-options"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope options to","disabled":true}]},"description":"Returns the distinct status, state, currency, and shipping-method values that actually appear in the orders for the given integration instance, so the list filters only offer options that return rows. Returns empty arrays when the instance cannot be resolved.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/orders/filter-options?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","orders","filter-options"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope options to","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"statuses\": [\n      \"canceled\",\n      \"closed\",\n      \"complete\",\n      \"processing\"\n    ],\n    \"states\": [\n      \"canceled\",\n      \"complete\",\n      \"new\",\n      \"processing\"\n    ],\n    \"currencies\": [\n      \"USD\"\n    ],\n    \"shipping_methods\": [\n      \"flatrate_flatrate\",\n      \"freeshipping_freeshipping\"\n    ]\n  }\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Returns a single Magento 1 order with its line items (each resolving the linked SKU.io product when mapped) and a summary of the linked SKU sales order.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3391,\n    \"integration_instance_id\": 3,\n    \"increment_id\": \"100004821\",\n    \"external_order_id\": \"4821\",\n    \"status\": \"processing\",\n    \"state\": \"processing\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"customer_firstname\": \"Jane\",\n    \"customer_lastname\": \"Doe\",\n    \"order_currency_code\": \"USD\",\n    \"grand_total\": \"54.1000\",\n    \"subtotal\": \"49.9800\",\n    \"tax_amount\": \"4.1200\",\n    \"shipping_amount\": \"5.0000\",\n    \"discount_amount\": \"0.0000\",\n    \"shipping_method\": \"flatrate_flatrate\",\n    \"shipping_description\": \"Flat Rate - Fixed\",\n    \"magento_created_at\": \"2026-07-01T14:22:05+00:00\",\n    \"magento_updated_at\": \"2026-07-02T09:10:44+00:00\",\n    \"order_items\": [\n      {\n        \"id\": 55012,\n        \"item_id\": 88231,\n        \"product_id\": 4471,\n        \"product_type\": \"simple\",\n        \"sku\": \"WIDGET-BLUE-M\",\n        \"name\": \"Blue Widget - Medium\",\n        \"magento_product_id\": 14471,\n        \"magento_product_route\": \"/integrations/magento1/products/14471\",\n        \"qty_ordered\": 2,\n        \"qty_shipped\": 2,\n        \"qty_canceled\": 0,\n        \"qty_refunded\": 0,\n        \"qty_invoiced\": 2,\n        \"price\": \"24.9900\",\n        \"row_total\": \"49.9800\",\n        \"tax_amount\": \"4.1200\",\n        \"discount_amount\": \"0.0000\",\n        \"sku_product_id\": 8817,\n        \"sku_product_route\": \"/products/8817\",\n        \"sku_product\": {\n          \"id\": 8817,\n          \"sku\": \"SKU-WIDGET-BLUE-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"type\": \"standard\"\n        }\n      }\n    ],\n    \"sales_order\": {\n      \"id\": 120544,\n      \"sales_order_number\": \"SO-120544\",\n      \"order_status\": \"processing\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"payment_status\": \"paid\"\n    },\n    \"created_at\": \"2026-07-01T14:25:11+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false\n  }\n}"}]},{"name":"Get Raw Order Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","raw"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Fetches the full order payload live from the Magento 1 store (the deep `salesOrderInfo` SOAP response) for the 'View Raw Data' panel. Magento 1 order mirrors carry no stored raw blob, so this reads on demand from the store. Returns 422 if the store call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","raw"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"increment_id\": \"100004821\",\n    \"order_id\": \"4821\",\n    \"status\": \"processing\",\n    \"state\": \"processing\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"grand_total\": \"54.1000\",\n    \"items\": [\n      {\n        \"item_id\": \"88231\",\n        \"sku\": \"WIDGET-BLUE-M\",\n        \"name\": \"Blue Widget - Medium\",\n        \"qty_ordered\": \"2.0000\",\n        \"price\": \"24.9900\"\n      }\n    ],\n    \"shipping_address\": {\n      \"firstname\": \"Jane\",\n      \"lastname\": \"Doe\",\n      \"city\": \"Austin\",\n      \"region\": \"Texas\",\n      \"postcode\": \"78701\",\n      \"country_id\": \"US\"\n    },\n    \"billing_address\": {\n      \"firstname\": \"Jane\",\n      \"lastname\": \"Doe\",\n      \"city\": \"Austin\",\n      \"region\": \"Texas\",\n      \"postcode\": \"78701\",\n      \"country_id\": \"US\"\n    }\n  }\n}"}]},{"name":"Refetch Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/refetch","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","refetch"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Re-pulls a single order from the Magento 1 store, re-persists the local mirror, and returns the refreshed order. Returns 422 if the store call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/refetch","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","refetch"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order refreshed from Magento 1\",\n  \"data\": {\n    \"id\": 3391,\n    \"integration_instance_id\": 3,\n    \"increment_id\": \"100004821\",\n    \"external_order_id\": \"4821\",\n    \"status\": \"processing\",\n    \"state\": \"processing\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"customer_firstname\": \"Jane\",\n    \"customer_lastname\": \"Doe\",\n    \"order_currency_code\": \"USD\",\n    \"grand_total\": \"54.1000\",\n    \"subtotal\": \"49.9800\",\n    \"tax_amount\": \"4.1200\",\n    \"shipping_amount\": \"5.0000\",\n    \"discount_amount\": \"0.0000\",\n    \"shipping_method\": \"flatrate_flatrate\",\n    \"shipping_description\": \"Flat Rate - Fixed\",\n    \"magento_created_at\": \"2026-07-01T14:22:05+00:00\",\n    \"magento_updated_at\": \"2026-07-02T09:10:44+00:00\",\n    \"order_items\": [\n      {\n        \"id\": 55012,\n        \"item_id\": 88231,\n        \"product_id\": 4471,\n        \"product_type\": \"simple\",\n        \"sku\": \"WIDGET-BLUE-M\",\n        \"name\": \"Blue Widget - Medium\",\n        \"magento_product_id\": 14471,\n        \"magento_product_route\": \"/integrations/magento1/products/14471\",\n        \"qty_ordered\": 2,\n        \"qty_shipped\": 2,\n        \"qty_canceled\": 0,\n        \"qty_refunded\": 0,\n        \"qty_invoiced\": 2,\n        \"price\": \"24.9900\",\n        \"row_total\": \"49.9800\",\n        \"tax_amount\": \"4.1200\",\n        \"discount_amount\": \"0.0000\",\n        \"sku_product_id\": 8817,\n        \"sku_product_route\": \"/products/8817\",\n        \"sku_product\": {\n          \"id\": 8817,\n          \"sku\": \"SKU-WIDGET-BLUE-M\",\n          \"name\": \"Blue Widget (Medium)\",\n          \"type\": \"standard\"\n        }\n      }\n    ],\n    \"sales_order\": {\n      \"id\": 120544,\n      \"sales_order_number\": \"SO-120544\",\n      \"order_status\": \"processing\",\n      \"fulfillment_status\": \"unfulfilled\",\n      \"payment_status\": \"paid\"\n    },\n    \"created_at\": \"2026-07-01T14:25:11+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false\n  }\n}"}]},{"name":"Archive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","archive"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Archives a single Magento 1 order so it is excluded from the active list and never auto-creates a SKU sales order. Idempotent — returns `archived: false` if it was already archived.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","archive"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order archived successfully\",\n  \"archived\": true\n}"}]},{"name":"Unarchive Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","unarchive"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Restores a previously archived Magento 1 order to the active list. Idempotent — returns `unarchived: false` if it was already active.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/unarchive","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","unarchive"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order unarchived successfully\",\n  \"unarchived\": true\n}"}]},{"name":"Bulk Archive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Archives multiple Magento 1 orders on the instance. Already-archived orders are skipped and not counted.\n\nBody fields:\n- ids (array of integers, required): Magento 1 order ids to archive.\n\nSet `apply_to_all: true` (instead of `ids`) to archive EVERY non-archived order for the instance — the \"All Filtered\" bulk scope.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-archive","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-archive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders archived successfully\",\n  \"archived_count\": 3\n}"}]},{"name":"Bulk Unarchive Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Restores multiple archived Magento 1 orders on the instance to active. Already-active orders are skipped and not counted.\n\nBody fields:\n- ids (array of integers, required): Magento 1 order ids to unarchive.\n\nSet `apply_to_all: true` (instead of `ids`) to unarchive EVERY archived order for the instance — the \"All Filtered\" bulk scope.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-unarchive","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-unarchive"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 orders unarchived successfully\",\n  \"unarchived_count\": 3\n}"}]},{"name":"Get Latest Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Aggregated metrics for the orders refresh modal: the latest imported order, total order count, the created / pending / archived split, and the last-synced timestamp (derived from the freshest mirror write — Magento 1 has no sync cursor).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_display_id\": \"100004821\",\n    \"latest_order_date\": \"2026-07-01T14:22:05+00:00\",\n    \"total_orders\": 174,\n    \"created_count\": 150,\n    \"pending_count\": 20,\n    \"archived_count\": 4,\n    \"last_synced_at\": \"2026-07-02T09:12:00+00:00\"\n  }\n}"}]},{"name":"Create SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Creates SKU.io sales orders from selected Magento 1 orders, or from every unlinked, non-archived order on the instance when `create_all_orders` is true. Runs as a background job — returns a `tracked_job_log_id` to poll. Already-linked and archived orders are skipped.\n\nBody fields:\n- ids (array of integers, required unless create_all_orders is true): Magento 1 order ids to create SKU orders for.\n- create_all_orders (boolean, optional, default false): when true, ignores ids and creates SKU orders for all unlinked, non-archived orders.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"create_all_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/create-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","create-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order creation started for 3 orders\",\n  \"tracked_job_log_id\": 91555,\n  \"total_orders\": 3\n}"}]},{"name":"Update SKU Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/{order}/update-sku-order","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders",":order","update-sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Refetches a single Magento 1 order and re-syncs the status fields on its linked SKU.io sales order. Returns 403 if the order does not belong to the instance, 404 if no SKU order is linked, 422 if the update failed.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/{order}/update-sku-order","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders",":order","update-sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order updated successfully\",\n  \"refetched\": true\n}"}]},{"name":"Bulk Update SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-update-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-update-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Refetches the given Magento 1 orders and re-syncs the status fields (order/fulfillment/payment status) on their linked SKU.io sales orders. A single order is processed synchronously; multiple orders run as a background job with a `tracked_job_log_id`.\n\nBody fields:\n- ids (array of integers, required): Magento 1 order ids whose linked SKU orders to update.\n\nSet `apply_to_all: true` (instead of `ids`) to update EVERY order that has a linked SKU sales order — the \"All Filtered\" bulk scope.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-update-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-update-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk update job started\",\n  \"tracked_job_log_id\": 91561,\n  \"total_orders\": 3\n}"}]},{"name":"Delete Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Permanently delete Magento 1 orders from SKU.io (the mirror records), cascading to any linked SKU sales order + order items. This does NOT delete anything in the Magento 1 store. Distinct from Delete SKU Orders, which only unlinks.\n\nBody: `ids` (integer array) OR `apply_to_all: true` to delete EVERY order for the instance (the \"All Filtered\" scope). Deletes >1 order via a tracked background job (returns `tracked_job_log_id`); a single order deletes synchronously.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"apply_to_all\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-delete","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-delete"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete job started\",\n  \"tracked_job_log_id\": 7,\n  \"total_orders\": 3\n}"}]},{"name":"Delete SKU Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]},"description":"Deletes the SKU.io sales order linked to a single Magento 1 order (the Magento 1 order is kept). Optionally archives the Magento 1 order afterwards via the `archive_magento1_order` query flag. Returns 403 if the order does not belong to the instance, 404 if no SKU order is linked.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/{order}/sku-order","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders",":order","sku-order"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."},{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"SKU order deleted successfully\",\n  \"archived_magento1_order\": false\n}"}]},{"name":"Bulk Delete SKU Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Deletes the SKU.io sales orders linked to the given Magento 1 orders (the Magento 1 orders themselves are kept). A single order is deleted synchronously; multiple orders run as a background job with a `tracked_job_log_id`. Optionally archives the Magento 1 orders afterwards so they are not re-created on the next sync.\n\nBody fields:\n- ids (array of integers, required): Magento 1 order ids whose linked SKU orders to delete.\n- archive_magento1_orders (boolean, optional, default false): archive the Magento 1 orders after deleting.\n\nSet `apply_to_all: true` (instead of `ids`) to delete the linked SKU sales order for EVERY order that has one — the \"All Filtered\" bulk scope.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    3391,\n    3392,\n    3393\n  ],\n  \"apply_to_all\": false,\n  \"archive_magento1_orders\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/bulk-delete-sku-orders","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","bulk-delete-sku-orders"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bulk delete job started\",\n  \"tracked_job_log_id\": 91560,\n  \"total_orders\": 3\n}"}]},{"name":"Submit Tracking","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/submit-tracking","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","submit-tracking"],"variable":[{"key":"order","value":"","description":"The order ID."}]},"description":"Queues a shipment (with tracking) back to the Magento 1 store for this order, using the most recent fulfilled shipment that carries a tracking number on the linked SKU sales order. Magento 1 is merchant-fulfilled, so tracking always applies. Returns 422 if no SKU order is linked or no fulfilled shipment with a tracking number exists.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/orders/{order}/submit-tracking","host":["{{baseUrl}}"],"path":["api","magento1","orders",":order","submit-tracking"],"variable":[{"key":"order","value":"","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Magento 1 tracking submission queued.\"\n}"}]},{"name":"Search Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/search","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","search"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Live-search the connected Magento 1 store for orders by increment id or customer email. Returns shallow matches, each flagged with whether it already exists in SKU.io.\n\nBody: `search_by` — `increment_id` or `email`. `query` — the search term (string, max 255).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"search_by\": \"increment_id\",\n  \"query\": \"100000017\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/search","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","search"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"increment_id\": \"100000017\",\n      \"status\": \"complete\",\n      \"customer_email\": \"jane@example.com\",\n      \"customer_firstname\": \"Jane\",\n      \"customer_lastname\": \"Doe\",\n      \"created_at\": \"2026-07-07 13:55:58\",\n      \"grand_total\": \"129.9900\",\n      \"order_currency_code\": \"USD\",\n      \"exists_in_database\": true,\n      \"database_id\": 42\n    }\n  ]\n}"}]},{"name":"Download Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/fetch-single","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","fetch-single"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Fetch a single order from the Magento 1 store by its increment id and persist it into SKU.io. Use this to import a specific order surfaced by Search Orders.\n\nBody: `increment_id` — the Magento order increment id (string, required).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"increment_id\": \"100000017\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/orders/fetch-single","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","orders","fetch-single"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order fetched from Magento 1\",\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"increment_id\": \"100000017\",\n    \"status\": \"complete\",\n    \"state\": \"complete\",\n    \"customer_email\": \"jane@example.com\",\n    \"customer_firstname\": \"Jane\",\n    \"customer_lastname\": \"Doe\",\n    \"grand_total\": \"129.9900\",\n    \"order_currency_code\": \"USD\",\n    \"magento_created_at\": \"2026-07-07T13:55:58+00:00\",\n    \"magento_updated_at\": \"2026-07-07T13:55:58+00:00\",\n    \"sales_order\": {\n      \"id\": 8891,\n      \"sales_order_number\": \"SO-100482\"\n    },\n    \"order_items\": [\n      {\n        \"sku\": \"ACME-HOODIE-M-BLU\",\n        \"name\": \"Acme Hoodie - Medium - Blue\",\n        \"qty_ordered\": \"1.0000\",\n        \"price\": \"129.9900\"\n      }\n    ]\n  }\n}"}]},{"name":"List Products (Cross-Instance)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/products?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","products"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope products to. On the cross-instance index this is REQUIRED — without it an empty page is returned so another store's catalog never leaks (no ::first() fallback).","disabled":true}]},"description":"Lists Magento 1 catalog products (the local mirror pulled from the store) for ONE integration instance. Scope with the `instance_id` query param — it is REQUIRED here; without it an empty page is returned so another store's catalog never leaks (the controller refuses to fall back to `::first()`). Paginated (default 10/page on this cross-instance route).\n\nAllowed sorts: id, product_id, sku, name, price, qty, status, magento_created_at, magento_updated_at. Prefix with - for descending. Default: -magento_updated_at.\n\nSearch (filter[search]) matches id, product_id, sku, name. Advanced filters (Spatie QueryBuilder): filter[sku], filter[name], filter[type_id], filter[status], filter[visibility] (text, tree operators); filter[product_id], filter[price], filter[weight], filter[qty] (numeric); filter[is_in_stock], filter[has_mapping] (boolean, .is); filter[magento_created_at], filter[magento_updated_at], filter[created_at], filter[updated_at] (datetime ranges); filter[archived]=only|all.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/products?instance_id=3","host":["{{baseUrl}}"],"path":["api","magento1","products"],"query":[{"key":"instance_id","value":"3","description":"Integration instance id to scope products to. On the cross-instance index this is REQUIRED — without it an empty page is returned so another store's catalog never leaks (no ::first() fallback).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"integration_instance_id\": 3,\n      \"product_id\": 8842,\n      \"sku\": \"ACME-HOODIE-M-BLU\",\n      \"name\": \"Acme Hoodie - Medium - Blue\",\n      \"type_id\": \"simple\",\n      \"status\": \"1\",\n      \"visibility\": \"4\",\n      \"price\": \"49.9900\",\n      \"weight\": \"0.8000\",\n      \"short_description\": \"Soft cotton hoodie\",\n      \"description\": \"A soft, midweight cotton hoodie.\",\n      \"qty\": \"124.0000\",\n      \"is_in_stock\": true,\n      \"image_url\": \"https://store.example.com/media/catalog/product/a/c/acme-hoodie.jpg\",\n      \"store_id\": 1,\n      \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n      \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n      \"is_mapped\": true,\n      \"product_listing\": {\n        \"id\": 9001,\n        \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n        \"product\": {\n          \"id\": 30412,\n          \"sku\": \"ACME-HOODIE-M-BLU\",\n          \"name\": \"Acme Hoodie (Medium, Blue)\",\n          \"type\": \"simple\"\n        }\n      },\n      \"created_at\": \"2026-01-04T09:15:00+00:00\",\n      \"archived_at\": null,\n      \"is_archived\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 9,\n  \"per_page\": 15,\n  \"total\": 128,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"List Products by Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Lists Magento 1 catalog products for the instance given in the path (the instance-scoped variant of the cross-instance index — same pagination, sorting, search, and filters, but the instance comes from the URL rather than `instance_id`).\n\nAllowed sorts: id, product_id, sku, name, price, qty, status, magento_created_at, magento_updated_at (default -magento_updated_at). Same advanced filters as the cross-instance index. Paginated (default 15/page).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 512,\n      \"integration_instance_id\": 3,\n      \"product_id\": 8842,\n      \"sku\": \"ACME-HOODIE-M-BLU\",\n      \"name\": \"Acme Hoodie - Medium - Blue\",\n      \"type_id\": \"simple\",\n      \"status\": \"1\",\n      \"visibility\": \"4\",\n      \"price\": \"49.9900\",\n      \"weight\": \"0.8000\",\n      \"short_description\": \"Soft cotton hoodie\",\n      \"description\": \"A soft, midweight cotton hoodie.\",\n      \"qty\": \"124.0000\",\n      \"is_in_stock\": true,\n      \"image_url\": \"https://store.example.com/media/catalog/product/a/c/acme-hoodie.jpg\",\n      \"store_id\": 1,\n      \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n      \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n      \"is_mapped\": true,\n      \"product_listing\": {\n        \"id\": 9001,\n        \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n        \"product\": {\n          \"id\": 30412,\n          \"sku\": \"ACME-HOODIE-M-BLU\",\n          \"name\": \"Acme Hoodie (Medium, Blue)\",\n          \"type\": \"simple\"\n        }\n      },\n      \"created_at\": \"2026-01-04T09:15:00+00:00\",\n      \"archived_at\": null,\n      \"is_archived\": false\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 9,\n  \"per_page\": 15,\n  \"total\": 128,\n  \"from\": 1,\n  \"to\": 15,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Get Product Filter Options","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","filter-options"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Distinct filter option values for the products listing filter chips — the set of product types, statuses, and visibilities present in this instance's mirrored catalog.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/filter-options","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","filter-options"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"types\": [\n      \"simple\",\n      \"configurable\",\n      \"bundle\"\n    ],\n    \"statuses\": [\n      \"1\",\n      \"2\"\n    ],\n    \"visibilities\": [\n      \"1\",\n      \"2\",\n      \"3\",\n      \"4\"\n    ]\n  }\n}"}]},{"name":"Get Latest Product Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Product sync summary powering the \"Latest Synced Product\" header card on the Refresh-from-Magento-1 modal: total/mapped/unmapped/archived counts plus the last-synced timestamp.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/latest-sync-info","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","latest-sync-info"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 128,\n    \"mapped\": 91,\n    \"unmapped\": 37,\n    \"archived\": 4,\n    \"last_synced_at\": \"2026-07-08T06:20:00+00:00\"\n  }\n}"}]},{"name":"Refresh Products (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Starts a background product refresh from the Magento 1 store into SKU.io. Returns a `tracked_job_log_id` you can poll for progress.\n\nBody (optional): `mode` — either `since_latest` (resume from the last synced product; default) or `full_catalog` (re-import the entire catalog). Magento 1's catalog API has no date query, so date-range refresh is not supported for products.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/refresh-tracked","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","refresh-tracked"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 48213\n  },\n  \"message\": \"Product refresh job has been queued\"\n}"}]},{"name":"Bulk Product Operation (Sync)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Runs a bulk operation on catalog products synchronously — best for small \"Selected Only\" requests. For large \"All Filtered\" sets that may exceed the HTTP timeout, use Bulk Product Operation (Tracked) instead.\n\nBody fields:\n- action (string, required): one of archive, unarchive, delete, map, unmap, create, remap. `map`/`remap` link by the product's own SKU; `archive` skips products that already carry channel orders.\n- selection (object, required):\n  - selection.type (required): selected | visible | filtered.\n  - selection.ids (`array<int>`, required when type=selected): magento1_products.id PKs.\n  - selection.filters (object, optional): the same filter[...] tree as the listing, used when type=filtered/visible to resolve the id set server-side.\n- options (object, optional): action-specific options.\n\nReturns per-action counts. 422 if the selection resolves to zero products.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"action\": \"map\",\n  \"selection\": {\n    \"type\": \"selected\",\n    \"ids\": [\n      512,\n      513,\n      514\n    ]\n  },\n  \"options\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"processed\": 3,\n    \"failed\": 0,\n    \"skipped\": 0\n  },\n  \"message\": \"Bulk map completed. Processed: 3, Failed: 0, Skipped: 0\"\n}"}]},{"name":"Bulk Product Operation (Tracked)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Starts a tracked bulk operation on catalog products — best for \"All Filtered\" requests that may exceed the HTTP timeout. Returns a `tracked_job_log_id` to poll for progress. Same body contract as the synchronous Bulk endpoint.\n\nBody fields:\n- action (string, required): archive | unarchive | delete | map | unmap | create | remap.\n- selection (object, required): { type: selected|visible|filtered, ids: [int] (required when selected), filters: {…} }.\n- options (object, optional).\n\n422 if the selection resolves to zero products.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"action\": \"archive\",\n  \"selection\": {\n    \"type\": \"filtered\",\n    \"filters\": {\n      \"filter\": {\n        \"has_mapping\": \"false\"\n      }\n    }\n  },\n  \"options\": {}\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk-tracked","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk-tracked"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 48219\n  },\n  \"message\": \"Bulk operation job has been queued\"\n}"}]},{"name":"Get Bulk Operation Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"trackedJobLogId","value":"48219","description":"Tracked job log id returned by Bulk Product Operation (Tracked)"}]},"description":"Progress for a tracked bulk product operation job — the tracked job log (status, processed/total, errors).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/bulk-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","bulk-progress",":trackedJobLogId"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"trackedJobLogId","value":"48219","description":"Tracked job log id returned by Bulk Product Operation (Tracked)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 48219,\n    \"name\": \"Bulk Magento 1 Product Operation\",\n    \"status\": \"COMPLETED\",\n    \"total\": 37,\n    \"processed\": 37,\n    \"failed\": 0,\n    \"created_at\": \"2026-07-08T06:40:00+00:00\"\n  }\n}"}]},{"name":"Smart-Match Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Returns smart-match candidates for a catalog product: the best exact-SKU match plus fuzzy name/SKU candidates. Powers the per-row mapping modal.\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/smart-match","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","smart-match"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"exact_match\": {\n      \"id\": 30412,\n      \"sku\": \"ACME-HOODIE-M-BLU\",\n      \"name\": \"Acme Hoodie (Medium, Blue)\",\n      \"barcode\": 819431027,\n      \"type\": \"simple\",\n      \"price\": \"49.99\",\n      \"match_type\": \"sku\"\n    },\n    \"similar_matches\": [\n      {\n        \"id\": 30418,\n        \"sku\": \"ACME-HOODIE-L-BLU\",\n        \"name\": \"Acme Hoodie (Large, Blue)\",\n        \"barcode\": 819431034,\n        \"type\": \"simple\",\n        \"price\": \"49.99\",\n        \"match_type\": \"fuzzy\"\n      }\n    ]\n  }\n}"}]},{"name":"Create SKU Product from Magento Product","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Creates a new SKU.io product from the catalog product's data and links it. If a SKU.io product with the matching SKU already exists, the manager links to it instead of creating a duplicate. Returns 422 if the catalog product is already mapped (unmap it first).\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/create-sku-product","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","create-sku-product"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 512,\n    \"integration_instance_id\": 3,\n    \"product_id\": 8842,\n    \"sku\": \"ACME-HOODIE-M-BLU\",\n    \"name\": \"Acme Hoodie - Medium - Blue\",\n    \"type_id\": \"simple\",\n    \"status\": \"1\",\n    \"visibility\": \"4\",\n    \"price\": \"49.9900\",\n    \"weight\": \"0.8000\",\n    \"short_description\": \"Soft cotton hoodie\",\n    \"description\": \"A soft, midweight cotton hoodie.\",\n    \"qty\": \"124.0000\",\n    \"is_in_stock\": true,\n    \"image_url\": \"https://store.example.com/media/catalog/product/a/c/acme-hoodie.jpg\",\n    \"store_id\": 1,\n    \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n    \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n    \"is_mapped\": true,\n    \"product_listing\": {\n      \"id\": 9001,\n      \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n      \"product\": {\n        \"id\": 30412,\n        \"sku\": \"ACME-HOODIE-M-BLU\",\n        \"name\": \"Acme Hoodie (Medium, Blue)\",\n        \"type\": \"simple\"\n      }\n    },\n    \"created_at\": \"2026-01-04T09:15:00+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false\n  },\n  \"message\": \"SKU.io product created and mapped.\"\n}"}]},{"name":"Map Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Maps a single catalog product to a specific SKU.io product chosen in the smart-match modal. Replaces any existing mapping in place. Returns the refreshed Magento 1 product resource (with its `product_listing`).\n\nBody fields:\n- product_id (integer, required): the SKU.io product id to link (must exist in `products`).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_id\": 30412\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 512,\n    \"integration_instance_id\": 3,\n    \"product_id\": 8842,\n    \"sku\": \"ACME-HOODIE-M-BLU\",\n    \"name\": \"Acme Hoodie - Medium - Blue\",\n    \"type_id\": \"simple\",\n    \"status\": \"1\",\n    \"visibility\": \"4\",\n    \"price\": \"49.9900\",\n    \"weight\": \"0.8000\",\n    \"short_description\": \"Soft cotton hoodie\",\n    \"description\": \"A soft, midweight cotton hoodie.\",\n    \"qty\": \"124.0000\",\n    \"is_in_stock\": true,\n    \"image_url\": \"https://store.example.com/media/catalog/product/a/c/acme-hoodie.jpg\",\n    \"store_id\": 1,\n    \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n    \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n    \"is_mapped\": true,\n    \"product_listing\": {\n      \"id\": 9001,\n      \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n      \"product\": {\n        \"id\": 30412,\n        \"sku\": \"ACME-HOODIE-M-BLU\",\n        \"name\": \"Acme Hoodie (Medium, Blue)\",\n        \"type\": \"simple\"\n      }\n    },\n    \"created_at\": \"2026-01-04T09:15:00+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false\n  }\n}"}]},{"name":"Unmap Product","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Removes the SKU.io product link for a single catalog product.\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/map","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","map"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"unmapped\": true\n  },\n  \"message\": \"Product unmapped\"\n}"}]},{"name":"Get Raw Product Data (Live)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Fetches the raw catalog payload for a product LIVE from the Magento 1 store via the SOAP Core API (mirrors Shopify's \"Load Raw Data\" panel). Magento 1 mirror tables carry no `raw_data` column, so there is no cached fallback — a store/SOAP error surfaces as 422.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product","raw"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_id\": \"8842\",\n    \"sku\": \"ACME-HOODIE-M-BLU\",\n    \"name\": \"Acme Hoodie - Medium - Blue\",\n    \"status\": \"1\",\n    \"visibility\": \"4\",\n    \"type\": \"simple\",\n    \"price\": \"49.9900\",\n    \"weight\": \"0.8000\"\n  },\n  \"source\": \"live\"\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]},"description":"Shows a single Magento 1 catalog product with its linked SKU.io product listing (when mapped). 404 if the product does not belong to the given instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/{product}","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products",":product"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"},{"key":"product","value":"512","description":"Magento 1 product mirror id (magento1_products.id PK)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 512,\n    \"integration_instance_id\": 3,\n    \"product_id\": 8842,\n    \"sku\": \"ACME-HOODIE-M-BLU\",\n    \"name\": \"Acme Hoodie - Medium - Blue\",\n    \"type_id\": \"simple\",\n    \"status\": \"1\",\n    \"visibility\": \"4\",\n    \"price\": \"49.9900\",\n    \"weight\": \"0.8000\",\n    \"short_description\": \"Soft cotton hoodie\",\n    \"description\": \"A soft, midweight cotton hoodie.\",\n    \"qty\": \"124.0000\",\n    \"is_in_stock\": true,\n    \"image_url\": \"https://store.example.com/media/catalog/product/a/c/acme-hoodie.jpg\",\n    \"store_id\": 1,\n    \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n    \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n    \"is_mapped\": true,\n    \"product_listing\": {\n      \"id\": 9001,\n      \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n      \"product\": {\n        \"id\": 30412,\n        \"sku\": \"ACME-HOODIE-M-BLU\",\n        \"name\": \"Acme Hoodie (Medium, Blue)\",\n        \"type\": \"simple\"\n      }\n    },\n    \"created_at\": \"2026-01-04T09:15:00+00:00\",\n    \"archived_at\": null,\n    \"is_archived\": false\n  }\n}"}]},{"name":"Search Products","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/search","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","search"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Live-search the connected Magento 1 catalog by SKU or name. Returns shallow matches, each flagged with whether it already exists in SKU.io.\n\nBody: `search_by` — `sku` or `name`. `query` — the search term (string, max 255).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"search_by\": \"sku\",\n  \"query\": \"ACME-HOODIE\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/search","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","search"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": \"8842\",\n      \"sku\": \"ACME-HOODIE-M-BLU\",\n      \"name\": \"Acme Hoodie - Medium - Blue\",\n      \"type\": \"simple\",\n      \"exists_in_database\": false,\n      \"database_id\": null\n    }\n  ]\n}"}]},{"name":"Download Single Product","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/fetch-single","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","fetch-single"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Fetch a single catalog product from the Magento 1 store by its product id (deep data + live stock) and persist it into SKU.io. Use this to import a specific product surfaced by Search Products.\n\nBody: `product_id` — the Magento catalog product id (string, required).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_id\": \"8842\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/products/fetch-single","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","products","fetch-single"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product fetched from Magento 1\",\n  \"data\": {\n    \"id\": 512,\n    \"integration_instance_id\": 3,\n    \"product_id\": 8842,\n    \"sku\": \"ACME-HOODIE-M-BLU\",\n    \"name\": \"Acme Hoodie - Medium - Blue\",\n    \"type_id\": \"simple\",\n    \"status\": \"1\",\n    \"visibility\": \"4\",\n    \"price\": \"49.9900\",\n    \"weight\": \"0.8000\",\n    \"qty\": \"124.0000\",\n    \"is_in_stock\": true,\n    \"magento_created_at\": \"2026-01-04T09:12:00+00:00\",\n    \"magento_updated_at\": \"2026-07-02T14:33:00+00:00\",\n    \"is_mapped\": true,\n    \"product_listing\": {\n      \"id\": 9001,\n      \"listing_sku\": \"ACME-HOODIE-M-BLU\",\n      \"product\": {\n        \"id\": 30412,\n        \"sku\": \"ACME-HOODIE-M-BLU\",\n        \"name\": \"Acme Hoodie (Medium, Blue)\",\n        \"type\": \"simple\"\n      }\n    }\n  }\n}"}]},{"name":"Get Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Current Magento 1 → SKU.io field-mapping config for the instance — what the Map dialog's \"Field Mapping\" section edits. Returns the available source (Magento) fields, the constrained set of target (SKU) fields, the default mappings, the instance's custom overrides, and the effective (merged) mappings.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 3,\n    \"integration_name\": \"Acme Magento Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": []\n      }\n    ],\n    \"available_magento_fields\": [\n      \"name\",\n      \"sku\",\n      \"price\",\n      \"weight\",\n      \"short_description\",\n      \"description\"\n    ],\n    \"available_sku_fields\": [\n      \"sku\",\n      \"item_name\",\n      \"price\",\n      \"weight\",\n      \"length\",\n      \"width\",\n      \"height\"\n    ],\n    \"default_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\"\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\"\n      }\n    ],\n    \"custom_mappings\": [],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\"\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]},"description":"Upserts the per-instance field-mapping config. Target (`sku_field`) values are constrained to the exact keys `Magento1Product::applyDataMapping()` resolves (sku, item_name, price, weight, length, width, height), so a saved mapping never silently no-ops at product-creation time.\n\nBody fields:\n- mappings (array, required): the full mapping set to persist.\n  - mappings.*.listing_field (string, required): a Magento source field (name, sku, price, weight, short_description, description).\n  - mappings.*.sku_field (string, required): the SKU.io target field.\n  - mappings.*.parsers (array, optional/nullable): ordered value transformers applied on import.\n\nReturns the persisted mappings + the recomputed effective mappings.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"listing_field\": \"sku\",\n      \"sku_field\": \"sku\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"name\",\n      \"sku_field\": \"item_name\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"price\",\n      \"sku_field\": \"price\",\n      \"parsers\": []\n    },\n    {\n      \"listing_field\": \"weight\",\n      \"sku_field\": \"weight\",\n      \"parsers\": []\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/mappings","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","mappings"],"variable":[{"key":"integrationInstance","value":"3","description":"Magento 1 integration instance id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_instance_id\": 3,\n    \"integration_name\": \"Acme Magento Store\",\n    \"mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price\",\n        \"parsers\": []\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\",\n        \"parsers\": []\n      }\n    ],\n    \"effective_mappings\": [\n      {\n        \"listing_field\": \"sku\",\n        \"sku_field\": \"sku\"\n      },\n      {\n        \"listing_field\": \"name\",\n        \"sku_field\": \"item_name\"\n      },\n      {\n        \"listing_field\": \"price\",\n        \"sku_field\": \"price\"\n      },\n      {\n        \"listing_field\": \"weight\",\n        \"sku_field\": \"weight\"\n      }\n    ]\n  },\n  \"message\": \"Field mappings updated successfully\"\n}"}]},{"name":"List Inventory Comparison","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Lists the inventory-comparison rows for a Magento 1 instance — one row per mapped product listing — comparing the SKU.io on-hand quantity against the last-known Magento 1 store quantity, with the variance and a per-row sync status (synced / variance / needs_recalc).\n\nAllowed sorts: id, sku_quantity, sales_channel_quantity, sales_channel_quantity_updated_at, sales_channel_quantity_synced_at, created_at, updated_at (default -id). Advanced search + status/quantity/datetime filters as listed. Paginated (default 10/page).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 7712,\n      \"product_listing_id\": 9001,\n      \"document_id\": 512,\n      \"sku\": \"ACME-HOODIE-M-BLU\",\n      \"title\": \"Acme Hoodie - Medium - Blue\",\n      \"product_sku\": \"ACME-HOODIE-M-BLU\",\n      \"sku_quantity\": 124,\n      \"sales_channel_quantity\": 118,\n      \"variance\": 6,\n      \"change_needed\": 6,\n      \"status\": \"variance\",\n      \"is_sku_recalculation_needed\": false,\n      \"sales_channel_quantity_updated_at\": \"2026-07-07T14:33:00+00:00\",\n      \"sales_channel_quantity_synced_at\": \"2026-07-06T09:10:00+00:00\",\n      \"sku_quantity_updated_at\": \"2026-07-07T15:00:00+00:00\",\n      \"created_at\": \"2026-01-04T09:15:00+00:00\",\n      \"updated_at\": \"2026-07-07T15:00:00+00:00\",\n      \"magento_product_id\": 8842\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Get Inventory Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Returns aggregate inventory statistics for a Magento 1 instance: total mapped items, in-sync count, variance count, needs-recalculation count, in-stock / out-of-stock counts, the last fetch and last push timestamps, and the (never-fetched) count. Powers the summary cards above the inventory comparison list.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/summary","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","summary"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_items\": 48,\n    \"in_sync\": 39,\n    \"with_variance\": 6,\n    \"needs_recalculation\": 3,\n    \"in_stock\": 44,\n    \"out_of_stock\": 4,\n    \"last_fetch_at\": \"2026-07-07T14:33:00+00:00\",\n    \"last_sync_at\": \"2026-07-06T09:10:00+00:00\",\n    \"needs_update\": 6,\n    \"never_fetched\": 2\n  }\n}"}]},{"name":"Fetch Inventory Levels (Tracked)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/fetch","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","fetch"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts a tracked job that reads the current stock level from Magento 1 for every mapped product and writes it into the comparison cache (the store-side column). Use this to refresh the Magento 1 quantities shown in the comparison before deciding what to push. Returns a `tracked_job_log_id` you can poll for progress.\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/fetch","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","fetch"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 48233\n  },\n  \"message\": \"Inventory refresh started\"\n}"}]},{"name":"Recache Inventory (Tracked)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts a tracked job that recomputes SKU.io on-hand quantities for every mapped product listing on the instance and refreshes the comparison cache. Use this when the SKU.io side is stale (status = needs_recalc). Returns a `tracked_job_log_id` you can poll for progress.\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/recache","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","recache"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 48231\n  },\n  \"message\": \"Inventory recache started\"\n}"}]},{"name":"Push Inventory (Tracked)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/push","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","push"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Starts a tracked job that pushes SKU.io on-hand quantities to Magento 1 for the mapped products with a variance. The outbound inventory sync gate (per-instance sync settings) is enforced inside the job — when outbound inventory sync is disabled the job still completes successfully, pushing nothing. Returns a `tracked_job_log_id` you can poll for progress.\n\nBody: none.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/magento1/instances/{integrationInstance}/inventory/push","host":["{{baseUrl}}"],"path":["api","magento1","instances",":integrationInstance","inventory","push"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 48232\n  },\n  \"message\": \"Inventory push started\"\n}"}]}]},{"name":"Shipfusion","item":[{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances"]},"description":"Create a new Shipfusion integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- name (string, required) — Unique name for the integration instance\n- integration_id (integer, required) — ID of the integration record (must exist in integrations table)\n- connection_settings (object, optional) — Shipfusion API credentials\n  - username (string) — Shipfusion API username\n  - password (string) — Shipfusion API password\n- integration_settings (object, optional) — Integration behavior settings\n  - enable_fulfillment (boolean) — Enable automated fulfillment via Shipfusion\n  - pass_tags (boolean) — Pass order tags to Shipfusion\n- is_automatic_sync_enabled (boolean, optional, default: false) — Enable automatic order/inventory syncing","body":{"mode":"raw","raw":"{\n  \"name\": \"My Shipfusion Account\",\n  \"integration_id\": 5,\n  \"connection_settings\": {\n    \"username\": \"sfuser@example.com\",\n    \"password\": \"sf_api_password\"\n  },\n  \"integration_settings\": {\n    \"enable_fulfillment\": true,\n    \"pass_tags\": false\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Shipfusion Account\",\n    \"integration_id\": 5,\n    \"connection_settings\": {\n      \"username\": \"sfuser@example.com\",\n      \"password\": \"***\"\n    },\n    \"integration_settings\": {\n      \"connection_name\": null,\n      \"linked_warehouse\": null,\n      \"enable_fulfillment\": true,\n      \"pass_tags\": false\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Retrieve a single Shipfusion integration instance by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Shipfusion Account\",\n    \"integration_id\": 5,\n    \"connection_settings\": {\n      \"username\": \"sfuser@example.com\",\n      \"password\": \"***\"\n    },\n    \"integration_settings\": {\n      \"connection_name\": null,\n      \"linked_warehouse\": null,\n      \"enable_fulfillment\": true,\n      \"pass_tags\": false\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Update a Shipfusion integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAll fields are optional — only include the ones you want to update.","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Shipfusion Account\",\n  \"integration_settings\": {\n    \"enable_fulfillment\": false,\n    \"pass_tags\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Shipfusion Account\",\n    \"integration_id\": 5,\n    \"connection_settings\": {\n      \"username\": \"sfuser@example.com\",\n      \"password\": \"***\"\n    },\n    \"integration_settings\": {\n      \"connection_name\": null,\n      \"linked_warehouse\": null,\n      \"enable_fulfillment\": false,\n      \"pass_tags\": true\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Delete a Shipfusion integration instance and all associated data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Integration instance deleted successfully\"\n}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get dashboard metrics for a Shipfusion integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns order counts by status, warehouse shipment counts by status, last sync timestamps, and sync frequency configuration.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders_by_status\": {\n      \"pending\": 12,\n      \"shipped\": 87,\n      \"cancelled\": 3\n    },\n    \"warehouse_shipments_by_status\": {\n      \"open\": 5,\n      \"closed\": 22\n    },\n    \"orders_last_synced_at\": \"2024-01-15T09:30:00.000000Z\",\n    \"warehouse_shipments_last_synced_at\": \"2024-01-15T09:30:00.000000Z\",\n    \"tracking_info_last_updated_at\": \"2024-01-15T08:00:00.000000Z\",\n    \"sync_frequency\": \"Every 30 minutes\",\n    \"tracking_update_frequency\": \"Every hour\"\n  }\n}"}]},{"name":"List Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List all warehouse mappings for a Shipfusion integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach mapping links a Shipfusion warehouse code (e.g. 'IL', 'CA') to a SKU.io warehouse.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_instance_id\": 1,\n      \"shipfusion_warehouse_code\": \"IL\",\n      \"shipfusion_warehouse_label\": \"Illinois\",\n      \"warehouse_id\": 3,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Warehouse Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Create a new warehouse mapping linking a Shipfusion warehouse code to a SKU.io warehouse.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipfusion_warehouse_code\": \"IL\",\n  \"warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_instance_id\": 1,\n    \"shipfusion_warehouse_code\": \"IL\",\n    \"shipfusion_warehouse_label\": \"Illinois\",\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Warehouse Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_code}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings",":warehouse_code"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_code","value":"IL","description":"Shipfusion warehouse code"}]},"description":"Update the SKU.io warehouse linked to a Shipfusion warehouse code.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_code}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings",":warehouse_code"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_code","value":"IL","description":"Shipfusion warehouse code"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_instance_id\": 1,\n    \"shipfusion_warehouse_code\": \"IL\",\n    \"shipfusion_warehouse_label\": \"Illinois\",\n    \"warehouse_id\": 5,\n    \"warehouse_name\": \"East Coast Warehouse\",\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Warehouse Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_code}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings",":warehouse_code"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_code","value":"IL","description":"Shipfusion warehouse code"}]},"description":"Delete a warehouse mapping by Shipfusion warehouse code.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_code}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-mappings",":warehouse_code"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_code","value":"IL","description":"Shipfusion warehouse code"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Warehouse mapping deleted successfully\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List Shipfusion orders for the integration instance (paginated). Each order carries its resolved SKU fulfillment link (`sku_fulfillment`) for the \"SKU Order\" card — resolved FulfillmentOrder-first so a deferred-FO order still links — plus the scalar tracking fields (`tracking_number`, `carrier`, `shipped_at`) derived from the order's stored payload (per-box detail lives on the separate Packages endpoint). Supports Spatie QueryBuilder filters, advanced filter operators, grouped filter trees, and sorting. Authenticate with a Personal Access Token (PAT) Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 12345,\n      \"integration_instance_id\": 4,\n      \"shipfusion_id\": \"SF-12345\",\n      \"order_number\": \"BG125116.1\",\n      \"shipment_status\": \"shipped\",\n      \"warehouse\": \"IL\",\n      \"order_date\": \"2026-05-25\",\n      \"sku_fulfillment_id\": 256917,\n      \"sku_fulfillment_order_id\": 4412,\n      \"sku_fulfillment\": {\n        \"id\": 256917,\n        \"link_reference\": 256917,\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 256917,\n        \"link_route\": \"/orders/sales-orders/fulfillments/256917\",\n        \"status\": \"shipped\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n        \"fulfilled_at\": \"2026-05-25T16:32:00+00:00\",\n        \"created_at\": \"2026-05-25T15:10:00+00:00\",\n        \"sales_order_id\": 88123,\n        \"sales_order_number\": \"SO-88123\",\n        \"fulfillment_order_id\": 4412,\n        \"warehouse\": {\n          \"id\": 7,\n          \"name\": \"Illinois DC\"\n        }\n      },\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS Ground\",\n      \"shipped_at\": \"2026-05-25T16:32:00.000000Z\",\n      \"has_detailed_data\": true,\n      \"details_last_updated\": \"2026-05-25T16:35:00.000000Z\",\n      \"created_at\": \"2026-05-20T09:00:00.000000Z\",\n      \"updated_at\": \"2026-05-25T16:35:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 17,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/orders?page=17\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/orders?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 167\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"SF-12345","description":"Shipfusion order number"}]},"description":"Get a specific Shipfusion order by its Shipfusion ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Delete Order","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"SF-12345","description":"Shipfusion order number"}]},"description":"Cancel/delete a Shipfusion order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Order Detail (JSON)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"101","description":"The order ID."}]},"description":"Get full detail for a single Shipfusion order. Returns the resource fields the standalone order detail page renders (id, integration_instance_id, shipfusion_id, order_number, shipment_status, warehouse, order_date, tracking_number, carrier, shipped_at, has_detailed_data, details_last_updated, timestamps), the linked `sku_fulfillment` card (resolved FulfillmentOrder-first so a deferred-FO order still links — a Sales Order Fulfillment, or the Fulfillment Order itself when the SOF has not been minted yet), AND the raw Shipfusion `json_object` (recipient address, shipmentItems, tracking packages) used by the detail page's expandable sections.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe `:order` path variable is the SKU primary key (route-model binding), matching the Fulfillment Order → provider-order cross-link route. Returns 404 if the order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token.\n\nThe response also includes a normalized `shipment_items` array (derived from `json_object.shipmentItems`) that the Items table renders. Each entry: `sku` (string|null), `product_id` (the EXTERNAL Shipfusion product id — not a SKU.io id, kept for reference only), `sku_product_id` (the resolved local SKU.io product id, used to link the SKU to its product detail page `/products/{sku_product_id}`; null when the SKU has no matching product), `quantity` (number|null), `status` (string|null), and `lot_number` (first lot number, string|null)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"101","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\",\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 7,\n    \"shipfusion_id\": \"SF-12345\",\n    \"order_number\": \"ORD-100245\",\n    \"shipment_status\": \"shipped\",\n    \"warehouse\": \"PA\",\n    \"order_date\": \"2026-06-20\",\n    \"sku_fulfillment_id\": 5582,\n    \"sku_fulfillment_order_id\": 12460,\n    \"sku_fulfillment\": {\n      \"id\": 5582,\n      \"link_reference\": 5582,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 5582,\n      \"link_route\": \"/orders/sales-orders/fulfillments/5582\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-06-21T14:32:00+00:00\",\n      \"created_at\": \"2026-06-20T09:15:00+00:00\",\n      \"sales_order_id\": 32861,\n      \"sales_order_number\": \"SO-32861\",\n      \"fulfillment_order_id\": 12460,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      }\n    },\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS Ground\",\n    \"shipped_at\": \"2026-06-21T14:32:00.000000Z\",\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-06-21T15:00:00.000000Z\",\n    \"created_at\": \"2026-06-20T09:15:00.000000Z\",\n    \"updated_at\": \"2026-06-21T15:00:00.000000Z\",\n    \"json_object\": {\n      \"id\": 987654,\n      \"shipmentId\": 987654,\n      \"orderNumber\": \"ORD-100245\",\n      \"orderReferenceNumber\": \"REF-100245\",\n      \"shipmentStatus\": \"shipped\",\n      \"warehouse\": \"PA\",\n      \"orderDate\": \"20260620\",\n      \"shipDate\": \"20260621\",\n      \"salesChannelTitle\": \"Shopify\",\n      \"shipmentInstructions\": \"Leave at front door\",\n      \"address\": {\n        \"firstName\": \"Jane\",\n        \"lastName\": \"Doe\",\n        \"address1\": \"123 Market St\",\n        \"address2\": \"Suite 400\",\n        \"city\": \"Philadelphia\",\n        \"state\": \"PA\",\n        \"zip\": \"19103\",\n        \"country\": \"US\",\n        \"phoneNumber\": \"+1 215-555-0142\",\n        \"emailAddress\": \"jane.doe@example.com\"\n      },\n      \"shipmentItems\": [\n        {\n          \"shipmentItemId\": 5511,\n          \"SKU\": \"WIDGET-BLK-01\",\n          \"qty\": 2,\n          \"itemStatus\": \"shipped\",\n          \"lotInformation\": [\n            {\n              \"lotNumber\": \"LOT-2026-0420\"\n            }\n          ]\n        }\n      ],\n      \"tracking\": {\n        \"totalPackages\": 1,\n        \"packages\": [\n          {\n            \"trackingStatus\": \"Delivered\",\n            \"shippingCarrier\": \"UPS\",\n            \"shippingService\": \"Ground\",\n            \"trackingNumber\": \"1Z999AA10123456784\",\n            \"trackingUrl\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n            \"shipDate\": \"20260621\",\n            \"dimensions\": {\n              \"lengthIn\": 12,\n              \"widthIn\": 9,\n              \"heightIn\": 4,\n              \"weightLb\": 2,\n              \"weightOz\": 6\n            }\n          }\n        ]\n      }\n    },\n    \"shipment_items\": [\n      {\n        \"sku\": \"WIDGET-BLK-01\",\n        \"product_id\": 1999637981,\n        \"sku_product_id\": 482,\n        \"quantity\": 2,\n        \"status\": \"shipped\",\n        \"lot_number\": \"LOT-2026-0420\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Raw Order Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order","raw"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"101","description":"The order ID."}]},"description":"Fetch the raw, un-persisted Shipfusion shipment JSON for a single order, live from the Shipfusion API. Mirrors the Shopify order detail \"Load Raw Data\" panel — it powers the ShipFusion order detail page's expandable \"Raw Data\" JSON tree viewer. Unlike `sync-detail`, this NEVER writes to the local row; it is a read-only transparency/debugging fetch.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nShipFusion exposes a single REST API (no GraphQL), so there is one source — no REST/GraphQL tabs.\n\nThe `:order` path variable is the SKU primary key (route-model binding). No request body, no query params.\n\nResponses:\n• 200 `{ data: <raw shipment JSON object> }` — the complete shipment payload straight from Shipfusion.\n• 200 `{ data: null, unavailable_reason: string }` — Shipfusion answered HTTP 200 but with `responseStatus: \"error\"` or a non-empty `errors` array (e.g. the order was just submitted and the warehouse has not populated shipment detail yet). The frontend shows the `unavailable_reason` message with a Retry button.\n• 404 `{ error }` — the order does not belong to the given integration instance.\n• 500 `{ error, message }` — the live fetch to Shipfusion failed (network/timeout/upstream error).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order","raw"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"101","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"responseStatus\": \"success\",\n    \"id\": 987654,\n    \"shipmentId\": 987654,\n    \"orderNumber\": \"ORD-100245\",\n    \"orderReferenceNumber\": \"REF-100245\",\n    \"shipmentStatus\": \"shipped\",\n    \"warehouse\": \"PA\",\n    \"orderDate\": \"20260620\",\n    \"shipDate\": \"20260621\",\n    \"salesChannelTitle\": \"Shopify\",\n    \"shipmentInstructions\": \"Leave at front door\",\n    \"address\": {\n      \"firstName\": \"Jane\",\n      \"lastName\": \"Doe\",\n      \"address1\": \"123 Market St\",\n      \"address2\": \"Suite 400\",\n      \"city\": \"Philadelphia\",\n      \"state\": \"PA\",\n      \"zip\": \"19103\",\n      \"country\": \"US\",\n      \"phoneNumber\": \"+1 215-555-0142\",\n      \"emailAddress\": \"jane.doe@example.com\"\n    },\n    \"shipmentItems\": [\n      {\n        \"shipmentItemId\": 5511,\n        \"SKU\": \"WIDGET-BLK-01\",\n        \"qty\": 2,\n        \"itemStatus\": \"shipped\",\n        \"lotInformation\": [\n          {\n            \"lotNumber\": \"LOT-2026-0420\"\n          }\n        ]\n      }\n    ],\n    \"tracking\": {\n      \"totalPackages\": 1,\n      \"packages\": [\n        {\n          \"trackingStatus\": \"Delivered\",\n          \"shippingCarrier\": \"UPS\",\n          \"shippingService\": \"Ground\",\n          \"trackingNumber\": \"1Z999AA10123456784\",\n          \"trackingUrl\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n          \"shipDate\": \"20260621\",\n          \"dimensions\": {\n            \"lengthIn\": 12,\n            \"widthIn\": 9,\n            \"heightIn\": 4,\n            \"weightLb\": 2,\n            \"weightOz\": 6\n          }\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Sync Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"101","description":"The order ID."}]},"description":"Fetch and store the latest detailed order data from the Shipfusion API for a specific order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Oldest Incomplete Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/oldest-incomplete","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders","oldest-incomplete"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get the oldest incomplete order for use in the sync modal UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Sync Orders (Queue Job)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job to sync all orders from Shipfusion for a given date range and optional status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Order Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"42","description":"The tracked job log ID."}]},"description":"Get progress of a queued order sync job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Update Tracking Info","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/orders/update-tracking","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","orders","update-tracking"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Trigger an update of tracking information for all shipped orders from this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"List Packages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/packages","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","packages"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of packages across all orders for this Shipfusion integration instance. Each package is promoted out of its parent order's `json_object.tracking.packages[]` array into its own row so packages are searchable by their per-package `tracking_number` (multi-package orders carry distinct tracking numbers that the order-level tracking_number drops) — mirroring the StarShipIt Order → Package model.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filtering, sorting, and pagination.\n\nFilters:\n- `filter[search]` — partial match across tracking_number, shipfusion_shipment_id, carrier_service_name, name, and the parent order's order_number\n- `filter[delivery_status]` — exact match on delivery status (e.g. Pending, InTransit, Delivered)\n- `filter[shipfusion_order_id]` — exact match on the local parent order id (shipfusion_orders.id)\n- Advanced per-column operators are available for: id (numeric), tracking_number, shipfusion_shipment_id, name, carrier, carrier_service_name, carrier_service_code, delivery_status, packaging_type, shipment_type (text), weight (numeric), shipped_at, label_created_date, created_at, updated_at (datetime)\n\nAllowed sorts: id, tracking_number, name, weight, delivery_status, carrier, carrier_service_name, packaging_type, shipment_type, shipped_at, label_created_date, created_at, updated_at, order (sorts by the related order number) (prefix with `-` for DESC; default `-id`).\n\nPagination: `page` (default 1), `per_page` (default 10).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/packages","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","packages"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 91234,\n      \"integration_instance_id\": 4,\n      \"shipfusion_order_id\": 60012,\n      \"package_index\": 0,\n      \"shipfusion_shipment_id\": \"SF-SHIP-88231\",\n      \"name\": \"Box 1\",\n      \"weight\": 0.81,\n      \"height\": 3,\n      \"width\": 6,\n      \"length\": 9,\n      \"packaging_type\": \"box\",\n      \"carrier\": \"DHL Global Mail\",\n      \"carrier_service_code\": \"ParcelsExpeditedDomestic\",\n      \"carrier_service_name\": \"Parcel Expedited Domestic\",\n      \"shipping_carrier_code\": \"DHLGlobalMail\",\n      \"shipping_method\": \"DHL Global Mail - Parcel Expedited Domestic\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://webtrack.dhlglobalmail.com/?trackingnumber=1Z999AA10123456784\",\n      \"delivery_status\": \"InTransit\",\n      \"shipment_type\": null,\n      \"shipped_at\": \"2025-01-28T00:00:00+00:00\",\n      \"label_created_date\": null,\n      \"order\": {\n        \"id\": 60012,\n        \"order_number\": \"LS-100245\",\n        \"shipfusion_id\": \"884412\",\n        \"link_reference\": \"LS-100245\",\n        \"link_type_label\": \"Shipfusion Order\",\n        \"link_id\": 60012,\n        \"link_route\": \"/integrations/shipfusion/4/orders/60012\"\n      },\n      \"sku_sales_order_fulfillment_id\": 33421,\n      \"sku_fulfillment_id\": null,\n      \"sku_fulfillment_status\": \"fulfilled\",\n      \"sales_order_id\": 77810,\n      \"sales_order_number\": \"SO-55231\",\n      \"sales_order_legacy_url\": \"/sales-orders/77810\",\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"ShipFusion - Cincinnati\"\n      },\n      \"created_at\": \"2025-01-28T14:21:09+00:00\",\n      \"updated_at\": \"2025-01-28T14:21:09+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/packages?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/packages?page=12\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/packages?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shipfusion/integration-instances/{{integration_instance}}/packages\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 116\n}"}]},{"name":"Get Package","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/packages/{package}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","packages",":package"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"package","value":"91234","description":"Local shipfusion_packages.id"}]},"description":"Fetch a single Shipfusion package by its local id, scoped to the integration instance (returns 404 if the package belongs to a different instance). The full provider `json_object` for the package is always included on this detail endpoint (the endpoint forces `include_json=1`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAlso includes `shipment_items` — the normalized line items for this package's shipment. ShipFusion tracks items at the shipment (order) level rather than per physical package, so each item is resolved from the parent order's `json_object.shipmentItems` first, falling back to the package's own embedded items. Each item carries `sku`, `product_id`, `quantity`, `status`, and `lot_number`. `shipment_items` is only present when `include_json` is set; the index (List Packages) endpoint does not return it.\n\nIncludes SKU.io linkage — the package's own SalesOrderFulfillment plus the parent order's legacy order→SOF link as a transition fallback — and a cross-link payload pointing back at the parent Shipfusion order.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/packages/{package}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","packages",":package"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"package","value":"91234","description":"Local shipfusion_packages.id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 91234,\n    \"integration_instance_id\": 4,\n    \"shipfusion_order_id\": 60012,\n    \"package_index\": 0,\n    \"shipfusion_shipment_id\": \"SF-SHIP-88231\",\n    \"name\": \"Box 1\",\n    \"weight\": 0.81,\n    \"height\": 3,\n    \"width\": 6,\n    \"length\": 9,\n    \"packaging_type\": \"box\",\n    \"carrier\": \"DHL Global Mail\",\n    \"carrier_service_code\": \"ParcelsExpeditedDomestic\",\n    \"carrier_service_name\": \"Parcel Expedited Domestic\",\n    \"shipping_carrier_code\": \"DHLGlobalMail\",\n    \"shipping_method\": \"DHL Global Mail - Parcel Expedited Domestic\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://webtrack.dhlglobalmail.com/?trackingnumber=1Z999AA10123456784\",\n    \"delivery_status\": \"InTransit\",\n    \"shipment_type\": null,\n    \"shipped_at\": \"2025-01-28T00:00:00+00:00\",\n    \"label_created_date\": null,\n    \"order\": {\n      \"id\": 60012,\n      \"order_number\": \"LS-100245\",\n      \"shipfusion_id\": \"884412\",\n      \"link_reference\": \"LS-100245\",\n      \"link_type_label\": \"Shipfusion Order\",\n      \"link_id\": 60012,\n      \"link_route\": \"/integrations/shipfusion/4/orders/60012\"\n    },\n    \"sku_sales_order_fulfillment_id\": 33421,\n    \"sku_fulfillment_id\": null,\n    \"sku_fulfillment_status\": \"fulfilled\",\n    \"sales_order_id\": 77810,\n    \"sales_order_number\": \"SO-55231\",\n    \"sales_order_legacy_url\": \"/sales-orders/77810\",\n    \"warehouse\": {\n      \"id\": 12,\n      \"name\": \"ShipFusion - Cincinnati\"\n    },\n    \"created_at\": \"2025-01-28T14:21:09+00:00\",\n    \"updated_at\": \"2025-01-28T14:21:09+00:00\",\n    \"shipment_items\": [\n      {\n        \"sku\": \"100233\",\n        \"product_id\": 1999637981,\n        \"quantity\": 1,\n        \"status\": \"shipped\",\n        \"lot_number\": \"25320\"\n      },\n      {\n        \"sku\": \"100663\",\n        \"product_id\": 1999637421,\n        \"quantity\": 2,\n        \"status\": \"shipped\",\n        \"lot_number\": null\n      }\n    ],\n    \"json_object\": {\n      \"shipmentItems\": [\n        {\n          \"SKU\": \"100233\",\n          \"productId\": 1999637981,\n          \"qty\": 1,\n          \"itemStatus\": \"shipped\",\n          \"lotInformation\": [\n            {\n              \"lotNumber\": \"25320\"\n            }\n          ]\n        },\n        {\n          \"SKU\": \"100663\",\n          \"productId\": 1999637421,\n          \"qty\": 2,\n          \"itemStatus\": \"shipped\",\n          \"lotInformation\": []\n        }\n      ],\n      \"shippingCarrier\": \"DHL Global Mail\",\n      \"shippingService\": \"Parcel Expedited Domestic\",\n      \"shippingCarrierCode\": \"DHLGlobalMail\",\n      \"shippingServiceCode\": \"ParcelsExpeditedDomestic\",\n      \"shipDate\": \"20250128\",\n      \"shipTimestamp\": 1762273047,\n      \"trackingNumber\": \"1Z999AA10123456784\",\n      \"trackingUrl\": \"https://webtrack.dhlglobalmail.com/?trackingnumber=1Z999AA10123456784\",\n      \"trackingStatus\": \"InTransit\",\n      \"dimensions\": {\n        \"lengthIn\": 9,\n        \"widthIn\": 6,\n        \"heightIn\": 3,\n        \"type\": \"box\",\n        \"weightOz\": 13,\n        \"weightLb\": 0.81\n      }\n    }\n  }\n}"}]},{"name":"List Warehouse Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List all warehouse shipments (inbound) for a Shipfusion integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Warehouse Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments/{warehouse_shipment}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments",":warehouse_shipment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_shipment","value":"WS-5001","description":"Shipfusion warehouse shipment number"}]},"description":"Get a specific warehouse shipment by its Shipfusion ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Warehouse Shipment Detail (JSON)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments/{warehouse_shipment}/detail","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments",":warehouse_shipment","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_shipment","value":"201","description":"The warehouse shipment ID."}]},"description":"Get the full raw JSON detail for a warehouse shipment as returned by the Shipfusion API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Sync Warehouse Shipment Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments/{warehouse_shipment}/sync-detail","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments",":warehouse_shipment","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"warehouse_shipment","value":"201","description":"The warehouse shipment ID."}]},"description":"Fetch and store the latest detailed data for a warehouse shipment from the Shipfusion API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Sync Warehouse Shipments (Queue Job)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments/sync","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job to sync all warehouse shipments from Shipfusion for a given date range.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Warehouse Shipment Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/warehouse-shipments/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","warehouse-shipments","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"43","description":"The tracked job log ID."}]},"description":"Get progress of a queued warehouse shipment sync job.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/webhook-events","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List all Shipfusion webhook events for an integration instance, with pagination.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Show Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"301","description":"The webhook event ID."}]},"description":"Get a single Shipfusion webhook event by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Retry Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/webhook-events/{webhook_event}/retry","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","webhook-events",":webhook_event","retry"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"301","description":"The webhook event ID."}]},"description":"Retry processing an unprocessed Shipfusion webhook event.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Refresh Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/refresh","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","refresh"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Refresh inventory data from the Shipfusion API for a specific warehouse.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse\": \"IL\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Inventory Discrepancies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/discrepancies","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","discrepancies"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get inventory discrepancies between SKU.io quantities and Shipfusion quantities.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Items Without SKU Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/without-sku-products","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","without-sku-products"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get Shipfusion inventory items that do not have a corresponding SKU.io product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Products Without Shipfusion Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/without-shipfusion-inventory","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","without-shipfusion-inventory"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get SKU.io products that do not have a corresponding Shipfusion inventory record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Create Stock Take from Discrepancies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/create-stock-take","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","create-stock-take"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Create a SKU.io stock take from selected Shipfusion inventory discrepancies.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    12,\n    15,\n    22\n  ],\n  \"notes\": \"Stock take created from Shipfusion discrepancy report\",\n  \"date\": \"2024-01-15\",\n  \"status\": \"draft\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Product Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/product-movements?product_id=12","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","product-movements"],"query":[{"key":"product_id","value":"12","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get recent inventory movements for a specific product across warehouses mapped to this Shipfusion integration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Last Synced At","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipfusion/integration-instances/{integration_instance}/inventory/last-synced-at","host":["{{baseUrl}}"],"path":["api","shipfusion","integration-instances",":integration_instance","inventory","last-synced-at"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Get the timestamp of the last successful inventory sync from Shipfusion.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}}]},{"name":"ShipHero","item":[{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances"]},"description":"Create a new ShipHero integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"ShipHero Production\",\n  \"integration_id\": 8,\n  \"connection_settings\": {},\n  \"integration_settings\": {\n    \"connection_name\": \"main\",\n    \"enable_fulfillment\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Retrieve a ShipHero integration instance by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Update a ShipHero integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"ShipHero Production\",\n  \"integration_id\": 8,\n  \"connection_settings\": {},\n  \"integration_settings\": {\n    \"connection_name\": \"main\",\n    \"enable_fulfillment\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Delete a ShipHero integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Show Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Aggregated dashboard metrics for the ShipHero integration instance: order counts grouped by fulfillment status, total orders, mapped warehouse count, last sync timestamps, sync cadence, and webhook health.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders_by_status\": {\n      \"pending\": 12,\n      \"fulfilled\": 340,\n      \"canceled\": 5\n    },\n    \"total_orders\": 357,\n    \"warehouse_count\": 3,\n    \"orders_last_synced_at\": \"2026-06-15T08:02:11.000000Z\",\n    \"tracking_info_last_updated_at\": \"2026-06-15T08:10:00.000000Z\",\n    \"sync_frequency\": \"On demand\",\n    \"tracking_update_frequency\": \"Every 10 minutes\",\n    \"webhook_health\": {\n      \"registered\": true,\n      \"last_received_at\": \"2026-06-14T22:45:00.000000Z\"\n    }\n  }\n}"}]},{"name":"List Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/warehouses","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","warehouses"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"List all ShipHero warehouses alongside local SKU.io warehouses.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Download Warehouses from ShipHero","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/warehouses/download","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","warehouses","download"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Fetch and cache warehouses from the ShipHero API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Map Warehouses","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/warehouses/map","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","warehouses","map"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Map ShipHero warehouses to SKU.io local warehouses.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"payload\": [\n    {\n      \"id\": 1,\n      \"warehouse_id\": 1\n    },\n    {\n      \"id\": 2,\n      \"warehouse_id\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Inventory","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/refresh","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","refresh"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Trigger a full inventory sync from ShipHero API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 1\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Inventory Discrepancies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/discrepancies?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","discrepancies"],"query":[{"key":"warehouse_id","value":"1","disabled":true}],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Get inventory discrepancies between SKU.io and ShipHero.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Items Without SKU Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/without-sku-products?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","without-sku-products"],"query":[{"key":"warehouse_id","value":"1","disabled":true}],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"List ShipHero inventory items that do not have a matching SKU.io product.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get SKU Products Without ShipHero Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/without-shiphero-inventory?warehouse_id=1","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","without-shiphero-inventory"],"query":[{"key":"warehouse_id","value":"1","disabled":true}],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"List SKU.io products that do not have corresponding inventory records in ShipHero.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Get Last Synced At","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/last-synced-at","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","last-synced-at"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Get the timestamp of the most recent successful inventory sync from ShipHero.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Create Stock Take From Discrepancies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/create-stock-take","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","create-stock-take"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Create a SKU.io stock take from the selected ShipHero inventory discrepancies. The stock take counts each product at its ShipHero on-hand quantity.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body:**\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| product_ids | array of integers | optional | Product IDs to include. Each must exist in `products`. **Empty array (or omitted) = \"stock take all\"**: every visible discrepancy is included (kits excluded by default — see `include_kits`). |\n| warehouse_id | integer | optional | Warehouse to scope discrepancies to. Must exist in `warehouses`. Defaults to the first mapped warehouse. |\n| notes | string | optional | Custom notes (max 500 chars). Defaults to an auto-generated note referencing the warehouse. |\n| date | string | optional | Stock take date in `Y-m-d` format. Defaults to today. |\n| status | string | optional | One of `draft`, `open`, `closed`. Defaults to `draft`. `open` initiates the count; `closed` initiates and finalizes it. |\n| include_kits | boolean | optional | Default `false`. Only meaningful for a \"stock take all\" (empty `product_ids`). ShipHero reports 0 on hand for kit SKUs (inventory lives on the components), so kits are excluded by default to avoid zeroing out their SKU.io on-hand inventory. Set `true` to include them anyway; `excluded_kit_count` in the response will then be 0. |\n\n**Response (`data`):**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| stock_take | object | The created stock take record. |\n| stock_take_url | string | Tenant URL to the stock take detail page (`/v2/inventory/stock-takes/{id}`). |\n| selected_count | integer | Number of discrepancies included in the stock take. |\n| total_value_adjustment | string | Sum of discrepancy values, formatted to 2 decimal places. |\n| excluded_kit_count | integer | Number of kit SKUs excluded from a \"stock take all\" (0 when `include_kits` is true or when specific `product_ids` were given). |\n\n**Errors:** Returns `422` with a `message` when no warehouse mapping exists, no discrepancies match the criteria, or the specified warehouse is not mapped.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    42,\n    57,\n    88\n  ],\n  \"warehouse_id\": 1,\n  \"notes\": \"Stock take from ShipHero discrepancies May 2024\",\n  \"date\": \"2024-05-01\",\n  \"status\": \"draft\",\n  \"include_kits\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Product Inventory Movements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory/product-movements?product_id=42&limit=10","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory","product-movements"],"query":[{"key":"product_id","value":"42","disabled":true},{"key":"limit","value":"10","description":"Maximum number of results to return.","disabled":true}],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Get recent inventory movements for a specific product in ShipHero-mapped warehouses.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"List ShipHero orders for the integration instance, newest first. Canonical list view endpoint (Spatie QueryBuilder); returns a paginated list of lightweight order rows.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuick search (filter[search]): matches ID (exact), order number (partial), and ShipHero ID (partial). Restrict which columns are searched with search_columns (allowed: id, order_number, shiphero_id); force exact matching on a column with search_strict_columns.\n\nFilters (all optional):\n- filter[fulfillment_status]: exact ShipHero fulfillment_status (pending, fulfilled, canceled).\n- filter[has_fulfillment]: true/1 = linked to a SKU.io fulfillment; false/0 = unlinked; omit for all.\n- filter[sku_fulfillment_id]: exact linked SalesOrderFulfillment id.\n- Per-column advanced filters with operators: filter[id], filter[order_number], filter[shiphero_id], filter[fulfillment_status], filter[created_at], filter[updated_at].\n\nSort (sort): id, order_number, fulfillment_status, created_at, updated_at. Prefix with - for descending. Default: -id.\nPagination: page, per_page (default 10).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1024,\n      \"integration_instance_id\": 8,\n      \"shiphero_id\": \"T3JkZXI6MTIzNDU2\",\n      \"order_number\": \"SO-100245\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"fulfillment_status_label\": \"Fulfilled\",\n      \"fulfillment_status_color\": \"success\",\n      \"order_date\": \"2026-06-10\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"shipped_at\": \"2026-06-11T14:32:00.000000Z\",\n      \"sku_fulfillment\": {\n        \"id\": 55231,\n        \"link_reference\": \"FUL-100245\",\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 55231,\n        \"link_route\": \"/orders/sales-orders/fulfillments/55231\",\n        \"status\": \"shipped\",\n        \"sales_order_id\": 4021,\n        \"sales_order_number\": \"SO-100245\",\n        \"fulfillment_order_id\": 9876\n      },\n      \"created_at\": \"2026-06-10T09:15:00.000000Z\",\n      \"updated_at\": \"2026-06-11T14:32:05.000000Z\"\n    },\n    {\n      \"id\": 1025,\n      \"integration_instance_id\": 8,\n      \"shiphero_id\": \"T3JkZXI6MTIzNDU3\",\n      \"order_number\": \"SO-100246\",\n      \"fulfillment_status\": \"pending\",\n      \"fulfillment_status_label\": \"Pending\",\n      \"fulfillment_status_color\": \"warning\",\n      \"order_date\": \"2026-06-12\",\n      \"tracking_number\": null,\n      \"tracking_url\": null,\n      \"carrier\": null,\n      \"shipped_at\": null,\n      \"sku_fulfillment\": null,\n      \"created_at\": \"2026-06-12T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-12T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"from\": 1,\n  \"to\": 2,\n  \"last_page\": 1,\n  \"total\": 2\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"T3JkZXI6MTIzNDU2","description":"The order ID."}]},"description":"Get a single ShipHero order by its ShipHero id (the `shiphero_id`, not the local row id).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"T3JkZXI6MTIzNDU2","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"integration_instance_id\": 8,\n    \"shiphero_id\": \"T3JkZXI6MTIzNDU2\",\n    \"order_number\": \"SO-100245\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"sku_fulfillment_id\": 55231,\n    \"has_fulfillment\": true,\n    \"order_date\": \"2026-06-10\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipped_at\": \"2026-06-11T14:32:00.000000Z\",\n    \"created_at\": \"2026-06-10T09:15:00.000000Z\",\n    \"updated_at\": \"2026-06-11T14:32:05.000000Z\"\n  }\n}"}]},{"name":"Get Order Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Get the full decoded ShipHero JSON object for an order (by local row id via route-model binding). `has_detailed_data` is false when no raw payload has been cached yet.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"json_object\": {\n      \"order_number\": \"SO-100245\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"order_date\": \"2026-06-10T09:15:00+00:00\",\n      \"shipping_labels\": [\n        {\n          \"tracking_number\": \"1Z999AA10123456784\",\n          \"carrier\": \"UPS\",\n          \"created_date\": \"2026-06-11T14:32:00+00:00\"\n        }\n      ]\n    },\n    \"has_detailed_data\": true\n  }\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Queue a tracked background job that re-syncs every open order for the integration instance and applies any new tracking. Returns the tracked job log id so the frontend can poll progress.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nIf a sync is already pending/processing for this instance, responds 409 SyncInProgress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9912\n  },\n  \"message\": \"Order sync job has been queued\"\n}"}]},{"name":"Get Order Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"9912","description":"The tracked job log ID."}]},"description":"Fetch the progress of a queued order sync job by its tracked job log id.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"9912","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9912,\n    \"job_type\": \"tenant_aware\",\n    \"queue\": \"default\",\n    \"job_name\": \"Sync Shiphero Orders: ShipHero Main\",\n    \"status\": \"processing\",\n    \"related_model\": {\n      \"id\": 8,\n      \"type\": \"Modules\\\\Shiphero\\\\Entities\\\\ShipheroIntegrationInstance\",\n      \"reference\": \"ShipHero Main\"\n    },\n    \"related_model_reference\": \"ShipHero Main\",\n    \"messages\": [],\n    \"attempted_at\": \"2026-06-15T08:02:00.000000Z\",\n    \"completed_at\": null,\n    \"duration\": null,\n    \"created_at\": \"2026-06-15T08:01:59.000000Z\",\n    \"updated_at\": \"2026-06-15T08:02:30.000000Z\",\n    \"results\": null,\n    \"total_items\": 357,\n    \"processed_items\": 120,\n    \"progress_percentage\": 33.61,\n    \"progress_mode\": \"count\",\n    \"stages\": null\n  }\n}"}]},{"name":"Import Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/import","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","import"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Queue a tracked background job that **imports** orders from ShipHero within a date window — treating ShipHero as an order *source*, not just a fulfillment target. Each imported order is FK-linked to its matching SKU entity by `order_number` (writing the real `sku_fulfillment_order_id` / `sku_fulfillment_id`); true orphans are imported unlinked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the tracked job log id so the frontend can poll progress (via Get Order Sync Progress).\n\nIf an import is already pending/processing for this instance, responds 409 ImportInProgress.\n\n**Request body (all optional):**\n- `mode` — fetch mode: `since_latest` | `from_start_date` | `date_range` | `all`. Defaults to `all` (unbounded full re-sync of the entire order history).\n- `date_from` — ISO date; the window start for `from_start_date` and `date_range`.\n- `date_to` — ISO date; the window end for `date_range`.\n- `date_method` — `created` | `updated`. For `date_range`, selects which ShipHero timestamp the window filters on (default `created`).\n- `latest_date` — ISO date anchor for `since_latest` (falls back to the stored last-sync cursor).\n\n**Mode → window mapping:** `since_latest` → `updated_from` = latest_date/cursor; `from_start_date` → `order_date_from` = date_from; `date_range` (created) → `order_date_from`/`order_date_to`; `date_range` (updated) → `updated_from`/`updated_to`; `all` → unbounded.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\",\n  \"date_method\": \"created\",\n  \"latest_date\": \"2026-06-15T08:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/import","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","import"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 9913\n  },\n  \"message\": \"Order import job has been queued\"\n}"}]},{"name":"Get Order Import Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/import-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","import-info"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]},"description":"Import UI metadata for the shared Refresh Orders modal:\n- `last_synced_at` — the \"since latest\" anchor. Prefers the persisted import cursor, falling back to the most recently imported order's `updated_at` when no cursor has been recorded yet.\n- `latest_identifier` — the most recently imported order's `order_number` (null when no orders exist).\n- `total_orders` — total imported order count for the instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/import-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","import-info"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"last_synced_at\": \"2026-06-29T22:14:05.000000Z\",\n    \"latest_identifier\": \"SO-1042.1\",\n    \"total_orders\": 1284\n  }\n}"}]},{"name":"Search Orders by Number","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Search ShipHero live for an order by its order number and return whether it already exists locally. Use this to pull a specific order the incremental import misses — e.g. a manual or backdated order created earlier than the last synced order (which \"fetch new since latest\" can never reach). Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"query\": \"129120541727222.1\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"T3JkZXI6OTk5\",\n      \"name\": \"129120541727222.1\",\n      \"email\": null,\n      \"createdAt\": null,\n      \"financialStatus\": null,\n      \"fulfillmentStatus\": \"fulfilled\",\n      \"totalPrice\": null,\n      \"currency\": null,\n      \"existsInDatabase\": false\n    }\n  ]\n}"}]},{"name":"Import Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Import (or update) a single ShipHero order by its ShipHero id — the `id` returned by Search Orders by Number. Fetches the order live and persists it locally, linking it to a matching sales-order fulfillment when the order number lines up. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"T3JkZXI6OTk5\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 41,\n    \"order_number\": \"129120541727222.1\"\n  },\n  \"message\": \"Order imported from ShipHero\"\n}"}]},{"name":"Sync Single Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Re-fetch a single order from ShipHero and apply any new tracking. Orders linked to a SalesOrderFulfillment refresh their tracking; FO-first orders (the deferred-shipment path — linked only to a FulfillmentOrder, not yet to a fulfillment) get their thin order_create stub enriched with the full order GET. Returns 422 OrderNotLinked only when the order is linked to neither a fulfillment nor a fulfillment order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1024,\n    \"integration_instance_id\": 8,\n    \"shiphero_id\": \"T3JkZXI6MTIzNDU2\",\n    \"order_number\": \"SO-100245\",\n    \"fulfillment_status\": \"fulfilled\",\n    \"sku_fulfillment_id\": 55231,\n    \"has_fulfillment\": true,\n    \"order_date\": \"2026-06-10\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipped_at\": \"2026-06-11T14:32:00.000000Z\",\n    \"created_at\": \"2026-06-10T09:15:00.000000Z\",\n    \"updated_at\": \"2026-06-11T14:32:05.000000Z\"\n  }\n}"}]},{"name":"Update Order From Fulfillment (Power User)","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","shiphero","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"202","description":"The sales order fulfillment ID."}]},"description":"Re-push a sales order fulfillment to ShipHero. Requires Power User role.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + is_power_user middleware."}},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]},"description":"Paginated Spatie activity-log entries for a single ShipHero order (by local row id) — the order detail page's Activity Log section. Each entry: id, description, event (created/updated/deleted), subject_type, subject_id, properties (changed attributes), causer_name, created_at. Ordered newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: page (default 1), per_page (default 15).\n\nAuthentication: Requires Bearer token.\n\nFilters: filter[event] (exact event), filter[source] (matches properties->source), filter[batch_uuid] (exact batch uuid), filter[search] (LIKE over causer name / properties / event)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"8","description":"The integration instance ID."},{"key":"order","value":"1024","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90412,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"ShipheroOrder\",\n      \"subject_id\": 1024,\n      \"properties\": {\n        \"attributes\": {\n          \"fulfillment_status\": \"fulfilled\"\n        },\n        \"old\": {\n          \"fulfillment_status\": \"pending\"\n        }\n      },\n      \"causer_name\": \"Sync Job\",\n      \"created_at\": \"2026-06-11T14:33:00.000000Z\"\n    },\n    {\n      \"id\": 90380,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"ShipheroOrder\",\n      \"subject_id\": 1024,\n      \"properties\": {\n        \"attributes\": {\n          \"order_number\": \"SO-100245\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-10T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shiphero/...?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Server-side paginated + filterable ShipHero shipments. Filters: carrier (exact), shipping_method (exact), has_order_link (true/false), search (tracking_number / order_number / shiphero_shipment_id / carrier). Sortable: id, order_number, tracking_number, carrier, shipping_method, cost, created_date, created_at, updated_at (default -created_date).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 15,\n      \"integration_instance_id\": 1,\n      \"shiphero_shipment_id\": \"U2hpcG1lbnQ6OTg3NjU0\",\n      \"shiphero_legacy_id\": \"1122334455\",\n      \"order_id\": 1,\n      \"shiphero_order_id\": \"T3JkZXI6MTIzNDU2Nzg5\",\n      \"order_number\": \"SO-100245\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"shipping_name\": \"UPS Ground\",\n      \"shipping_method\": \"ground\",\n      \"cost\": 8.45,\n      \"insurance_amount\": 0,\n      \"warehouse_id\": 3,\n      \"warehouse\": \"Primary DC\",\n      \"carrier_account_id\": \"ca_8842\",\n      \"source\": \"shiphero\",\n      \"shipped_off_shiphero\": false,\n      \"dropshipment\": false,\n      \"created_date\": \"2024-06-03T08:14:00.000Z\",\n      \"created_at\": \"2024-06-03T08:14:02.000000Z\",\n      \"updated_at\": \"2024-06-03T08:14:05.000000Z\",\n      \"order\": {\n        \"id\": 1,\n        \"order_number\": \"SO-100245\",\n        \"shiphero_id\": \"T3JkZXI6MTIzNDU2Nzg5\",\n        \"link_reference\": \"SO-100245\",\n        \"link_type_label\": \"ShipHero Order\",\n        \"link_id\": 1,\n        \"link_route\": \"/integrations/shiphero/1/orders/1\"\n      },\n      \"sku_sales_order_fulfillment_id\": 88,\n      \"sku_fulfillment_id\": 88,\n      \"sku_fulfillment_status\": \"shipped\",\n      \"sales_order_id\": 55,\n      \"sales_order_number\": \"SO-2024-0055\",\n      \"sku_fulfillment_route\": \"/orders/sales-orders/fulfillments/88\",\n      \"warehouse_link\": {\n        \"id\": 3,\n        \"name\": \"Primary DC\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 10,\n  \"last_page\": 3,\n  \"total\": 27,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments",":shipment"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"shipment","value":"12","description":"The shipment ID."}]},"description":"Single ShipHero shipment by local row id. Append include_json=1 for the raw payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments",":shipment"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"shipment","value":"12","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 15,\n    \"integration_instance_id\": 1,\n    \"shiphero_shipment_id\": \"U2hpcG1lbnQ6OTg3NjU0\",\n    \"shiphero_legacy_id\": \"1122334455\",\n    \"order_id\": 1,\n    \"shiphero_order_id\": \"T3JkZXI6MTIzNDU2Nzg5\",\n    \"order_number\": \"SO-100245\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipping_name\": \"UPS Ground\",\n    \"shipping_method\": \"ground\",\n    \"cost\": 8.45,\n    \"insurance_amount\": 0,\n    \"warehouse_id\": 3,\n    \"warehouse\": \"Primary DC\",\n    \"carrier_account_id\": \"ca_8842\",\n    \"source\": \"shiphero\",\n    \"shipped_off_shiphero\": false,\n    \"dropshipment\": false,\n    \"created_date\": \"2024-06-03T08:14:00.000Z\",\n    \"created_at\": \"2024-06-03T08:14:02.000000Z\",\n    \"updated_at\": \"2024-06-03T08:14:05.000000Z\",\n    \"order\": {\n      \"id\": 1,\n      \"order_number\": \"SO-100245\",\n      \"shiphero_id\": \"T3JkZXI6MTIzNDU2Nzg5\",\n      \"link_reference\": \"SO-100245\",\n      \"link_type_label\": \"ShipHero Order\",\n      \"link_id\": 1,\n      \"link_route\": \"/integrations/shiphero/1/orders/1\"\n    },\n    \"sku_sales_order_fulfillment_id\": 88,\n    \"sku_fulfillment_id\": 88,\n    \"sku_fulfillment_status\": \"shipped\",\n    \"sales_order_id\": 55,\n    \"sales_order_number\": \"SO-2024-0055\",\n    \"sku_fulfillment_route\": \"/orders/sales-orders/fulfillments/88\",\n    \"warehouse_link\": {\n      \"id\": 3,\n      \"name\": \"Primary DC\"\n    }\n  }\n}"}]},{"name":"Sync Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments","sync"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Queue a tracked job that syncs shipments from ShipHero's GraphQL `shipments` query (cursor-paginated). Job name: `Sync Shiphero Shipments: {instance}`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body (all optional):\n- `mode` (string) — sync mode. One of: `since_latest`, `date_range`, `all`.\n    - `since_latest` — pass `date_from` set to the latest synced shipment's created date (bounded window through now).\n    - `date_range` — pass an explicit `date_from` / `date_to` window.\n    - `all` — FULL re-sync: leaves the window unbounded so ShipHero returns the entire shipment history. `date_from` / `date_to` are ignored.\n- `date_from` (ISO 8601 datetime) — lower bound. Ignored when `mode=all`.\n- `date_to` (ISO 8601 datetime) — upper bound. Ignored when `mode=all`.\n\nWhen `mode` is omitted, a missing date window defaults to the last 30 days.\n\nReturns 409 if a shipments sync is already in progress for this integration.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-05-25T00:00:00Z\",\n  \"date_to\": \"2026-06-25T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments","sync"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90871\n  },\n  \"message\": \"Shipments sync job has been queued\"\n}"}]},{"name":"Get Shipments Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/sync-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments","sync-info"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Latest synced shipment + total count, for the sync UI.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/shipments/sync-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","shipments","sync-info"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_shipment_identifier\": \"9405550105799029788980\",\n    \"latest_shipment_date\": \"2026-06-24T13:29:00.000000Z\",\n    \"total_shipments\": 190\n  }\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Paginated list of ShipHero products — one row per SKU with on-hand/available/allocated/backorder summed across warehouses, plus the number of stocking warehouses and the mapped local product, plus the ShipHero product id (shiphero_product_legacy_id). Filters: kit (true/false), mapped (mapped/unmapped), search. Sortable: sku, name, on_hand, available, allocated, backorder, warehouse_count, value, last_synced_at. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"CABLE-USB-C\",\n      \"name\": \"USB-C Cable\",\n      \"barcode\": \"693400391793911\",\n      \"shiphero_product_id\": \"UHJvZHVjdEluZm86MTIz\",\n      \"on_hand\": 412,\n      \"available\": 388,\n      \"allocated\": 24,\n      \"backorder\": 0,\n      \"reserve\": 0,\n      \"non_sellable\": 0,\n      \"warehouse_count\": 2,\n      \"value\": 5.5,\n      \"price\": 9.99,\n      \"kit\": false,\n      \"last_synced_at\": \"2026-07-20T17:52:26.000000Z\",\n      \"mapped_product\": {\n        \"id\": 459,\n        \"name\": \"USB-C Cable\"\n      },\n      \"shiphero_product_legacy_id\": 333360642\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 78,\n  \"per_page\": 10,\n  \"total\": 778,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products/{sku}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products",":sku"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"sku","value":"CABLE-USB-C","description":"The sku ID."}]},"description":"Full detail for one ShipHero product: per-warehouse inventory breakdown, summed totals, richer product fields (barcode, dimensions, value, country, tariff, tags, images, kit) and the mapped local SKU product. The sku path segment is URL-encoded. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products/{sku}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products",":sku"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"sku","value":"CABLE-USB-C","description":"The sku ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sku\": \"CABLE-USB-C\",\n    \"name\": \"USB-C Cable\",\n    \"barcode\": \"693400391793911\",\n    \"shiphero_product_id\": \"UHJvZHVjdEluZm86MTIz\",\n    \"ship_hero_product_id\": 1024,\n    \"needs_review\": false,\n    \"value\": \"5.5000\",\n    \"price\": \"9.9900\",\n    \"kit\": false,\n    \"country_of_manufacture\": \"US\",\n    \"tariff_code\": \"\",\n    \"dimensions\": {\n      \"height\": \"1.0000 inch\",\n      \"width\": \"0.50 inch\",\n      \"length\": \"4.00 inch\",\n      \"weight\": \"0.0600 lb\"\n    },\n    \"images\": [],\n    \"tags\": [],\n    \"shiphero_updated_at\": \"2026-07-01T23:32:03\",\n    \"totals\": {\n      \"on_hand\": 412,\n      \"available\": 388,\n      \"allocated\": 24,\n      \"backorder\": 0,\n      \"reserve\": 0,\n      \"non_sellable\": 0\n    },\n    \"warehouse_count\": 2,\n    \"last_synced_at\": \"2026-07-20T17:52:26.000000Z\",\n    \"warehouses\": [\n      {\n        \"warehouse_id\": 4,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"shiphero_warehouse_id\": \"V2FyZWhvdXNlOjExNTQxNQ==\",\n        \"on_hand\": 300,\n        \"available\": 288,\n        \"allocated\": 12,\n        \"backorder\": 0,\n        \"reserve\": 0,\n        \"non_sellable\": 0\n      }\n    ],\n    \"mapped_product\": {\n      \"id\": 459,\n      \"sku\": \"ABC-123\",\n      \"name\": \"USB-C Cable\"\n    }\n  }\n}"}]},{"name":"Set Product SKU Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products/{shipHeroProduct}/mapping","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products",":shipHeroProduct","mapping"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"shipHeroProduct","value":"1024","description":"ShipHero product id (the mapping mirror row, from the products list / detail)."}]},"description":"Sets or clears the SKU.io product mapping for a ShipHero product. Pass `sku_product_id` to map this ShipHero SKU to a SKU.io product, or `null` to unmap. Use this when a fulfillment provider holds stock under a SKU that differs from your own (a SKU they will not rename): once mapped, the ShipHero SKU resolves to the mapped product across the products list, inventory reconciliation, and fulfillment submission. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_product_id\": 459\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/products/{shipHeroProduct}/mapping","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","products",":shipHeroProduct","mapping"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"shipHeroProduct","value":"1024","description":"ShipHero product id (the mapping mirror row, from the products list / detail)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"ship_hero_product_id\": 1024,\n    \"sku\": \"amzn.gr.2968014-FBA-AaEE6yfT22OThjupL-LN\",\n    \"sku_product_id\": 459,\n    \"needs_review\": false,\n    \"mapped_product\": {\n      \"id\": 459,\n      \"sku\": \"ABC-123\",\n      \"name\": \"USB-C Cable\"\n    }\n  },\n  \"message\": \"Product mapped.\"\n}"}]},{"name":"List Inventory Changes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Server-side paginated, filterable audit trail of ShipHero inventory movements. Each row is one inventory change with the signed delta, human-readable reason, category, and who/where/when. Filters: category (comma-separated), warehouse_id, shiphero_warehouse_id, cycle_counted (true/false), search. Also searchable/sortable by id and shiphero_change_id. Sortable: id, changed_at, sku, change_in_on_hand, new_on_hand, previous_on_hand, category, created_at. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4412,\n      \"shiphero_change_id\": 1409175962,\n      \"sku\": \"SU400-939-3057\",\n      \"product\": {\n        \"id\": 459,\n        \"name\": \"Premium Widget\"\n      },\n      \"category\": \"pick\",\n      \"category_label\": \"Pick\",\n      \"previous_on_hand\": 298,\n      \"change_in_on_hand\": -1,\n      \"new_on_hand\": 297,\n      \"cycle_counted\": false,\n      \"reason_text\": \"Order #FP2075.1 picked into tote Tote-325. Pick type: mib\",\n      \"reference_type\": \"order\",\n      \"reference_number\": \"#FP2075.1\",\n      \"shiphero_reference_url\": \"https://app.shiphero.com/dashboard/orders/details/804491805\",\n      \"warehouse\": {\n        \"id\": 4,\n        \"name\": \"Main Warehouse\"\n      },\n      \"shiphero_warehouse_id\": 115415,\n      \"location_name\": \"E-05-06-A-03\",\n      \"location_zone\": \"A\",\n      \"shiphero_user_id\": 716769,\n      \"changed_at\": \"2026-04-27T16:19:50.000000Z\",\n      \"created_at\": \"2026-07-20T20:25:47.000000Z\",\n      \"shiphero_order\": {\n        \"id\": 1995,\n        \"order_number\": \"SXC14895.1\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 18,\n  \"per_page\": 10,\n  \"total\": 179,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Inventory Audit KPI Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/kpi-stats","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","kpi-stats"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Summary KPIs for the inventory audit trail — total changes, net change, increases, decreases, adjustments, cycle counts, and a per-category breakdown. Honors the same filters as the list endpoint (pass the same filter[...] query params). Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/kpi-stats","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","kpi-stats"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_changes\": 179,\n    \"net_change\": 125,\n    \"increases\": 81,\n    \"decreases\": 95,\n    \"adjustments\": 2,\n    \"cycle_counts\": 0,\n    \"by_category\": {\n      \"pick\": 57,\n      \"transfer\": 72,\n      \"receive\": 27,\n      \"return\": 12,\n      \"ship\": 6,\n      \"adjustment\": 2,\n      \"location_add\": 3\n    },\n    \"range\": {\n      \"from\": \"2026-07-14 17:51:22\",\n      \"to\": \"2026-07-20 20:25:46\"\n    }\n  }\n}"}]},{"name":"Get Inventory Audit Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/sync-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","sync-info"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Metadata for the inventory audit sync UI — the most recent recorded movement time and the total number of changes stored. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/sync-info","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","sync-info"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_changed_at\": \"2026-07-20T20:25:46.000000Z\",\n    \"total_changes\": 179\n  }\n}"}]},{"name":"Export Inventory Audit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/export","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","export"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Download the inventory audit trail as an Excel (.xlsx) or CSV file. The export honors the active filters (scope=filtered) or can export all, the current page, or a selected set of ids. Returns a binary file download, not JSON. Requires a Bearer token."}},{"name":"Sync Inventory Audit","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","sync"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]},"description":"Queue a background job that pulls ShipHero inventory changes into the audit ledger. mode: since_latest (incremental from the latest recorded change, pass date_from), date_range (pass date_from + date_to), or all (full history). Returns the tracked job id. Returns 409 if a sync is already running for this integration. Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"date_from\": \"2026-07-14\",\n  \"date_to\": \"2026-07-20\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/sync","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit","sync"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90210\n  },\n  \"message\": \"Inventory audit sync job has been queued\"\n}"}]},{"name":"Get Inventory Change","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/{inventoryChange}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit",":inventoryChange"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"inventoryChange","value":"4412","description":"The inventory change ID."}]},"description":"Get a single inventory change by its local id, with the resolved product and warehouse. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shiphero/integration-instances/{integration_instance}/inventory-audit/{inventoryChange}","host":["{{baseUrl}}"],"path":["api","shiphero","integration-instances",":integration_instance","inventory-audit",":inventoryChange"],"variable":[{"key":"integration_instance","value":"38","description":"The integration instance ID."},{"key":"inventoryChange","value":"4412","description":"The inventory change ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4412,\n    \"shiphero_change_id\": 1409175962,\n    \"sku\": \"SU400-939-3057\",\n    \"product\": {\n      \"id\": 459,\n      \"name\": \"Premium Widget\"\n    },\n    \"category\": \"pick\",\n    \"category_label\": \"Pick\",\n    \"previous_on_hand\": 298,\n    \"change_in_on_hand\": -1,\n    \"new_on_hand\": 297,\n    \"cycle_counted\": false,\n    \"reason_text\": \"Order #FP2075.1 picked into tote Tote-325. Pick type: mib\",\n    \"reference_type\": \"order\",\n    \"reference_number\": \"#FP2075.1\",\n    \"shiphero_reference_url\": \"https://app.shiphero.com/dashboard/orders/details/804491805\",\n    \"warehouse\": {\n      \"id\": 4,\n      \"name\": \"Main Warehouse\"\n    },\n    \"shiphero_warehouse_id\": 115415,\n    \"location_name\": \"E-05-06-A-03\",\n    \"location_zone\": \"A\",\n    \"shiphero_user_id\": 716769,\n    \"changed_at\": \"2026-04-27T16:19:50.000000Z\",\n    \"created_at\": \"2026-07-20T20:25:47.000000Z\",\n    \"shiphero_order\": {\n      \"id\": 1995,\n      \"order_number\": \"SXC14895.1\"\n    }\n  }\n}"}]}]},{"name":"ShipStation","item":[{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances"]},"description":"Creates a new ShipStation integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOn success the manager immediately dispatches the initial background sync jobs for the new instance: auto-subscribe webhooks, sync warehouses, sync shipping methods, sync orders, and sync shipments (tracking info). Each sync surfaces via the tracked job log endpoints.\n\nBody fields:\n- name (string, required): display name for the instance. Must be unique across all integration instances (validated by a unique rule and re-checked in the manager, which returns 422 with `Provider name (X) already exists` on conflict).\n- connection_settings (object, required): ShipStation V1 API credentials.\n  - connection_settings.apiKey (string, required in practice): ShipStation API Key.\n  - connection_settings.apiSecret (string, required in practice): ShipStation API Secret.\n  - connection_settings.timezone (string, optional): IANA timezone used to interpret ShipStation's local timestamps. Defaults to America/Los_Angeles (ShipStation V1 returns PST/PDT timestamps).\n- integration_settings (object, optional): initial integration settings (see Update for the full key list). Defaults to `{}`.\n  - integration_settings.sync_enabled (boolean): whether automatic order syncing is on.\n  - integration_settings.order_start_date (date string or null): earliest order date to sync. When not set, syncs fall back to the Inventory Start Date, then a fixed 30-day window.\n  - integration_settings.auto_submit_fulfillments (boolean): submit fulfillments automatically without manual review.\n- is_automatic_sync_enabled (boolean, optional): toggle the hourly scheduled syncs for this instance.\n\nResponse: `data.id` and `data.name` of the created instance.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"ShipStation US\",\n  \"connection_settings\": {\n    \"apiKey\": \"ss_live_a1b2c3d4e5f6\",\n    \"apiSecret\": \"ss_secret_f6e5d4c3b2a1\",\n    \"timezone\": \"America/Los_Angeles\"\n  },\n  \"integration_settings\": {\n    \"sync_enabled\": true,\n    \"order_start_date\": \"2026-05-11\",\n    \"auto_submit_fulfillments\": true\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"ShipStation US\"\n  }\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a single ShipStation integration instance with its connection settings and integration settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- id (int), name (string), integration_id (int)\n- connection_settings (object): apiKey, apiSecret, timezone\n- integration_settings (object): connection_name, enable_fulfillment, order_start_date, auto_submit_fulfillments, settings (legacy ShipStation options such as productFieldToPass, gift_card_note_sales_order_custom_field_id, saturday_delivery_sales_order_custom_field_id, send_sales_order_tags_as_notes), fulfillment_cost_financial_line_type_id, and fulfillment (per-warehouse routing: enabledWarehousesIds / automatedWarehousesIds)\n- is_automatic_sync_enabled (boolean)\n- created_at / updated_at (ISO 8601)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"ShipStation US\",\n    \"integration_id\": 27,\n    \"connection_settings\": {\n      \"apiKey\": \"ss_live_a1b2c3d4e5f6\",\n      \"apiSecret\": \"ss_secret_f6e5d4c3b2a1\",\n      \"timezone\": \"America/Los_Angeles\"\n    },\n    \"integration_settings\": {\n      \"connection_name\": \"ShipStation US\",\n      \"enable_fulfillment\": true,\n      \"order_start_date\": \"2026-01-01\",\n      \"auto_submit_fulfillments\": true,\n      \"settings\": {\n        \"productFieldToPass\": \"sku\",\n        \"send_sales_order_tags_as_notes\": false\n      },\n      \"fulfillment_cost_financial_line_type_id\": 4,\n      \"fulfillment\": {\n        \"enabledWarehousesIds\": [\n          1,\n          2\n        ],\n        \"automatedWarehousesIds\": [\n          1\n        ]\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-05-01T10:15:00+00:00\",\n    \"updated_at\": \"2026-06-09T18:42:11+00:00\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Update an existing ShipStation integration instance. All fields are optional. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- name (optional, string)\n- connection_settings (optional, object): API credentials\n- integration_settings (optional, object). Includes:\n  - fulfillment_cost_financial_line_type_id (optional, int|null): COST financial line type used for ShipStation shipping cost lines. null = auto (default \"Shipping Cost\"). Must be a cost type or returns 422.\n- is_automatic_sync_enabled (optional, boolean)\n\nWhen the effective cost-line type changes, a reconcile tracked job is dispatched and the response includes reconcile_tracked_job_log_id.","body":{"mode":"raw","raw":"{\n  \"name\": \"US ShipStation\",\n  \"integration_settings\": {\n    \"fulfillment_cost_financial_line_type_id\": 29\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"ShipStation US\",\n    \"integration_id\": 27,\n    \"connection_settings\": {\n      \"apiKey\": \"ss_live_a1b2c3d4e5f6\",\n      \"apiSecret\": \"ss_secret_f6e5d4c3b2a1\",\n      \"timezone\": \"America/Los_Angeles\"\n    },\n    \"integration_settings\": {\n      \"connection_name\": \"ShipStation US\",\n      \"enable_fulfillment\": true,\n      \"order_start_date\": \"2026-01-01\",\n      \"auto_submit_fulfillments\": true,\n      \"settings\": {\n        \"productFieldToPass\": \"sku\",\n        \"send_sales_order_tags_as_notes\": false\n      },\n      \"fulfillment_cost_financial_line_type_id\": 4,\n      \"fulfillment\": {\n        \"enabledWarehousesIds\": [\n          1,\n          2\n        ],\n        \"automatedWarehousesIds\": [\n          1\n        ]\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-05-01T10:15:00+00:00\",\n    \"updated_at\": \"2026-06-09T18:42:11+00:00\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Deletes a ShipStation integration instance. The deletion runs asynchronously — a background job removes the instance and its related data (orders, warehouses, shipping method mappings, webhook events/subscriptions).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Integration instance deleted successfully\"\n}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns dashboard metrics for a ShipStation integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse fields (camelCase, serialized from ShipstationDashboardMetricsData):\n- totalOrders (int): total synced ShipStation orders for the instance\n- ordersByStatus (array): one row per ShipStation order status (awaiting_payment, awaiting_shipment, pending_fulfillment, shipped, on_hold, cancelled, rejected_fulfillment, unknown) with status, status_label and count (zero-filled for statuses with no orders)\n- ordersByCarrier (array): up to 20 carriers ordered by count desc, each {carrier, count}\n- totalWarehouses (int): synced ShipStation warehouses\n- unprocessedWebhookEvents (int) / failedWebhookEvents (int): webhook event queue health\n- activeWebhookSubscriptions (int)\n- ordersLastSyncedAt / trackingInfoLastUpdatedAt / warehousesLastSyncedAt (ISO 8601 or null): last sync timestamps\n- unlinkedOrders (int): ShipStation orders not linked to a SKU fulfillment\n- schedules (object): sync schedule metadata keyed by orders, tracking_info, warehouses — each {frequency: 'Hourly' | 'Manual only', seconds_until_next: int | null} powering the dashboard countdown\n- ordersChart (array): one {date, orders_count} row per day for the last 30 days (oldest first, zero-filled)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalOrders\": 1245,\n    \"ordersByStatus\": [\n      {\n        \"status\": \"awaiting_payment\",\n        \"status_label\": \"Awaiting Payment\",\n        \"count\": 12\n      },\n      {\n        \"status\": \"awaiting_shipment\",\n        \"status_label\": \"Awaiting Shipment\",\n        \"count\": 86\n      },\n      {\n        \"status\": \"pending_fulfillment\",\n        \"status_label\": \"Pending Fulfillment\",\n        \"count\": 9\n      },\n      {\n        \"status\": \"shipped\",\n        \"status_label\": \"Shipped\",\n        \"count\": 1098\n      },\n      {\n        \"status\": \"on_hold\",\n        \"status_label\": \"On Hold\",\n        \"count\": 5\n      },\n      {\n        \"status\": \"cancelled\",\n        \"status_label\": \"Cancelled\",\n        \"count\": 30\n      },\n      {\n        \"status\": \"rejected_fulfillment\",\n        \"status_label\": \"Rejected Fulfillment\",\n        \"count\": 2\n      },\n      {\n        \"status\": \"unknown\",\n        \"status_label\": \"Unknown\",\n        \"count\": 3\n      }\n    ],\n    \"ordersByCarrier\": [\n      {\n        \"carrier\": \"stamps_com\",\n        \"count\": 640\n      },\n      {\n        \"carrier\": \"ups\",\n        \"count\": 310\n      },\n      {\n        \"carrier\": \"fedex\",\n        \"count\": 148\n      }\n    ],\n    \"totalWarehouses\": 3,\n    \"unprocessedWebhookEvents\": 4,\n    \"failedWebhookEvents\": 1,\n    \"activeWebhookSubscriptions\": 2,\n    \"ordersLastSyncedAt\": \"2026-06-10T08:00:12+00:00\",\n    \"trackingInfoLastUpdatedAt\": \"2026-06-10T08:05:43+00:00\",\n    \"warehousesLastSyncedAt\": \"2026-06-09T15:21:07+00:00\",\n    \"unlinkedOrders\": 17,\n    \"schedules\": {\n      \"orders\": {\n        \"frequency\": \"Hourly\",\n        \"seconds_until_next\": 1820\n      },\n      \"tracking_info\": {\n        \"frequency\": \"Hourly\",\n        \"seconds_until_next\": 1820\n      },\n      \"warehouses\": {\n        \"frequency\": \"Manual only\",\n        \"seconds_until_next\": null\n      }\n    },\n    \"ordersChart\": [\n      {\n        \"date\": \"2026-05-12\",\n        \"orders_count\": 38\n      },\n      {\n        \"date\": \"2026-05-13\",\n        \"orders_count\": 42\n      },\n      {\n        \"date\": \"2026-05-14\",\n        \"orders_count\": 0\n      },\n      {\n        \"date\": \"2026-05-15\",\n        \"orders_count\": 51\n      }\n    ]\n  }\n}"}]},{"name":"Get Orders Chart (Date Range)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders-chart?start_date=2026-05-11&end_date=2026-06-10","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders-chart"],"query":[{"key":"start_date","value":"2026-05-11","description":"Start date of the range (YYYY-MM-DD). Required.","disabled":true},{"key":"end_date","value":"2026-06-10","description":"End date of the range (YYYY-MM-DD). Must be on or after start_date. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a daily order-count time series for a ShipStation integration instance over the given date range, powering the dashboard orders trend chart's custom range selection.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains one bucket per day in [start_date, end_date] (oldest first), counting orders by their order_date and filling zero-counts for days with no orders so the chart x-axis is continuous.\n\nQuery parameters:\n- start_date (required, date e.g. YYYY-MM-DD): start of the range\n- end_date (required, date e.g. YYYY-MM-DD): end of the range; must be on or after start_date\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders-chart?start_date=2026-05-11&end_date=2026-06-10","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders-chart"],"query":[{"key":"start_date","value":"2026-05-11","description":"Start date of the range (YYYY-MM-DD). Required.","disabled":true},{"key":"end_date","value":"2026-06-10","description":"End date of the range (YYYY-MM-DD). Must be on or after start_date. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"date\": \"2026-05-11\",\n      \"orders_count\": 0\n    },\n    {\n      \"date\": \"2026-05-12\",\n      \"orders_count\": 38\n    },\n    {\n      \"date\": \"2026-05-13\",\n      \"orders_count\": 42\n    },\n    {\n      \"date\": \"2026-05-14\",\n      \"orders_count\": 7\n    }\n  ]\n}"}]},{"name":"Test Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Tests the ShipStation API connection for an integration instance by calling the ShipStation V1 List Warehouses endpoint with the instance's stored apiKey/apiSecret.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Returns 200 with `Connection successful` when ShipStation responds successfully, or 400 when the request fails (invalid credentials, network error, etc.).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Connection successful\"\n}"}]},{"name":"Preview Cost Line Type Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/cost-line-type/preview","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","cost-line-type","preview"],"variable":[{"key":"integrationInstance","value":"6","description":"ShipStation integration instance ID"}]},"description":"Preview how many ShipStation cost financial lines and sales orders would be touched if the fulfillment-cost financial line type changed to new_type_id. Read-only. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- new_type_id (optional, int|null): Proposed cost financial line type id. null = auto default. Must exist.\n\nDrives the confirmation modal before saving the setting.","body":{"mode":"raw","raw":"{\n  \"new_type_id\": 29\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/cost-line-type/preview","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","cost-line-type","preview"],"variable":[{"key":"integrationInstance","value":"6","description":"ShipStation integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rewire_lines\": 12,\n    \"backfill_lines\": 340,\n    \"sales_orders_impacted\": 351,\n    \"is_noop\": false\n  }\n}"}]},{"name":"Update Fulfillment Routing","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/fulfillment-routing","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","fulfillment-routing"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Saves per-warehouse fulfillment routing for a ShipStation integration instance — which SKU warehouses participate in ShipStation fulfillment and which of those are pushed automatically (no manual review). Stored under integration_settings.fulfillment.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (both must be present, arrays of warehouse ids):\n- enabledWarehousesIds (`array<int>`, required/present): warehouses that participate in ShipStation fulfillment\n- automatedWarehousesIds (`array<int>`, required/present): subset of enabled warehouses whose fulfillments are pushed automatically. Ids not also present in enabledWarehousesIds are silently dropped. Returns 422 if any warehouse is already automated by another integration instance.\n\nResponse: the saved `fulfillment` object plus a confirmation message.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"enabledWarehousesIds\": [\n    1,\n    2,\n    3\n  ],\n  \"automatedWarehousesIds\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/fulfillment-routing","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","fulfillment-routing"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"fulfillment\": {\n      \"enabledWarehousesIds\": [\n        1,\n        2,\n        3\n      ],\n      \"automatedWarehousesIds\": [\n        1,\n        2\n      ]\n    }\n  },\n  \"message\": \"Fulfillment routing saved\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10).","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of locally cached ShipStation orders for an integration instance (default sort `-id`, default 10 per page). Eager loads the linked SKU fulfillment (+ sales order number and warehouse).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Free-text search** — `filter[search]` searches `order_number`, `tracking_number`, `shipstation_order_id`, `customer_name`. Prefers the Scout/Typesense index (fast substring search); falls back to column-aware DB LIKE. `search_columns` restricts which columns are searched; `search_strict_columns` switches listed columns to exact `=` match. A fully-strict search always runs on the DB.\n\n**Simple filters** — `filter[order_status]`, `filter[carrier_code]`, `filter[sku_fulfillment_id]` (exact); `filter[has_fulfillment]`, `filter[has_tracking]` (true/false); `filter[date_from]`, `filter[date_to]` (order_date bounds).\n\n**Advanced operator filters** — `filter[<column>.<operator>]=value` (bare `filter[<column>]=value` acts as implicit `is`):\n- Text columns (`order_number`, `shipstation_order_id`, `order_key`, `tracking_number`, `customer_name`, `order_status`, `carrier_code`, `service_code`): contains, does_not_contain, is, is_not, is_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty\n- Numeric column (`id`): is, is_not, is_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty\n- Date column (`order_date`) and datetime columns (`ship_date`, `created_at`, `updated_at` — timezone-aware): is, is_not, before, after, on_or_before, on_or_after, between, is_empty, is_not_empty, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days\n\n**Grouped filters** — `filter_groups` (base64 JSON on GET; plain JSON in a POST body) applies a nested AND/OR condition tree against the same registered columns, taking precedence over flat filters.\n\n**Sorting** — `sort` accepts: id, order_number, customer_name, order_date, order_status, created_at, updated_at, ship_date, carrier_code, tracking_number (prefix `-` for descending; default `-id`).\n\n**Response fields of note** — `tracking_url` is resolved server-side from carrier_code + tracking_number (null when the carrier is unknown); `customer_name` is searchable/filterable; `sku_fulfillment` is a cross-link object (route, sales order number, warehouse) or null; `json_object` is only included when `include_json=1`.\n\nAuthentication: Requires Bearer token.\n\nEach order includes a `shipments` array of linked ShipStation shipment rows (tracking number/URL, carrier + service, cost, voided / return-label flags, ship date, and a `link_route` to the shipment detail page), sorted by ship date descending."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default 10).","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 412,\n      \"integration_instance_id\": 7,\n      \"shipstation_order_id\": 987654321,\n      \"order_key\": \"a1b2c3d4e5f6\",\n      \"order_number\": \"C604018.1\",\n      \"order_status\": \"shipped\",\n      \"order_status_label\": \"Shipped\",\n      \"order_status_color\": \"success\",\n      \"customer_email\": \"jane@example.com\",\n      \"order_date\": \"2026-06-01T14:22:10+00:00\",\n      \"ship_date\": \"2026-06-02T18:05:00+00:00\",\n      \"ship_by_date\": \"2026-06-04T07:00:00+00:00\",\n      \"carrier_code\": \"fedex\",\n      \"service_code\": \"fedex_ground\",\n      \"tracking_number\": \"781234567890\",\n      \"tracking_url\": \"https://www.fedex.com/fedextrack/?trknbr=781234567890\",\n      \"shipments\": [\n        {\n          \"id\": 101,\n          \"shipstation_shipment_id\": 987654321,\n          \"tracking_number\": \"9400111899560000000001\",\n          \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n          \"carrier_code\": \"stamps_com\",\n          \"service_code\": \"usps_priority_mail\",\n          \"package_code\": \"package\",\n          \"confirmation\": \"delivery\",\n          \"shipment_cost\": 7.42,\n          \"voided\": false,\n          \"is_return_label\": false,\n          \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n          \"create_date\": \"2026-06-08T14:22:10+00:00\",\n          \"link_route\": \"/integrations/shipstation/4/shipments/101\"\n        }\n      ],\n      \"sku_fulfillment\": {\n        \"id\": 650,\n        \"link_reference\": 650,\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 650,\n        \"link_route\": \"/orders/sales-orders/fulfillments/650\",\n        \"status\": \"fulfilled\",\n        \"tracking_number\": \"781234567890\",\n        \"tracking_url\": \"https://www.fedex.com/fedextrack/?trknbr=781234567890\",\n        \"fulfilled_at\": \"2026-06-02T18:06:11+00:00\",\n        \"created_at\": \"2026-06-01T14:30:00+00:00\",\n        \"sales_order_number\": \"C604018\",\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\"\n        }\n      },\n      \"has_detailed_data\": true,\n      \"details_last_updated\": \"2026-06-02T18:10:00+00:00\",\n      \"created_at\": \"2026-06-01T14:25:00+00:00\",\n      \"updated_at\": \"2026-06-02T18:10:00+00:00\"\n    },\n    {\n      \"id\": 411,\n      \"integration_instance_id\": 7,\n      \"shipstation_order_id\": 987654300,\n      \"order_key\": \"f6e5d4c3b2a1\",\n      \"order_number\": \"C604011.1\",\n      \"order_status\": \"awaiting_shipment\",\n      \"order_status_label\": \"Awaiting Shipment\",\n      \"order_status_color\": \"warning\",\n      \"customer_email\": \"bob@example.com\",\n      \"order_date\": \"2026-06-01T09:11:42+00:00\",\n      \"ship_date\": null,\n      \"ship_by_date\": \"2026-06-03T07:00:00+00:00\",\n      \"carrier_code\": null,\n      \"service_code\": null,\n      \"tracking_number\": null,\n      \"tracking_url\": null,\n      \"shipments\": [\n        {\n          \"id\": 101,\n          \"shipstation_shipment_id\": 987654321,\n          \"tracking_number\": \"9400111899560000000001\",\n          \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n          \"carrier_code\": \"stamps_com\",\n          \"service_code\": \"usps_priority_mail\",\n          \"package_code\": \"package\",\n          \"confirmation\": \"delivery\",\n          \"shipment_cost\": 7.42,\n          \"voided\": false,\n          \"is_return_label\": false,\n          \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n          \"create_date\": \"2026-06-08T14:22:10+00:00\",\n          \"link_route\": \"/integrations/shipstation/4/shipments/101\"\n        }\n      ],\n      \"sku_fulfillment\": null,\n      \"has_detailed_data\": false,\n      \"details_last_updated\": null,\n      \"created_at\": \"2026-06-01T09:15:00+00:00\",\n      \"updated_at\": \"2026-06-01T09:15:00+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/7/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 21,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/7/orders?page=21\",\n  \"links\": [],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/7/orders?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/7/orders\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 10,\n  \"total\": 204\n}"}]},{"name":"Search Orders (Live)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Search ShipStation **live** for orders matching a phrase, for the refresh modal's \"Search Specific Order\" tab. ShipStation's V1 `orderNumber` filter is a **starts-with** match, so the query should be an order number or its prefix (up to 50 results are fetched). Each result is flagged with whether it already exists in this instance's local cache so the UI can offer Download (new) vs Update (existing).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters:**\n- `query` — **required** string (max 255). The order number (or prefix) to search for.\n\n**Errors:**\n- 422 if `query` is missing or exceeds 255 chars\n- 502 if the upstream ShipStation call fails (message: `Search failed: ...`)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"query\": \"C604018\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shipstation_order_id\": 987654321,\n      \"order_number\": \"C604018.1\",\n      \"status\": \"shipped\",\n      \"order_date\": \"2026-06-01T07:22:10.0000000\",\n      \"email\": \"jane@example.com\",\n      \"exists_in_database\": true,\n      \"database_id\": 412\n    },\n    {\n      \"shipstation_order_id\": 987654399,\n      \"order_number\": \"C604018.2\",\n      \"status\": \"awaiting_shipment\",\n      \"order_date\": \"2026-06-01T07:25:44.0000000\",\n      \"email\": \"jane@example.com\",\n      \"exists_in_database\": false,\n      \"database_id\": null\n    }\n  ],\n  \"status\": \"Success\"\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background orders sync from ShipStation into the local cache. Dispatches a tracked job (a background job, job name `Sync ShipStation Orders: {instance name}`) and returns its `tracked_job_log_id` for polling via the tracked job log endpoints or the `sync-progress` endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters (all optional):**\n- `mode` — string. One of `since_latest` | `date_range` | `all`. With `all` the job ignores any start date and pulls full history; with `date_range` use `date_from`/`date_to`; with `since_latest` the job resumes from the most recently synced order.\n- `date_from` — date/datetime string (Carbon-parseable). Start bound for the fetch. (`since_date` is accepted as a deprecated alias for backward compatibility with the previous one-click refresh payload.)\n- `date_to` — date/datetime string (Carbon-parseable). Optional end bound (date_range mode).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"date_range\",\n  \"date_from\": \"2026-05-01\",\n  \"date_to\": \"2026-05-31\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 5821\n  },\n  \"message\": \"Order sync queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Header data for the orders refresh modal: the most recently dated order (number + ISO-8601 order date), the total cached order count, and the effective **order start date** the \"Fetch from Start Date\" sync option will use.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`order_start_date_source` explains where the start date came from, falling back in order:\n1. `ShipStation Order Start Date` — set on the integration instance\n2. `Inventory Start Date` — the general inventory settings start date\n3. `Default sync window (last 30 days)` — a fixed 30-day window used when neither start date is configured\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_number\": \"C604018.1\",\n    \"latest_order_date\": \"2026-06-01T14:22:10+00:00\",\n    \"total_orders\": 204,\n    \"order_start_date\": \"2025-01-01\",\n    \"order_start_date_source\": \"ShipStation Order Start Date\"\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"5821","description":"The tracked_job_log_id returned by POST /orders/sync."}]},"description":"Poll the progress of a queued orders sync by its tracked job log id (returned by POST `/orders/sync`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job must be a ShipStation sync (`job_name` starting with `Sync ShipStation`) belonging to this integration instance — matched either by the job name suffix (`: {instance name}`) or by the log's related model (`ShipstationIntegrationInstance` + instance id). Anything else returns **404 Job not found** (also returned when the id does not exist).\n\n`status` is the TrackedJobLog status enum value (e.g. `pending`, `processing`, `completed`, `failed`, `cancelled`).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"5821","description":"The tracked_job_log_id returned by POST /orders/sync."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5821,\n    \"status\": \"processing\",\n    \"job_name\": \"Sync ShipStation Orders: My ShipStation\",\n    \"total_items\": 500,\n    \"processed_items\": 240,\n    \"progress_percentage\": 48,\n    \"messages\": [\n      \"Fetched page 3 of 5\"\n    ],\n    \"results\": null,\n    \"completed_at\": null\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Refresh Single Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Download (or update) a single order **live** from ShipStation by its ShipStation order id and upsert it into the local cache with detailed data (`has_detailed_data: true`, `details_last_updated` stamped). Backs the search tab's per-result Download/Update buttons. Newly downloaded orders are auto-linked to a matching SKU fulfillment when an unambiguous match exists.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters:**\n- `uniqueId` — **required** string. The ShipStation order id (`shipstation_order_id` / `orderId`, as returned by the live search endpoint).\n\nReturns the persisted order serialized with `json_object` included.\n\n**Errors:**\n- 422 if `uniqueId` is missing\n- 502 if the upstream ShipStation fetch or persistence fails (message: `Failed to refresh order: ...`)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"987654321\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 412,\n    \"integration_instance_id\": 7,\n    \"shipstation_order_id\": 987654321,\n    \"order_key\": \"a1b2c3d4e5f6\",\n    \"order_number\": \"C604018.1\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane@example.com\",\n    \"order_date\": \"2026-06-01T14:22:10+00:00\",\n    \"ship_date\": \"2026-06-02T18:05:00+00:00\",\n    \"ship_by_date\": \"2026-06-04T07:00:00+00:00\",\n    \"carrier_code\": \"fedex\",\n    \"service_code\": \"fedex_ground\",\n    \"tracking_number\": \"781234567890\",\n    \"tracking_url\": \"https://www.fedex.com/fedextrack/?trknbr=781234567890\",\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-06-10T11:02:33+00:00\",\n    \"created_at\": \"2026-06-01T14:25:00+00:00\",\n    \"updated_at\": \"2026-06-10T11:02:33+00:00\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderNumber\": \"C604018.1\",\n      \"orderStatus\": \"shipped\",\n      \"items\": [\n        {\n          \"sku\": \"WIDGET-1\",\n          \"quantity\": 2\n        }\n      ]\n    }\n  },\n  \"message\": \"Order refreshed from ShipStation\",\n  \"status\": \"Success\"\n}"}]},{"name":"Submit Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/submit-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","submit-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Manually re-dispatch a SKU.io SalesOrderFulfillment's sales order to ShipStation via the canonical operator-initiated FulfillmentDispatcher. On the `defer_dispatch_sof` canary this submits the FulfillmentOrder with NO SalesOrderFulfillment at submit (the shipment SOF is minted at ship); it is idempotent — already-submitted FulfillmentOrders are skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters:**\n- `sku_fulfillment_id` — **required** integer. A SalesOrderFulfillment id; its sales order is dispatched.\n\n**Errors:**\n- 400 if `sku_fulfillment_id` is missing (message: `sku_fulfillment_id required`)\n- 404 if the fulfillment (`Fulfillment not found`) or its sales order (`Sales order not found`) does not exist\n- 502 if the dispatch fails (message: `Failed to submit fulfillment: ...`)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_fulfillment_id\": 650\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/submit-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders","submit-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sales_order_id\": 12345\n  },\n  \"message\": \"Order dispatched to ShipStation\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Returns a single ShipStation order from the local cache, serialized via ShipStation order object. Includes the order status (value + label + color), carrier/service codes, a resolved `tracking_url` (derived from `carrier_code` + `tracking_number` via `ShipstationTrackingUrl::resolve`), and the linked SKU.io sales order fulfillment (`sku_fulfillment`, null when not linked).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen `include_json=1` (or `true`) is supplied, the raw ShipStation JSON payload is included as `json_object`.\n\nReturns 404 when the order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token.\n\nEach order includes a `shipments` array of linked ShipStation shipment rows (tracking number/URL, carrier + service, cost, voided / return-label flags, ship date, and a `link_route` to the shipment detail page), sorted by ship date descending.\n\n**product_links** — when `include_json=1`, the response also includes `product_links`: a map of lowercased item SKU → `{ id, name, link_route }` resolving the raw payload's item SKUs (shipmentItems for shipments, items for orders) to local SKU.io products at `/products/{id}`. SKUs with no matching local product are absent from the map."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_key\": \"manual-7f3b2c9d\",\n    \"order_number\": \"SO-10245\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"order_date\": \"2026-05-28T14:32:00+00:00\",\n    \"ship_date\": \"2026-05-29T09:15:00+00:00\",\n    \"ship_by_date\": null,\n    \"carrier_code\": \"ups\",\n    \"service_code\": \"ups_ground\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"shipments\": [\n      {\n        \"id\": 101,\n        \"shipstation_shipment_id\": 987654321,\n        \"tracking_number\": \"9400111899560000000001\",\n        \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n        \"carrier_code\": \"stamps_com\",\n        \"service_code\": \"usps_priority_mail\",\n        \"package_code\": \"package\",\n        \"confirmation\": \"delivery\",\n        \"shipment_cost\": 7.42,\n        \"voided\": false,\n        \"is_return_label\": false,\n        \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n        \"create_date\": \"2026-06-08T14:22:10+00:00\",\n        \"link_route\": \"/integrations/shipstation/4/shipments/101\"\n      }\n    ],\n    \"sku_fulfillment\": {\n      \"id\": 815,\n      \"link_reference\": 815,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 815,\n      \"link_route\": \"/orders/sales-orders/fulfillments/815\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-05-29T09:20:00+00:00\",\n      \"created_at\": \"2026-05-28T15:00:00+00:00\",\n      \"sales_order_number\": \"SO-10245\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-30T08:00:00+00:00\",\n    \"created_at\": \"2026-05-28T15:00:00+00:00\",\n    \"updated_at\": \"2026-05-30T08:00:00+00:00\"\n  }\n}"}]},{"name":"Get Order Detail (raw JSON)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Returns the full cached detail for a ShipStation order: the complete raw `json_object` payload (including `items`, addresses, weight, advanced options, etc. when full detail has been fetched), plus `has_detailed_data` indicating whether the per-order detail endpoint has been synced (via `POST .../sync-detail`) and `details_last_updated` for when that happened.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nList-sync only populates summary fields; `has_detailed_data=false` means the `json_object` may only contain the list-level payload.\n\nReturns 404 when the order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_number\": \"SO-10245\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderKey\": \"manual-7f3b2c9d\",\n      \"orderNumber\": \"SO-10245\",\n      \"orderDate\": \"2026-05-28T07:32:00.0000000\",\n      \"orderStatus\": \"shipped\",\n      \"customerEmail\": \"jane.doe@example.com\",\n      \"customerUsername\": \"jane.doe@example.com\",\n      \"billTo\": {\n        \"name\": \"Jane Doe\"\n      },\n      \"shipTo\": {\n        \"name\": \"Jane Doe\",\n        \"street1\": \"123 Main St\",\n        \"city\": \"Austin\",\n        \"state\": \"TX\",\n        \"postalCode\": \"78701\",\n        \"country\": \"US\"\n      },\n      \"items\": [\n        {\n          \"orderItemId\": 555001,\n          \"sku\": \"WIDGET-L\",\n          \"name\": \"Large Widget\",\n          \"quantity\": 2,\n          \"unitPrice\": 19.99\n        }\n      ],\n      \"carrierCode\": \"ups\",\n      \"serviceCode\": \"ups_ground\",\n      \"orderTotal\": 52,\n      \"amountPaid\": 52,\n      \"weight\": {\n        \"value\": 24,\n        \"units\": \"ounces\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-30T08:00:00+00:00\"\n  }\n}"}]},{"name":"Get Order Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/webhook-events","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Recent webhook events scoped to this single ShipStation order, matched on the order's `order_number`, `tracking_number` or `shipstation_order_id`. Used by the order detail page to render a per-order webhook audit trail.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach event is serialized via ShipStation webhook event object and includes the event type (value + label + color), the ShipStation `resource_url`/`resource_type`, whether the resource was fetched, signature validation status, the raw `payload`, processing state (`processed`, `processed_at`, `error_message`) and the `dedup_key`.\n\nReturns 404 when the order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/webhook-events","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 311,\n      \"integration_instance_id\": 3,\n      \"event_type\": \"SHIP_NOTIFY\",\n      \"event_type_label\": \"Ship Notify\",\n      \"event_type_color\": \"success\",\n      \"resource_url\": \"https://ssapi.shipstation.com/orders?importBatch=1abc2def-3ghi-4jkl-5mno-6pqr7stu8vwx\",\n      \"resource_type\": \"SHIP_NOTIFY\",\n      \"resource_fetched\": true,\n      \"order_number\": \"SO-10245\",\n      \"shipstation_order_id\": 987654321,\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"signature_valid\": true,\n      \"payload\": {\n        \"resource_url\": \"https://ssapi.shipstation.com/orders?importBatch=1abc2def-3ghi-4jkl-5mno-6pqr7stu8vwx\",\n        \"resource_type\": \"SHIP_NOTIFY\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-05-29T09:21:30+00:00\",\n      \"error_message\": null,\n      \"dedup_key\": \"ship_notify-987654321-1Z999AA10123456784\",\n      \"created_at\": \"2026-05-29T09:21:28+00:00\",\n      \"updated_at\": \"2026-05-29T09:21:30+00:00\"\n    },\n    {\n      \"id\": 298,\n      \"integration_instance_id\": 3,\n      \"event_type\": \"ORDER_NOTIFY\",\n      \"event_type_label\": \"Order Notify\",\n      \"event_type_color\": \"info\",\n      \"resource_url\": \"https://ssapi.shipstation.com/orders?importBatch=9zyx8wvu-7tsr-6qpo-5nml-4kji3hgf2edc\",\n      \"resource_type\": \"ORDER_NOTIFY\",\n      \"resource_fetched\": true,\n      \"order_number\": \"SO-10245\",\n      \"shipstation_order_id\": 987654321,\n      \"tracking_number\": null,\n      \"signature_valid\": true,\n      \"payload\": {\n        \"resource_url\": \"https://ssapi.shipstation.com/orders?importBatch=9zyx8wvu-7tsr-6qpo-5nml-4kji3hgf2edc\",\n        \"resource_type\": \"ORDER_NOTIFY\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-05-28T15:01:02+00:00\",\n      \"error_message\": null,\n      \"dedup_key\": \"order_notify-987654321\",\n      \"created_at\": \"2026-05-28T15:01:00+00:00\",\n      \"updated_at\": \"2026-05-28T15:01:02+00:00\"\n    }\n  ]\n}"}]},{"name":"Refresh Order Tracking","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/tracking","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","tracking"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Refreshes tracking for a single order live from ShipStation's V1 `/shipments` endpoint (looked up by the order's ShipStation order ID), persists the tracking number / carrier / ship date to the local order cache, and applies the tracking to the linked SKU.io SalesOrderFulfillment (if any). Mirrors the Starshipit \"Refresh Order Tracking\" endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Returns the refreshed order (with `json_object` included) and the message \"Tracking refreshed from ShipStation\".\n\nErrors: 404 when the order does not belong to the instance; 400 when the order has no `shipstation_order_id`; 502 when the live ShipStation call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/tracking","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","tracking"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_key\": \"manual-7f3b2c9d\",\n    \"order_number\": \"SO-10245\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"order_date\": \"2026-05-28T14:32:00+00:00\",\n    \"ship_date\": \"2026-05-29T09:15:00+00:00\",\n    \"ship_by_date\": null,\n    \"carrier_code\": \"ups\",\n    \"service_code\": \"ups_ground\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"sku_fulfillment\": {\n      \"id\": 815,\n      \"link_reference\": 815,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 815,\n      \"link_route\": \"/orders/sales-orders/fulfillments/815\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-05-29T09:20:00+00:00\",\n      \"created_at\": \"2026-05-28T15:00:00+00:00\",\n      \"sales_order_number\": \"SO-10245\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-30T08:00:00+00:00\",\n    \"created_at\": \"2026-05-28T15:00:00+00:00\",\n    \"updated_at\": \"2026-06-10T10:05:00+00:00\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderNumber\": \"SO-10245\",\n      \"orderStatus\": \"shipped\"\n    }\n  },\n  \"message\": \"Tracking refreshed from ShipStation\"\n}"}]},{"name":"Sync Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Fetches the full order detail for a single order live from the ShipStation API, replacing the cached `json_object` with the complete per-order payload (items, addresses, weight, advanced options) and setting `has_detailed_data=true` + `details_last_updated`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Returns the refreshed order serialized via ShipStation order object with `json_object` included so the detail page can re-render items / packages / raw data immediately.\n\nErrors: 404 when the order does not belong to the instance; 502 when the live ShipStation call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_key\": \"manual-7f3b2c9d\",\n    \"order_number\": \"SO-10245\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"order_date\": \"2026-05-28T14:32:00+00:00\",\n    \"ship_date\": \"2026-05-29T09:15:00+00:00\",\n    \"ship_by_date\": null,\n    \"carrier_code\": \"ups\",\n    \"service_code\": \"ups_ground\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-06-10T10:12:00+00:00\",\n    \"created_at\": \"2026-05-28T15:00:00+00:00\",\n    \"updated_at\": \"2026-06-10T10:12:00+00:00\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderNumber\": \"SO-10245\",\n      \"orderStatus\": \"shipped\",\n      \"items\": [\n        {\n          \"orderItemId\": 555001,\n          \"sku\": \"WIDGET-L\",\n          \"name\": \"Large Widget\",\n          \"quantity\": 2,\n          \"unitPrice\": 19.99\n        }\n      ],\n      \"shipTo\": {\n        \"name\": \"Jane Doe\",\n        \"city\": \"Austin\",\n        \"state\": \"TX\",\n        \"country\": \"US\"\n      },\n      \"weight\": {\n        \"value\": 24,\n        \"units\": \"ounces\"\n      }\n    }\n  }\n}"}]},{"name":"Link Order to Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Manually links a cached ShipStation order to a SKU.io SalesOrderFulfillment by setting `sku_fulfillment_id` on the order (matched by its ShipStation order ID).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `sku_fulfillment_id` (integer, required) — the SalesOrderFulfillment ID to link.\n\nReturns the updated order (with `json_object` included and the populated `sku_fulfillment` object).\n\nErrors: 400 when `sku_fulfillment_id` is missing/zero; 404 when the order does not belong to the instance, or when no cached order with that ShipStation order ID exists.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_fulfillment_id\": 815\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_key\": \"manual-7f3b2c9d\",\n    \"order_number\": \"SO-10245\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"order_date\": \"2026-05-28T14:32:00+00:00\",\n    \"ship_date\": \"2026-05-29T09:15:00+00:00\",\n    \"ship_by_date\": null,\n    \"carrier_code\": \"ups\",\n    \"service_code\": \"ups_ground\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"sku_fulfillment\": {\n      \"id\": 815,\n      \"link_reference\": 815,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 815,\n      \"link_route\": \"/orders/sales-orders/fulfillments/815\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-05-29T09:20:00+00:00\",\n      \"created_at\": \"2026-05-28T15:00:00+00:00\",\n      \"sales_order_number\": \"SO-10245\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-30T08:00:00+00:00\",\n    \"created_at\": \"2026-05-28T15:00:00+00:00\",\n    \"updated_at\": \"2026-06-10T10:20:00+00:00\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderNumber\": \"SO-10245\",\n      \"orderStatus\": \"shipped\"\n    }\n  }\n}"}]},{"name":"Unlink Order from Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Removes the manual link between a cached ShipStation order and its SKU.io SalesOrderFulfillment by clearing `sku_fulfillment_id` on the order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body. Returns the updated order (with `json_object` included) — `sku_fulfillment` is null after unlinking.\n\nReturns 404 when the order does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 3,\n    \"shipstation_order_id\": \"987654321\",\n    \"order_key\": \"manual-7f3b2c9d\",\n    \"order_number\": \"SO-10245\",\n    \"order_status\": \"shipped\",\n    \"order_status_label\": \"Shipped\",\n    \"order_status_color\": \"success\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"order_date\": \"2026-05-28T14:32:00+00:00\",\n    \"ship_date\": \"2026-05-29T09:15:00+00:00\",\n    \"ship_by_date\": null,\n    \"carrier_code\": \"ups\",\n    \"service_code\": \"ups_ground\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-30T08:00:00+00:00\",\n    \"created_at\": \"2026-05-28T15:00:00+00:00\",\n    \"updated_at\": \"2026-06-10T10:25:00+00:00\",\n    \"json_object\": {\n      \"orderId\": 987654321,\n      \"orderNumber\": \"SO-10245\",\n      \"orderStatus\": \"shipped\"\n    }\n  }\n}"}]},{"name":"Download Shipping Services","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/{integration_instance}/download-shipping-services","host":["{{baseUrl}}"],"path":["api","shipstation",":integration_instance","download-shipping-services"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]},"description":"Download available shipping services from ShipStation and seed them into the shipping method mapping table.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/{integration_instance}/download-shipping-services","host":["{{baseUrl}}"],"path":["api","shipstation",":integration_instance","download-shipping-services"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"shipping_provider_id\": 5,\n      \"shipping_provider_carrier\": \"stamps_com\",\n      \"shipping_provider_method\": \"usps_first_class_mail\",\n      \"shipping_method_id\": 12,\n      \"shipping_method_name\": \"USPS First Class\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]},"description":"Paginated Spatie activity-log entries for a single Shipstation order (by local row id) — the order detail page's Activity Log tab. Each entry: id, description, event (created/updated/deleted), subject_type, subject_id, properties (changed attributes), causer_name, created_at. Ordered newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: page (default 1), per_page (default 15).\n\nAuthentication: Requires Bearer token.\n\nFilters: filter[event] (exact event), filter[source] (matches properties->source), filter[batch_uuid] (exact batch uuid), filter[search] (LIKE over causer name / properties / event)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"42","description":"Internal ShipstationOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90412,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"ShipstationOrder\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"attributes\": {\n          \"tracking_number\": \"1Z999AA10123456784\"\n        },\n        \"old\": {\n          \"tracking_number\": null\n        }\n      },\n      \"causer_name\": \"Sync Job\",\n      \"created_at\": \"2026-06-11T14:33:00.000000Z\"\n    },\n    {\n      \"id\": 90380,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"ShipstationOrder\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"attributes\": {\n          \"order_number\": \"SO-100245\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-10T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/...?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"List label shipments for a ShipStation integration instance (paginated). Backed by the dedicated shipstation_shipments table populated from ShipStation's GET /shipments endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFree-text search (filter[search]) matches tracking_number, shipstation_shipment_id, order_number, carrier_code, service_code (Typesense-backed when available, with DB LIKE fallback).\n\nAllowed sorts: id, shipstation_shipment_id, order_number, tracking_number, carrier_code, service_code, package_code, shipment_cost, weight_value, voided, ship_date, create_date, created_at, updated_at. Prefix with - for DESC. Default sort: -ship_date.\n\nAdvanced filter operators are supported per column via the AdvancedFiltersModal (text operators on order_number/tracking_number/carrier_code/service_code/package_code/confirmation/warehouse_id, numeric on id/shipstation_shipment_id/weight_value/shipment_cost, datetime on ship_date/create_date/created_at/updated_at).\n\nPass include_json=1 to include the raw ShipStation payload (json_object) on each row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 101,\n      \"integration_instance_id\": 4,\n      \"shipstation_shipment_id\": 987654321,\n      \"order_id\": 2456,\n      \"shipstation_order_id\": 123456789,\n      \"order_number\": \"SS-10342\",\n      \"tracking_number\": \"9400111899560000000001\",\n      \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n      \"carrier_code\": \"stamps_com\",\n      \"service_code\": \"usps_priority_mail\",\n      \"package_code\": \"package\",\n      \"confirmation\": \"delivery\",\n      \"warehouse_id\": \"12345\",\n      \"weight_value\": 14.5,\n      \"weight_units\": \"ounces\",\n      \"length\": 10,\n      \"width\": 8,\n      \"height\": 4,\n      \"dimension_units\": \"inches\",\n      \"shipment_cost\": 7.42,\n      \"insurance_cost\": 0,\n      \"voided\": false,\n      \"void_date\": null,\n      \"is_return_label\": false,\n      \"batch_number\": \"100301\",\n      \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n      \"create_date\": \"2026-06-08T14:22:10+00:00\",\n      \"created_at\": \"2026-06-08T14:25:00+00:00\",\n      \"updated_at\": \"2026-06-08T14:25:00+00:00\",\n      \"order\": {\n        \"id\": 2456,\n        \"order_number\": \"SS-10342\",\n        \"shipstation_order_id\": 123456789,\n        \"link_reference\": \"SS-10342\",\n        \"link_type_label\": \"ShipStation Order\",\n        \"link_id\": 2456,\n        \"link_route\": \"/integrations/shipstation/4/orders/2456\"\n      },\n      \"sku_fulfillment_id\": 778,\n      \"sku_fulfillment_status\": \"shipped\",\n      \"sales_order_id\": 3301,\n      \"sales_order_number\": \"SO-3301\",\n      \"sales_order_legacy_url\": \"/sales-orders/3301\",\n      \"warehouse\": {\n        \"id\": 2,\n        \"name\": \"Main Warehouse\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"...\",\n  \"last_page_url\": \"...\",\n  \"next_page_url\": \"...\",\n  \"prev_page_url\": null,\n  \"path\": \"...\",\n  \"links\": []\n}"}]},{"name":"Get Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"101","description":"The shipment ID."}]},"description":"Get a single ShipStation shipment by local row id. Returns 404 when the shipment does not belong to the instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**product_links** — when `include_json=1`, the response also includes `product_links`: a map of lowercased item SKU → `{ id, name, link_route }` resolving the raw payload's item SKUs (shipmentItems for shipments, items for orders) to local SKU.io products at `/products/{id}`. SKUs with no matching local product are absent from the map."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments",":shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."},{"key":"shipment","value":"101","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 4,\n    \"shipstation_shipment_id\": 987654321,\n    \"order_id\": 2456,\n    \"shipstation_order_id\": 123456789,\n    \"order_number\": \"SS-10342\",\n    \"tracking_number\": \"9400111899560000000001\",\n    \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n    \"carrier_code\": \"stamps_com\",\n    \"service_code\": \"usps_priority_mail\",\n    \"package_code\": \"package\",\n    \"confirmation\": \"delivery\",\n    \"warehouse_id\": \"12345\",\n    \"weight_value\": 14.5,\n    \"weight_units\": \"ounces\",\n    \"length\": 10,\n    \"width\": 8,\n    \"height\": 4,\n    \"dimension_units\": \"inches\",\n    \"shipment_cost\": 7.42,\n    \"insurance_cost\": 0,\n    \"voided\": false,\n    \"void_date\": null,\n    \"is_return_label\": false,\n    \"batch_number\": \"100301\",\n    \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n    \"create_date\": \"2026-06-08T14:22:10+00:00\",\n    \"created_at\": \"2026-06-08T14:25:00+00:00\",\n    \"updated_at\": \"2026-06-08T14:25:00+00:00\",\n    \"order\": {\n      \"id\": 2456,\n      \"order_number\": \"SS-10342\",\n      \"shipstation_order_id\": 123456789,\n      \"link_reference\": \"SS-10342\",\n      \"link_type_label\": \"ShipStation Order\",\n      \"link_id\": 2456,\n      \"link_route\": \"/integrations/shipstation/4/orders/2456\"\n    },\n    \"sku_fulfillment_id\": 778,\n    \"sku_fulfillment_status\": \"shipped\",\n    \"sales_order_id\": 3301,\n    \"sales_order_number\": \"SO-3301\",\n    \"sales_order_legacy_url\": \"/sales-orders/3301\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    }\n  },\n  \"message\": null\n}"}]},{"name":"Refresh Shipment From ShipStation","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/{shipment}/refresh?include_json=1","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments",":shipment","refresh"],"query":[{"key":"include_json","value":"1","description":"Include raw ShipStation payload (json_object) in the response. The endpoint forces this on internally, so the refreshed payload is always returned.","disabled":true}],"variable":[{"key":"integrationInstance","value":"4","description":"The integration instance ID."},{"key":"shipment","value":"101","description":"The shipment ID."}]},"description":"Fetch fresh shipment data live from the ShipStation API and upsert it into the local row, then return the refreshed resource (including the raw json_object payload).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nShipStation V1 has no GET /shipments/{id} endpoint, so the lookup calls List Shipments filtered by the shipment's orderId (falling back to its trackingNumber) and matches the shipmentId in the results.\n\nReturns 404 when the local shipment does not belong to the instance, or when ShipStation no longer returns the shipment (e.g. it was removed). Returns 502 when the ShipStation API call fails.\n\nAuthentication: Requires Bearer token.\n\n**product_links** — when `include_json=1`, the response also includes `product_links`: a map of lowercased item SKU → `{ id, name, link_route }` resolving the raw payload's item SKUs (shipmentItems for shipments, items for orders) to local SKU.io products at `/products/{id}`. SKUs with no matching local product are absent from the map."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/{shipment}/refresh?include_json=1","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments",":shipment","refresh"],"query":[{"key":"include_json","value":"1","description":"Include raw ShipStation payload (json_object) in the response. The endpoint forces this on internally, so the refreshed payload is always returned.","disabled":true}],"variable":[{"key":"integrationInstance","value":"4","description":"The integration instance ID."},{"key":"shipment","value":"101","description":"The shipment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 4,\n    \"shipstation_shipment_id\": 987654321,\n    \"order_id\": 2456,\n    \"shipstation_order_id\": 123456789,\n    \"order_number\": \"SS-10342\",\n    \"tracking_number\": \"9400111899560000000001\",\n    \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n    \"carrier_code\": \"stamps_com\",\n    \"service_code\": \"usps_priority_mail\",\n    \"package_code\": \"package\",\n    \"confirmation\": \"delivery\",\n    \"warehouse_id\": \"12345\",\n    \"weight_value\": 14.5,\n    \"weight_units\": \"ounces\",\n    \"length\": 10,\n    \"width\": 8,\n    \"height\": 4,\n    \"dimension_units\": \"inches\",\n    \"shipment_cost\": 7.42,\n    \"insurance_cost\": 0,\n    \"voided\": false,\n    \"void_date\": null,\n    \"is_return_label\": false,\n    \"batch_number\": \"100301\",\n    \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n    \"create_date\": \"2026-06-08T14:22:10+00:00\",\n    \"created_at\": \"2026-06-08T14:25:00+00:00\",\n    \"updated_at\": \"2026-06-10T09:12:44+00:00\",\n    \"json_object\": {\n      \"shipmentId\": 987654321,\n      \"orderId\": 123456789,\n      \"orderNumber\": \"SS-10342\",\n      \"trackingNumber\": \"9400111899560000000001\",\n      \"carrierCode\": \"stamps_com\",\n      \"serviceCode\": \"usps_priority_mail\",\n      \"shipmentCost\": 7.42,\n      \"voided\": false,\n      \"shipDate\": \"2026-06-08\",\n      \"shipmentItems\": [\n        {\n          \"orderItemId\": 555111,\n          \"sku\": \"WIDGET-1\",\n          \"name\": \"Widget\",\n          \"quantity\": 2\n        }\n      ]\n    },\n    \"order\": {\n      \"id\": 2456,\n      \"order_number\": \"SS-10342\",\n      \"shipstation_order_id\": 123456789,\n      \"link_reference\": \"SS-10342\",\n      \"link_type_label\": \"ShipStation Order\",\n      \"link_id\": 2456,\n      \"link_route\": \"/integrations/shipstation/4/orders/2456\"\n    },\n    \"sku_fulfillment_id\": 778,\n    \"sku_fulfillment_status\": \"shipped\",\n    \"sales_order_id\": 3301,\n    \"sales_order_number\": \"SO-3301\",\n    \"sales_order_legacy_url\": \"/sales-orders/3301\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    },\n    \"product_links\": {\n      \"l0524v-303-3230-u-1\": {\n        \"id\": 4821,\n        \"name\": \"24V COB LED Strip Spotless 32.8ft UL Listed IP20 Indoor - Warm White 3000k\",\n        \"link_route\": \"/products/4821\"\n      }\n    }\n  },\n  \"message\": \"Shipment refreshed from ShipStation\"\n}"}]},{"name":"Sync Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Queue a tracked background sync that pages ShipStation's GET /shipments endpoint into the shipstation_shipments table (and applies tracking to linked orders/fulfillments, including a second pass over GET /fulfillments for externally fulfilled orders).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (all optional):\n- mode: 'all' (full history), 'date_range' (bounded by date_from/date_to), 'since_latest' (bounded by date_from). Default: falls back to date_from, else the configured order start date.\n- date_from / since_date: ISO datetime lower bound\n- date_to: ISO datetime upper bound\n\nTrack progress via the tracked job log endpoints (job name: 'Sync ShipStation Shipments: {instance name}').\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"date_from\": \"2026-05-01T00:00:00Z\",\n  \"date_to\": \"2026-06-01T00:00:00Z\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","sync"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 991\n  },\n  \"message\": \"Shipments sync queued\"\n}"}]},{"name":"Shipments Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/sync-info","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Header data for the shipments refresh modal: the most recently created shipment (by ShipStation createDate), the total shipment count, and the effective sync start date for this instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`shipment_start_date` is the date the \"Fetch from Start Date\" sync option will use, and `shipment_start_date_source` is a human-readable label for where it came from. The date resolves in priority order: the instance's ShipStation Order Start Date (source: \"ShipStation Order Start Date\"), then the general Inventory Start Date (source: \"Inventory Start Date\"), then a 30-day fallback window (source: \"Default sync window (last 30 days)\").\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/sync-info","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","sync-info"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_shipment_identifier\": \"9400111899560000000001\",\n    \"latest_shipment_date\": \"2026-06-08T14:22:10+00:00\",\n    \"total_shipments\": 118,\n    \"shipment_start_date\": \"2025-01-01\",\n    \"shipment_start_date_source\": \"Inventory Start Date\"\n  },\n  \"message\": null\n}"}]},{"name":"Search Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/search","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","search"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Search ShipStation live for label shipments matching an order number or tracking number. Backs the \"Search Specific Shipment\" tab of the shipments refresh modal.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request body:**\n- `search_by` (string, optional) — `order_number` (default) or `tracking_number`. `order_number` is a starts-with match in ShipStation V1; `tracking_number` is an exact match.\n- `query` (string, required, max 255) — the order number or tracking number to search for.\n\nReturns up to 50 live results from ShipStation. Each result includes `exists_in_database` / `database_id` so the UI can offer \"Download\" (new) vs \"Update\" (already cached). Use the returned `shipstation_shipment_id`, `shipstation_order_id`, and `tracking_number` to call the Refresh Single Shipment endpoint.\n\nReturns 502 if the ShipStation API call fails.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"search_by\": \"order_number\",\n  \"query\": \"SS-10342\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/search","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","search"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"shipstation_shipment_id\": 987654321,\n      \"shipstation_order_id\": 123456789,\n      \"order_number\": \"SS-10342\",\n      \"tracking_number\": \"9400111899560000000001\",\n      \"carrier_code\": \"stamps_com\",\n      \"service_code\": \"usps_priority_mail\",\n      \"shipment_cost\": 7.42,\n      \"voided\": false,\n      \"create_date\": \"2026-06-08T14:22:10+00:00\",\n      \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n      \"exists_in_database\": true,\n      \"database_id\": 101\n    },\n    {\n      \"shipstation_shipment_id\": 987654400,\n      \"shipstation_order_id\": 123456790,\n      \"order_number\": \"SS-10343\",\n      \"tracking_number\": \"9400111899560000000045\",\n      \"carrier_code\": \"stamps_com\",\n      \"service_code\": \"usps_first_class_mail\",\n      \"shipment_cost\": 4.15,\n      \"voided\": false,\n      \"create_date\": \"2026-06-09T09:10:05+00:00\",\n      \"ship_date\": \"2026-06-09T00:00:00+00:00\",\n      \"exists_in_database\": false,\n      \"database_id\": null\n    }\n  ],\n  \"message\": null\n}"}]},{"name":"Refresh Single Shipment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/refresh-shipment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","refresh-shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]},"description":"Download (or update) a single label shipment live from ShipStation and persist it to the local cache. Backs the per-result Download/Update buttons on the shipments refresh modal's search tab.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nShipStation V1 has no GET /shipments/{id} endpoint, so the lookup needs the shipment's order id or tracking number alongside its id — the shipment is found by listing shipments filtered by `orderId` (preferred) or exact `trackingNumber` and matching on the shipment id.\n\n**Request body:**\n- `uniqueId` (string, required) — the ShipStation shipment id (`shipstation_shipment_id` from a search result).\n- `order_id` (integer, optional, nullable) — the ShipStation order id (`shipstation_order_id` from a search result). Preferred lookup key.\n- `tracking_number` (string, optional, nullable, max 255) — fallback lookup key when the shipment has no order id.\n\nAt least one of `order_id` or `tracking_number` is required (400 otherwise). Returns 404 if ShipStation no longer returns the shipment, 502 if the ShipStation API call fails.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"987654321\",\n  \"order_id\": 123456789,\n  \"tracking_number\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integrationInstance}/shipments/refresh-shipment","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integrationInstance","shipments","refresh-shipment"],"variable":[{"key":"integrationInstance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"integration_instance_id\": 4,\n    \"shipstation_shipment_id\": 987654321,\n    \"order_id\": 2456,\n    \"shipstation_order_id\": 123456789,\n    \"order_number\": \"SS-10342\",\n    \"tracking_number\": \"9400111899560000000001\",\n    \"tracking_url\": \"https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111899560000000001\",\n    \"carrier_code\": \"stamps_com\",\n    \"service_code\": \"usps_priority_mail\",\n    \"package_code\": \"package\",\n    \"confirmation\": \"delivery\",\n    \"warehouse_id\": \"12345\",\n    \"weight_value\": 14.5,\n    \"weight_units\": \"ounces\",\n    \"length\": 10,\n    \"width\": 8,\n    \"height\": 4,\n    \"dimension_units\": \"inches\",\n    \"shipment_cost\": 7.42,\n    \"insurance_cost\": 0,\n    \"voided\": false,\n    \"void_date\": null,\n    \"is_return_label\": false,\n    \"batch_number\": \"100301\",\n    \"ship_date\": \"2026-06-08T00:00:00+00:00\",\n    \"create_date\": \"2026-06-08T14:22:10+00:00\",\n    \"created_at\": \"2026-06-08T14:25:00+00:00\",\n    \"updated_at\": \"2026-06-08T14:25:00+00:00\",\n    \"order\": {\n      \"id\": 2456,\n      \"order_number\": \"SS-10342\",\n      \"shipstation_order_id\": 123456789,\n      \"link_reference\": \"SS-10342\",\n      \"link_type_label\": \"ShipStation Order\",\n      \"link_id\": 2456,\n      \"link_route\": \"/integrations/shipstation/4/orders/2456\"\n    },\n    \"sku_fulfillment_id\": 778,\n    \"sku_fulfillment_status\": \"shipped\",\n    \"sales_order_id\": 3301,\n    \"sales_order_number\": \"SO-3301\",\n    \"sales_order_legacy_url\": \"/sales-orders/3301\",\n    \"warehouse\": {\n      \"id\": 2,\n      \"name\": \"Main Warehouse\"\n    }\n  },\n  \"message\": \"Shipment refreshed from ShipStation\"\n}"}]},{"name":"List Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"All cached ShipStation warehouses for this instance, ordered by name (no pagination or filters). Each entry includes the optional SKU.io warehouse link (`warehouse_id` + `warehouse_name`) and origin-address fields.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 5,\n      \"shipstation_id\": 98765,\n      \"name\": \"Main Fulfillment Center\",\n      \"is_default\": true,\n      \"warehouse_id\": 3,\n      \"warehouse_name\": \"Main Warehouse\",\n      \"address_line_1\": \"123 Commerce St\",\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"postal_code\": \"78701\",\n      \"country\": \"US\",\n      \"created_at\": \"2026-04-10T08:00:00+00:00\",\n      \"updated_at\": \"2026-06-01T12:00:00+00:00\"\n    },\n    {\n      \"id\": 6,\n      \"shipstation_id\": 98766,\n      \"name\": \"West Coast Annex\",\n      \"is_default\": false,\n      \"warehouse_id\": null,\n      \"warehouse_name\": null,\n      \"address_line_1\": \"55 Harbor Blvd\",\n      \"city\": \"Long Beach\",\n      \"state\": \"CA\",\n      \"postal_code\": \"90802\",\n      \"country\": \"US\",\n      \"created_at\": \"2026-04-10T08:00:00+00:00\",\n      \"updated_at\": \"2026-06-01T12:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Sync Warehouses","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queues a background job as a tracked job that pulls the warehouse list from the ShipStation API and upserts the local cache. No request body. Returns `data.tracked_job_log_id` for the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Warehouse sync queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 9140\n  }\n}"}]},{"name":"Link Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses/{shipstationId}/link","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses",":shipstationId","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"shipstationId","value":"","description":"The shipstation ID."}]},"description":"Links (or unlinks) a ShipStation warehouse to a SKU.io warehouse.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath params:\n- `shipstationId` — the ShipStation warehouse id (shipstation_id), not the local row id\n\nBody fields:\n- `warehouse_id` — SKU.io warehouse id to link; pass null (or omit) to unlink\n\nReturns the updated warehouse resource.\n\nErrors:\n- 404 — no cached ShipStation warehouse with that shipstation_id for this instance ('Warehouse not found')\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/warehouses/{shipstationId}/link","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","warehouses",":shipstationId","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"shipstationId","value":"","description":"The shipstation ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 5,\n    \"shipstation_id\": 98765,\n    \"name\": \"Main Fulfillment Center\",\n    \"is_default\": true,\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"Main Warehouse\",\n    \"address_line_1\": \"123 Commerce St\",\n    \"city\": \"Austin\",\n    \"state\": \"TX\",\n    \"postal_code\": \"78701\",\n    \"country\": \"US\",\n    \"created_at\": \"2026-04-10T08:00:00+00:00\",\n    \"updated_at\": \"2026-06-10T09:30:00+00:00\"\n  }\n}"}]},{"name":"Get ShipStation Warehouses","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/warehouses","host":["{{baseUrl}}"],"path":["api","shipstation","warehouses"]},"description":"List all ShipStation warehouses that have been downloaded from ShipStation.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access."}},{"name":"Get Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/warehouses/mappings","host":["{{baseUrl}}"],"path":["api","shipstation","warehouses","mappings"]},"description":"Retrieve all mappings between SKU warehouses and ShipStation warehouses.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access."}},{"name":"Download ShipStation Warehouses","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/warehouses/download","host":["{{baseUrl}}"],"path":["api","shipstation","warehouses","download"]},"description":"Download warehouses from ShipStation and store them locally.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access."}},{"name":"Map Warehouses","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/warehouses/map","host":["{{baseUrl}}"],"path":["api","shipstation","warehouses","map"]},"description":"Create mappings between SKU warehouses and ShipStation warehouses.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access.","body":{"mode":"raw","raw":"{\n  \"mapping\": [\n    {\n      \"warehouse_id\": 1,\n      \"shipstation_warehouse_id\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unmap Warehouses","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/warehouses/unmap","host":["{{baseUrl}}"],"path":["api","shipstation","warehouses","unmap"]},"description":"Remove warehouse mappings between SKU and ShipStation.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"List Shipping Methods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns every ShipStation carrier/service combination for the instance (flattened to `carrier_code|service_code` codes, cached 10 minutes from the ShipStation /carriers + /services endpoints, sorted by carrier then service name) with its current SKU.io mapping (or null), plus the list of available SKU.io shipping methods for the mapping dropdown.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"services\": [\n      {\n        \"code\": \"ups|ups_ground\",\n        \"carrier_code\": \"ups\",\n        \"carrier_name\": \"UPS\",\n        \"service_code\": \"ups_ground\",\n        \"service_name\": \"UPS Ground\",\n        \"is_domestic\": true,\n        \"mapping\": {\n          \"id\": 12,\n          \"shipping_method_id\": 4,\n          \"shipping_method_name\": \"Ground Shipping\",\n          \"shipping_method_type\": \"standard\"\n        }\n      },\n      {\n        \"code\": \"fedex|fedex_2day\",\n        \"carrier_code\": \"fedex\",\n        \"carrier_name\": \"FedEx\",\n        \"service_code\": \"fedex_2day\",\n        \"service_name\": \"FedEx 2Day\",\n        \"is_domestic\": true,\n        \"mapping\": null\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 4,\n        \"name\": \"Ground Shipping\",\n        \"full_name\": \"Ground Shipping (3-5 days)\",\n        \"type\": \"standard\"\n      },\n      {\n        \"id\": 5,\n        \"name\": \"Expedited\",\n        \"full_name\": \"Expedited (2 days)\",\n        \"type\": \"expedited\"\n      }\n    ]\n  }\n}"}]},{"name":"Sync Shipping Methods","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queues a background job as a tracked job that force-refreshes the carrier/service cache from ShipStation. No request body. Returns `data.tracked_job_log_id` for the tracked job log endpoints.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Shipping methods sync queued\",\n  \"data\": {\n    \"tracked_job_log_id\": 9142\n  }\n}"}]},{"name":"Export Shipping Method Mappings (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Downloads the persisted mappings as CSV (Content-Type: text/csv, Content-Disposition attachment named `shipstation-shipping-methods-{instance}-{date}.csv`). Only stored mappings are exported — no live ShipStation API calls.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nColumns: code, carrier_code, carrier_name, service_code, service_name, is_domestic (yes/no), shipping_method_id, shipping_method_name.\n\nThe file is round-trippable with the import endpoint: blanking both shipping_method_id and shipping_method_name on a row deletes that mapping on re-import.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"code,carrier_code,carrier_name,service_code,service_name,is_domestic,shipping_method_id,shipping_method_name\nups|ups_ground,ups,UPS,ups_ground,UPS Ground,yes,4,Ground Shipping (3-5 days)\nfedex|fedex_2day,fedex,FedEx,fedex_2day,FedEx 2Day,yes,5,Expedited (2 days)\n"}]},{"name":"Import Shipping Method Mappings (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Uploads a CSV of mappings (multipart/form-data).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `file` — required, mimes: csv or txt, max 2048 KB. First row must be a header.\n\nRow semantics (per line):\n- `code` identifies the service (`carrier_code|service_code`); if blank, it is rebuilt from carrier_code + service_code columns\n- `shipping_method_id` (authoritative) or `shipping_method_name` (fallback, matched case-insensitively against name or full_name) resolves the SKU.io shipping method\n- Both blank → the mapping for that code is deleted\n- Unresolvable rows are collected into `errors` with their line numbers\n\nResponse data: `{created, updated, deleted, errors[]}` summary.\n\nErrors:\n- 422 — missing/invalid file (wrong mime type or > 2 MB)\n\nAuthentication: Requires Bearer token.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Import processed\",\n  \"data\": {\n    \"created\": 3,\n    \"updated\": 1,\n    \"deleted\": 1,\n    \"errors\": [\n      \"Line 6: shipping method name 'Overnight Gold' not found\"\n    ]\n  }\n}"}]},{"name":"Map Shipping Method","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Creates or updates a single mapping from a ShipStation `carrier_code|service_code` code to a SKU.io shipping method. Carrier/service metadata is captured from the cached service list when the code is recognized.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `code` — required, string, max 255 (format: carrier_code|service_code)\n- `shipping_method_id` — required, integer, must exist in shipping_methods\n\nErrors:\n- 422 — validation failure (missing code, unknown shipping_method_id)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"code\": \"ups|ups_ground\",\n  \"shipping_method_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Mapping saved\",\n  \"data\": {\n    \"id\": 12,\n    \"code\": \"ups|ups_ground\",\n    \"shipping_method_id\": 4\n  }\n}"}]},{"name":"Bulk Map Shipping Methods","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Maps many ShipStation service codes to a single SKU.io shipping method in one call. Duplicate codes are de-duplicated; carrier/service metadata is derived from the `carrier_code|service_code` split (no live ShipStation lookup).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `codes` — required, array, min 1; each entry required string max 255\n- `shipping_method_id` — required, integer, must exist in shipping_methods\n\nResponse data: `updated_count` — number of mappings written.\n\nErrors:\n- 422 — validation failure (empty codes array, unknown shipping_method_id)\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"codes\": [\n    \"ups|ups_ground\",\n    \"fedex|fedex_2day\",\n    \"usps|usps_priority_mail\"\n  ],\n  \"shipping_method_id\": 4\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"3 mapping(s) saved\",\n  \"data\": {\n    \"updated_count\": 3\n  }\n}"}]},{"name":"Unmap Shipping Method","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/map/ups|ups_ground","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","map","ups|ups_ground"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Deletes the mapping for a ShipStation service code.\n\nPath params:\n- `code` — the mapped `carrier_code|service_code` code. The route allows any characters including slashes (`->where('code', '.*')`), so codes containing `/` work; URL-encode the pipe (`%7C`) when needed.\n\nErrors:\n- 404 — no mapping exists for that code ('Mapping not found')\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/shipping-methods/map/ups|ups_ground","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","shipping-methods","map","ups|ups_ground"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Mapping removed\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events?page=1&per_page=15&sort=-id","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort column. Allowed: id, created_at, updated_at, event_type, processed_at. Prefix with - for descending. Default: -id","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of inbound webhook events recorded for this ShipStation integration instance, newest first (default sort -id).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Filtering** (Spatie QueryBuilder + GroupedFilterSupport):\n- `filter[search]` — multi-column AdvancedSearchFilter across `id`, `order_number`, `tracking_number`, `event_type`; tune with top-level `search_columns` / `search_strict_columns`\n- Numeric: `id`, `shipstation_order_id`\n- Text: `event_type`, `resource_type`, `processed`, `signature_valid`, `order_number`, `tracking_number`\n- Datetime: `processed_at`, `created_at`, `updated_at`\n- `filter[has_error]=true` — legacy flag for events with an error_message\n- `filter_groups` — base64-encoded JSON tree for grouped AND/OR filtering using the same column.operator names\n\n**Sorting**: `id`, `created_at`, `updated_at`, `event_type`, `processed_at` (default `-id`).\n\n**Pagination**: standard Laravel paginator, `per_page` default 15.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events?page=1&per_page=15&sort=-id","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default 15)","disabled":true},{"key":"sort","value":"-id","description":"Sort column. Allowed: id, created_at, updated_at, event_type, processed_at. Prefix with - for descending. Default: -id","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1201,\n      \"integration_instance_id\": 5,\n      \"event_type\": \"SHIP_NOTIFY\",\n      \"event_type_label\": \"Shipment Notification\",\n      \"event_type_color\": \"success\",\n      \"resource_url\": \"https://ssapi.shipstation.com/shipments?storeId=12345&batchId=98765&includeShipmentItems=false\",\n      \"resource_type\": \"SHIP_NOTIFY\",\n      \"resource_fetched\": true,\n      \"order_number\": \"SO-1234\",\n      \"shipstation_order_id\": 123456789,\n      \"tracking_number\": \"9405511899560001234567\",\n      \"signature_valid\": true,\n      \"payload\": {\n        \"resource_url\": \"https://ssapi.shipstation.com/shipments?storeId=12345&batchId=98765&includeShipmentItems=false\",\n        \"resource_type\": \"SHIP_NOTIFY\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-06-09T14:32:11+00:00\",\n      \"error_message\": null,\n      \"dedup_key\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\",\n      \"created_at\": \"2026-06-09T14:32:08+00:00\",\n      \"updated_at\": \"2026-06-09T14:32:11+00:00\"\n    },\n    {\n      \"id\": 1200,\n      \"integration_instance_id\": 5,\n      \"event_type\": \"ORDER_NOTIFY\",\n      \"event_type_label\": \"Order Notification\",\n      \"event_type_color\": \"info\",\n      \"resource_url\": \"https://ssapi.shipstation.com/orders?storeId=12345&importBatch=11223\",\n      \"resource_type\": \"ORDER_NOTIFY\",\n      \"resource_fetched\": false,\n      \"order_number\": null,\n      \"shipstation_order_id\": null,\n      \"tracking_number\": null,\n      \"signature_valid\": true,\n      \"payload\": {\n        \"resource_url\": \"https://ssapi.shipstation.com/orders?storeId=12345&importBatch=11223\",\n        \"resource_type\": \"ORDER_NOTIFY\"\n      },\n      \"processed\": false,\n      \"processed_at\": null,\n      \"error_message\": \"ShipStation API returned 429 Too Many Requests while fetching resource\",\n      \"dedup_key\": \"f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1\",\n      \"created_at\": \"2026-06-09T14:30:55+00:00\",\n      \"updated_at\": \"2026-06-09T14:31:02+00:00\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/5/webhook-events?page=1\",\n  \"from\": 1,\n  \"last_page\": 7,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/5/webhook-events?page=7\",\n  \"links\": [],\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/5/webhook-events?page=2\",\n  \"path\": \"{{protocol}}://{{domain}}/api/shipstation/integration-instances/5/webhook-events\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 98\n}"}]},{"name":"Get Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"1201","description":"ShipstationWebhookEvent ID"}]},"description":"Returns the full detail for a single webhook event, including the raw inbound `payload`, processing status, error message (if processing failed), dedup key and signature validity.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns **404** if the event does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"1201","description":"ShipstationWebhookEvent ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1201,\n    \"integration_instance_id\": 5,\n    \"event_type\": \"SHIP_NOTIFY\",\n    \"event_type_label\": \"Shipment Notification\",\n    \"event_type_color\": \"success\",\n    \"resource_url\": \"https://ssapi.shipstation.com/shipments?storeId=12345&batchId=98765&includeShipmentItems=false\",\n    \"resource_type\": \"SHIP_NOTIFY\",\n    \"resource_fetched\": true,\n    \"order_number\": \"SO-1234\",\n    \"shipstation_order_id\": 123456789,\n    \"tracking_number\": \"9405511899560001234567\",\n    \"signature_valid\": true,\n    \"payload\": {\n      \"resource_url\": \"https://ssapi.shipstation.com/shipments?storeId=12345&batchId=98765&includeShipmentItems=false\",\n      \"resource_type\": \"SHIP_NOTIFY\"\n    },\n    \"processed\": true,\n    \"processed_at\": \"2026-06-09T14:32:11+00:00\",\n    \"error_message\": null,\n    \"dedup_key\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\",\n    \"created_at\": \"2026-06-09T14:32:08+00:00\",\n    \"updated_at\": \"2026-06-09T14:32:11+00:00\"\n  }\n}"}]},{"name":"Retry Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events/{webhook_event}/retry","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events",":webhook_event","retry"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"1200","description":"ShipstationWebhookEvent ID to re-process"}]},"description":"Queues the webhook event for reprocessing by dispatching a background job. Typically used on events whose `processed` flag is false and `error_message` is set (e.g. a transient ShipStation API failure during the resource fetch).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job re-runs the standard processing path: fetch the resource from ShipStation, apply the fetched payload (order/shipment linkage), then mark the event processed or record a new error.\n\nReturns **404** if the event does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-events/{webhook_event}/retry","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-events",":webhook_event","retry"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"1200","description":"ShipstationWebhookEvent ID to re-process"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook event queued for retry\",\n  \"status\": \"Success\"\n}"}]},{"name":"List Webhook Configurations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns the webhook configuration matrix for the instance:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `configurations` — one row per ShipStation event type (`SHIP_NOTIFY`, `ITEM_SHIP_NOTIFY`, `ORDER_NOTIFY`, `ITEM_ORDER_NOTIFY`, `FULFILLMENT_SHIPPED`, `FULFILLMENT_REJECTED`) with label, color, description, and the linked local subscription (`subscription_id`, `shipstation_webhook_id`, `friendly_name`, `is_enabled`)\n- `target_url` — the public ingress URL ShipStation should POST notifications to (encodes the integration instance id so tenancy can be initialised)\n- `event_type_count` — total number of supported event types (6)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"configurations\": [\n      {\n        \"event_type\": \"SHIP_NOTIFY\",\n        \"event_type_label\": \"Shipment Notification\",\n        \"event_type_color\": \"success\",\n        \"event_type_description\": \"Sent when one or more shipments are created in ShipStation.\",\n        \"subscription_id\": 12,\n        \"shipstation_webhook_id\": \"784512\",\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": \"SKU.io Shipment Notification\",\n        \"is_enabled\": true\n      },\n      {\n        \"event_type\": \"ITEM_SHIP_NOTIFY\",\n        \"event_type_label\": \"Item Shipment Notification\",\n        \"event_type_color\": \"success\",\n        \"event_type_description\": \"Sent when shipments are created — payload includes per-item shipment detail.\",\n        \"subscription_id\": null,\n        \"shipstation_webhook_id\": null,\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": null,\n        \"is_enabled\": false\n      },\n      {\n        \"event_type\": \"ORDER_NOTIFY\",\n        \"event_type_label\": \"Order Notification\",\n        \"event_type_color\": \"info\",\n        \"event_type_description\": \"Sent when one or more new orders are imported into ShipStation.\",\n        \"subscription_id\": 13,\n        \"shipstation_webhook_id\": \"784513\",\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": \"SKU.io Order Notification\",\n        \"is_enabled\": true\n      },\n      {\n        \"event_type\": \"ITEM_ORDER_NOTIFY\",\n        \"event_type_label\": \"Item Order Notification\",\n        \"event_type_color\": \"info\",\n        \"event_type_description\": \"Sent when orders are imported — payload includes per-item order detail.\",\n        \"subscription_id\": null,\n        \"shipstation_webhook_id\": null,\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": null,\n        \"is_enabled\": false\n      },\n      {\n        \"event_type\": \"FULFILLMENT_SHIPPED\",\n        \"event_type_label\": \"Fulfillment Shipped\",\n        \"event_type_color\": \"success\",\n        \"event_type_description\": \"Sent when a fulfillment marked-as-shipped is recorded in ShipStation.\",\n        \"subscription_id\": null,\n        \"shipstation_webhook_id\": null,\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": null,\n        \"is_enabled\": false\n      },\n      {\n        \"event_type\": \"FULFILLMENT_REJECTED\",\n        \"event_type_label\": \"Fulfillment Rejected\",\n        \"event_type_color\": \"error\",\n        \"event_type_description\": \"Sent when ShipStation rejects an inbound fulfillment.\",\n        \"subscription_id\": null,\n        \"shipstation_webhook_id\": null,\n        \"callback_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n        \"friendly_name\": null,\n        \"is_enabled\": false\n      }\n    ],\n    \"target_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n    \"event_type_count\": 6\n  }\n}"}]},{"name":"Subscribe to Webhook Event","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Creates a webhook subscription on the ShipStation account (POST /webhooks/subscribe via the ShipStation V1 API) pointing at this instance's ingress URL, then records it locally.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `event_type` (required, string) — one of: `SHIP_NOTIFY`, `ITEM_SHIP_NOTIFY`, `ORDER_NOTIFY`, `ITEM_ORDER_NOTIFY`, `FULFILLMENT_SHIPPED`, `FULFILLMENT_REJECTED`\n- `friendly_name` (optional, string, max 255) — display name for the webhook in ShipStation; defaults to the event type label when omitted\n\nReturns **422** when `event_type` is missing or not one of the allowed values.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"event_type\": \"SHIP_NOTIFY\",\n  \"friendly_name\": \"SKU.io Shipment Notification\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"event_type\": \"SHIP_NOTIFY\",\n    \"event_type_label\": \"Shipment Notification\",\n    \"event_type_color\": \"success\",\n    \"shipstation_webhook_id\": \"784512\",\n    \"target_url\": \"https://acme.sku.io/api/shipstation/webhooks/5/notify\",\n    \"friendly_name\": \"SKU.io Shipment Notification\",\n    \"active\": true,\n    \"created_at\": \"2026-06-10T09:15:00+00:00\",\n    \"updated_at\": \"2026-06-10T09:15:00+00:00\"\n  },\n  \"message\": \"Webhook subscribed\",\n  \"status\": \"Success\"\n}"}]},{"name":"Sync Subscriptions from ShipStation","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Reconciles the local subscription table with the live webhook list on the ShipStation account (GET /webhooks):\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- Remote webhooks with a recognised event type that are missing locally are **added**\n- Local subscriptions whose ShipStation webhook no longer exists remotely are **removed**\n\nReturns counts of added/removed plus the resulting total.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions/sync","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"added\": 1,\n    \"removed\": 0,\n    \"total\": 3\n  },\n  \"message\": \"Sync complete — 1 added, 0 removed\",\n  \"status\": \"Success\"\n}"}]},{"name":"Unsubscribe Webhook","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions/{subscription}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions",":subscription"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"subscription","value":"12","description":"ShipstationWebhookSubscription ID"}]},"description":"Removes the webhook subscription from the ShipStation account (DELETE /webhooks/{id}) and deletes the local record.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns **404** if the subscription does not belong to the given integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shipstation/integration-instances/{integration_instance}/webhook-subscriptions/{subscription}","host":["{{baseUrl}}"],"path":["api","shipstation","integration-instances",":integration_instance","webhook-subscriptions",":subscription"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"subscription","value":"12","description":"ShipstationWebhookSubscription ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook unsubscribed\",\n  \"status\": \"Success\"\n}"}]}]},{"name":"Veracore","item":[{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances"]},"description":"Create a new Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Veracore Production\",\n  \"integration_id\": 12,\n  \"connection_settings\": {},\n  \"integration_settings\": {\n    \"connection_name\": \"main\",\n    \"linked_warehouse_id\": 1,\n    \"enable_fulfillment\": true\n  },\n  \"is_automatic_sync_enabled\": false,\n  \"is_deliver_by_date_required\": false,\n  \"gift_card_note_sales_order_custom_field_id\": null,\n  \"third_party_enabled_shipping_method_ids\": []\n}","options":{"raw":{"language":"json"}}}}},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]},"description":"Retrieve a Veracore integration instance by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]},"description":"Update a Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Veracore Production Updated\",\n  \"integration_id\": 12,\n  \"connection_settings\": {},\n  \"integration_settings\": {\n    \"connection_name\": \"main\",\n    \"linked_warehouse_id\": 1,\n    \"enable_fulfillment\": true\n  },\n  \"is_automatic_sync_enabled\": true,\n  \"is_deliver_by_date_required\": true,\n  \"gift_card_note_sales_order_custom_field_id\": null,\n  \"third_party_enabled_shipping_method_ids\": [\n    3,\n    7\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]},"description":"Delete a Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."}},{"name":"Test Connection with Credentials","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/test-connection","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances","test-connection"]},"description":"Test a set of Veracore credentials before saving an integration instance. The endpoint attempts to request an access token from the Veracore API using the supplied credentials and reports whether authentication succeeded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo integration instance is created or modified — the credentials are used only for the live authentication attempt.\n\nUse this during initial setup. To test the credentials already saved on an existing instance, use the instance-scoped test-connection endpoint instead.\n\n**Errors**\n- `422` when a required field is missing.\n- `422` with `data.success = false` and `data.error` when Veracore rejects the credentials or the server cannot be reached.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"username\": \"api-user@example.com\",\n  \"password\": \"secret-password\",\n  \"systemId\": \"ACME01\",\n  \"server_name\": \"rhu338\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/test-connection","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances","test-connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"has_token\": true\n  },\n  \"message\": \"Veracore connection successful.\",\n  \"status\": \"success\"\n}"}]},{"name":"Test Connection for Instance","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Test the Veracore connection for an existing integration instance using its saved credentials. The endpoint attempts to request an access token from the Veracore API and reports whether authentication succeeded.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nNo request body is required — the credentials stored on the instance are used.\n\n**Errors**\n- `404` when the integration instance does not exist.\n- `422` with `data.success = false` and `data.error` when Veracore rejects the saved credentials or the server cannot be reached.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"has_token\": true\n  },\n  \"message\": \"Veracore connection successful.\",\n  \"status\": \"success\"\n}"}]},{"name":"Preview Financial Line Type Impact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/financial/preview-impact","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","financial","preview-impact"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Preview how many financial lines and sales orders would be affected if the fulfillment-cost financial line type configured on this Veracore integration instance were changed to `new_type_id`. This is a read-only computation — no data is modified.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe preview compares the currently configured type against the proposed one for fulfillments in the warehouse linked to this instance:\n- `rewire_lines` — existing fulfillment-cost financial lines that would be moved from the old type to the new type.\n- `backfill_lines` — fulfillments with a cost that have no financial line of the new type yet and would get one created.\n- `sales_orders_impacted` — distinct sales orders touched by either change.\n- `is_noop` — `true` when the change would have no effect (same type, no linked warehouse, or the proposed type is not a cost type).\n\nOmit `new_type_id` (or send it empty) to preview clearing the setting.\n\n**Errors**\n- `404` when the integration instance does not exist.\n- `422` when `new_type_id` is not an existing financial line type id.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/financial/preview-impact","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","financial","preview-impact"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rewire_lines\": 128,\n    \"backfill_lines\": 46,\n    \"sales_orders_impacted\": 152,\n    \"is_noop\": false\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Order From Fulfillment (Power User)","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","veracore","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"101","description":"The sales order fulfillment ID."}]},"description":"Re-dispatch a sales order fulfillment to Veracore. Requires Power User role.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + is_power_user middleware."}},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]},"description":"List locally cached Veracore orders for an integration instance (paginated), serialized via Veracore order object. Each order exposes the SKU.io fulfillment link fields: `sku_fulfillment_id` (legacy order→SalesOrderFulfillment id, kept as a fallback), `sku_fulfillment_order_id` (order→FulfillmentOrder id), and `sku_fulfillment` (a resolved link object, or null when the order is not yet linked). Supply `include_json=1` to include the raw Veracore `json_data` payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5012,\n      \"integration_instance_id\": 5,\n      \"veracore_id\": 880123,\n      \"ReferenceNumber\": \"SO-2024-0091\",\n      \"CurrentOrderStatus\": \"Shipped\",\n      \"status_label\": \"Shipped\",\n      \"status_color\": \"warning\",\n      \"sku_fulfillment_id\": 731,\n      \"sku_fulfillment_order_id\": 642,\n      \"customer_name\": \"Jane Doe\",\n      \"customer_email\": \"jane.doe@example.com\",\n      \"ship_date\": \"2024-06-03T14:00:00Z\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"carrier_description\": \"UPS Ground\",\n      \"requested_shipping\": \"Ground\",\n      \"ship_to\": {\n        \"name\": \"Jane Doe\",\n        \"company\": null,\n        \"address1\": \"123 Market St\",\n        \"address2\": null,\n        \"city\": \"San Francisco\",\n        \"state\": \"CA\",\n        \"postal_code\": \"94103\",\n        \"country\": \"US\",\n        \"phone\": \"+1-415-555-0100\",\n        \"email\": \"jane.doe@example.com\"\n      },\n      \"items\": [\n        {\n          \"sku\": \"WIDGET-BLUE-L\",\n          \"description\": \"Blue Widget (Large)\",\n          \"quantity\": 2,\n          \"unit_price\": 19.99\n        }\n      ],\n      \"sku_fulfillment\": {\n        \"id\": 731,\n        \"link_reference\": 731,\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 731,\n        \"link_route\": \"/orders/sales-orders/fulfillments/731\",\n        \"status\": \"shipped\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n        \"fulfilled_at\": \"2024-06-03T14:00:00+00:00\",\n        \"created_at\": \"2024-06-01T12:00:00+00:00\",\n        \"sales_order_id\": 91,\n        \"sales_order_number\": \"SO-2024-0091\",\n        \"fulfillment_order_id\": 642,\n        \"warehouse\": {\n          \"id\": 3,\n          \"name\": \"Main Warehouse\"\n        }\n      },\n      \"has_detailed_data\": true,\n      \"details_last_updated\": \"2024-06-03T15:00:00+00:00\",\n      \"created_at\": \"2024-06-01T12:00:00+00:00\",\n      \"updated_at\": \"2024-06-03T14:05:00+00:00\"\n    },\n    {\n      \"id\": 5011,\n      \"integration_instance_id\": 5,\n      \"veracore_id\": 880119,\n      \"ReferenceNumber\": \"SO-2024-0090\",\n      \"CurrentOrderStatus\": \"Processed\",\n      \"status_label\": \"Processed\",\n      \"status_color\": \"primary\",\n      \"sku_fulfillment_id\": null,\n      \"sku_fulfillment_order_id\": null,\n      \"customer_name\": \"John Smith\",\n      \"customer_email\": \"john.smith@example.com\",\n      \"ship_date\": null,\n      \"tracking_number\": null,\n      \"carrier\": null,\n      \"carrier_description\": null,\n      \"requested_shipping\": \"Ground\",\n      \"ship_to\": {\n        \"name\": \"John Smith\",\n        \"company\": null,\n        \"address1\": \"500 Oak Ave\",\n        \"address2\": null,\n        \"city\": \"Austin\",\n        \"state\": \"TX\",\n        \"postal_code\": \"78701\",\n        \"country\": \"US\",\n        \"phone\": null,\n        \"email\": \"john.smith@example.com\"\n      },\n      \"items\": [\n        {\n          \"sku\": \"WIDGET-RED-S\",\n          \"description\": \"Red Widget (Small)\",\n          \"quantity\": 1,\n          \"unit_price\": 9.99\n        }\n      ],\n      \"sku_fulfillment\": null,\n      \"has_detailed_data\": false,\n      \"details_last_updated\": null,\n      \"created_at\": \"2024-06-01T09:00:00+00:00\",\n      \"updated_at\": \"2024-06-01T09:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 9,\n  \"per_page\": 15,\n  \"total\": 128,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Show Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."},{"key":"order","value":"5012","description":"The order ID."}]},"description":"Show a single locally cached Veracore order by its database id, serialized via Veracore order object. Exposes the SKU.io fulfillment link fields `sku_fulfillment_id`, `sku_fulfillment_order_id`, and the resolved `sku_fulfillment` link object (null when not linked). Supply `include_json=1` to include the raw Veracore `json_data` payload. Returns 404 when the order does not belong to the given integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"5","description":"The integration instance ID."},{"key":"order","value":"5012","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5012,\n    \"integration_instance_id\": 5,\n    \"veracore_id\": 880123,\n    \"ReferenceNumber\": \"SO-2024-0091\",\n    \"CurrentOrderStatus\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"warning\",\n    \"sku_fulfillment_id\": 731,\n    \"sku_fulfillment_order_id\": 642,\n    \"customer_name\": \"Jane Doe\",\n    \"customer_email\": \"jane.doe@example.com\",\n    \"ship_date\": \"2024-06-03T14:00:00Z\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"carrier_description\": \"UPS Ground\",\n    \"requested_shipping\": \"Ground\",\n    \"ship_to\": {\n      \"name\": \"Jane Doe\",\n      \"company\": null,\n      \"address1\": \"123 Market St\",\n      \"address2\": null,\n      \"city\": \"San Francisco\",\n      \"state\": \"CA\",\n      \"postal_code\": \"94103\",\n      \"country\": \"US\",\n      \"phone\": \"+1-415-555-0100\",\n      \"email\": \"jane.doe@example.com\"\n    },\n    \"items\": [\n      {\n        \"sku\": \"WIDGET-BLUE-L\",\n        \"description\": \"Blue Widget (Large)\",\n        \"quantity\": 2,\n        \"unit_price\": 19.99\n      }\n    ],\n    \"sku_fulfillment\": {\n      \"id\": 731,\n      \"link_reference\": 731,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 731,\n      \"link_route\": \"/orders/sales-orders/fulfillments/731\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2024-06-03T14:00:00+00:00\",\n      \"created_at\": \"2024-06-01T12:00:00+00:00\",\n      \"sales_order_id\": 91,\n      \"sales_order_number\": \"SO-2024-0091\",\n      \"fulfillment_order_id\": 642,\n      \"warehouse\": {\n        \"id\": 3,\n        \"name\": \"Main Warehouse\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2024-06-03T15:00:00+00:00\",\n    \"created_at\": \"2024-06-01T12:00:00+00:00\",\n    \"updated_at\": \"2024-06-03T14:05:00+00:00\"\n  }\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Queue a background job that syncs orders from Veracore for this integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe job fetches the order list from the Veracore API for the instance's configured look-back window, upserts each order locally, then queues follow-up fetches that pull full detail (status, shipping, line items) for every order that has never been enriched or is still in an open status. The instance's last-synced timestamp is updated when the job finishes.\n\nThe response is immediate and contains a `tracked_job_log_id`. Poll the sync-progress endpoint with that id to follow the job:\n`GET /api/veracore/integration-instances/:integration_instance/orders/sync-progress/{tracked_job_log_id}`\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 3311\n  },\n  \"message\": \"Order sync queued\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Order Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/sync-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders","sync-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"3311","description":"The tracked job log ID."}]},"description":"Get the progress of a queued Veracore order sync. Pass the `tracked_job_log_id` returned by the sync endpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`status` moves through `pending` → `processing` → `completed` (or `failed`). While processing, `total_items` / `processed_items` / `progress_percentage` report how many orders still need a detail fetch. `results` includes counters recorded by the job such as `orders_fetched`, `orders_needing_detail`, and the synced date range.\n\n**Errors**\n- `404` when no job log exists with that id, or the id belongs to a job other than a Veracore order sync.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/sync-progress/{tracked_job_log_id}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders","sync-progress",":tracked_job_log_id"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"tracked_job_log_id","value":"3311","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3311,\n    \"status\": \"processing\",\n    \"job_name\": \"Sync Veracore Orders: Veracore 3PL\",\n    \"total_items\": 148,\n    \"processed_items\": 96,\n    \"progress_percentage\": 64.86,\n    \"messages\": [],\n    \"results\": {\n      \"orders_fetched\": 148,\n      \"orders_needing_detail\": 148,\n      \"date_from\": \"2026-06-22T00:00:00+00:00\",\n      \"date_to\": \"2026-07-06T02:00:04+00:00\"\n    },\n    \"attempted_at\": \"2026-07-06T02:00:05.000000Z\",\n    \"completed_at\": null\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Sync Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]},"description":"Refresh a single Veracore order's stored data by fetching full order detail from the Veracore API. The fetched detail (status flags, shipping, line items, addresses) is merged into the locally stored order and the detail-refresh timestamp is updated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nVeracore reports status as a block of flags where several can be true at once; the most advanced flag becomes the order's current status (`Canceled` and `Complete` take precedence, then `Shipped`, and so on).\n\nThe call is synchronous — the Veracore API is contacted during the request and the refreshed order is returned.\n\n**Errors**\n- `404` when the order does not exist or belongs to a different integration instance.\n- `422` when the stored record has no Veracore order id to fetch by; run a full order sync first.\n- `502` when the Veracore API call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 1,\n    \"veracore_id\": 8675309,\n    \"ReferenceNumber\": \"C604018.1\",\n    \"CurrentOrderStatus\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"warning\",\n    \"sku_fulfillment_id\": 5150,\n    \"sku_fulfillment_order_id\": null,\n    \"customer_name\": \"Jane Smith\",\n    \"customer_email\": \"jane.smith@example.com\",\n    \"ship_date\": \"2026-07-01T18:22:04Z\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"parcels\": [],\n    \"carrier\": \"UPS\",\n    \"carrier_description\": \"UPS Ground\",\n    \"requested_shipping\": \"Ground\",\n    \"ship_to\": {\n      \"name\": \"Jane Smith\",\n      \"company\": null,\n      \"address1\": \"123 Main St\",\n      \"address2\": null,\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"postal_code\": \"78701\",\n      \"country\": \"US\",\n      \"phone\": \"512-555-0134\",\n      \"email\": \"jane.smith@example.com\"\n    },\n    \"items\": [\n      {\n        \"sku\": \"WIDGET-BLUE\",\n        \"description\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 14.99\n      }\n    ],\n    \"sku_fulfillment\": {\n      \"id\": 5150,\n      \"link_reference\": 5150,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 5150,\n      \"link_route\": \"/orders/sales-orders/fulfillments/5150\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-07-01T18:22:04+00:00\",\n      \"created_at\": \"2026-07-01T10:13:58+00:00\",\n      \"sales_order_id\": 900,\n      \"sales_order_number\": \"C604018\",\n      \"fulfillment_order_id\": null,\n      \"warehouse\": {\n        \"id\": 4,\n        \"name\": \"Veracore 3PL\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-06T09:15:00+00:00\",\n    \"created_at\": \"2026-07-01T02:00:18+00:00\",\n    \"updated_at\": \"2026-07-06T09:15:00+00:00\"\n  },\n  \"message\": \"Order details refreshed\",\n  \"status\": \"success\"\n}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Get aggregate metrics for a Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns:\n- `totalOrders` — total Veracore orders stored for this instance.\n- `ordersByStatus` — one entry per Veracore order status (all 13 statuses are always present, with `count: 0` when empty): `Unapproved`, `Unprocessed`, `Accepted`, `Hold`, `DeniedCredit`, `Pending`, `Processed`, `Picked`, `Backordered`, `PartiallyShipped`, `Shipped`, `Complete`, `Canceled`.\n- `ordersLastSyncedAt` / `trackingLastSyncedAt` — timestamps of the most recent order and tracking syncs.\n- `pendingReportTasks` — report tasks still in `created`, `polling`, or `done` (awaiting processing) status.\n- `failedReportTasks` — report tasks in `failed` status.\n- `unlinkedOrders` — Veracore orders not yet linked to a SKU.io fulfillment.\n\nAll values are computed from locally stored data; no call is made to the Veracore API.\n\n**Errors**\n- `404` when the integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalOrders\": 1284,\n    \"ordersByStatus\": [\n      {\n        \"status\": \"Unapproved\",\n        \"status_label\": \"Unapproved\",\n        \"count\": 0\n      },\n      {\n        \"status\": \"Unprocessed\",\n        \"status_label\": \"Unprocessed\",\n        \"count\": 3\n      },\n      {\n        \"status\": \"Accepted\",\n        \"status_label\": \"Accepted\",\n        \"count\": 12\n      },\n      {\n        \"status\": \"Hold\",\n        \"status_label\": \"Hold\",\n        \"count\": 1\n      },\n      {\n        \"status\": \"DeniedCredit\",\n        \"status_label\": \"Denied Credit\",\n        \"count\": 0\n      },\n      {\n        \"status\": \"Pending\",\n        \"status_label\": \"Pending\",\n        \"count\": 8\n      },\n      {\n        \"status\": \"Processed\",\n        \"status_label\": \"Processed\",\n        \"count\": 25\n      },\n      {\n        \"status\": \"Picked\",\n        \"status_label\": \"Picked\",\n        \"count\": 14\n      },\n      {\n        \"status\": \"Backordered\",\n        \"status_label\": \"Backordered\",\n        \"count\": 2\n      },\n      {\n        \"status\": \"PartiallyShipped\",\n        \"status_label\": \"Partially Shipped\",\n        \"count\": 4\n      },\n      {\n        \"status\": \"Shipped\",\n        \"status_label\": \"Shipped\",\n        \"count\": 310\n      },\n      {\n        \"status\": \"Complete\",\n        \"status_label\": \"Complete\",\n        \"count\": 896\n      },\n      {\n        \"status\": \"Canceled\",\n        \"status_label\": \"Canceled\",\n        \"count\": 9\n      }\n    ],\n    \"ordersLastSyncedAt\": \"2026-07-06T02:00:11+00:00\",\n    \"trackingLastSyncedAt\": \"2026-07-06T02:30:44+00:00\",\n    \"pendingReportTasks\": 2,\n    \"failedReportTasks\": 1,\n    \"unlinkedOrders\": 7\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Activity Log Entries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/activity-log","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","activity-log"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"List activity log entries recorded against a Veracore integration instance, including changes to the instance itself and to its Veracore orders. Entries are returned newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach entry includes the event name, the type and id of the changed record, the change payload (`properties`), and the name of the user who caused the change (`causer_name`, `null` for system-initiated changes).\n\n**Filters**\n- `filter[search]` — matches the causer name, event, record type, or anywhere in the change payload.\n- `filter[event]` — exact event, e.g. `created`, `updated`, `deleted`, `bulk_upsert`.\n- `filter[source]` — the source recorded on the change, e.g. `manual` or a sync process name.\n- `filter[batch_uuid]` — all entries written by one bulk operation.\n\n**Errors**\n- `404` when the integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/activity-log","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","activity-log"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"IntegrationInstance\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"integration_settings\": {\n            \"sync_days_back\": 14\n          }\n        },\n        \"old\": {\n          \"integration_settings\": {\n            \"sync_days_back\": 7\n          }\n        }\n      },\n      \"causer_name\": \"Jane Admin\",\n      \"created_at\": \"2026-07-05T14:22:31.000000Z\"\n    },\n    {\n      \"id\": 90187,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"VeracoreOrder\",\n      \"subject_id\": 42,\n      \"properties\": {\n        \"source\": \"veracore_sync\"\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-07-05T02:00:18.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 6,\n  \"last_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log?page=6\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log?page=2\",\n  \"path\": \"https://app.example.com/api/veracore/integration-instances/1/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 84\n}"}]},{"name":"List Fulfillments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/fulfillments","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","fulfillments"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"List SKU.io sales order fulfillments dispatched to this Veracore integration instance. Only fulfillments of the Veracore fulfillment type are returned, scoped to the warehouse linked to the instance when one is configured.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nUse this to find the fulfillment a Veracore order shipped against, then link it with the link-fulfillment endpoint. Each row is a full fulfillment record plus a `customer_name` convenience field.\n\n**Filters**\n- `filter[search]` — matches fulfillment number, tracking number, sales order number, or customer name.\n- `filter[status]` — exact fulfillment status.\n- `filter[requested_shipping_method_id]` — exact shipping method id.\n\n**Sorting**\n`sort` accepts `id`, `fulfillment_number`, `status`, `fulfilled_at`, `created_at`, `updated_at` (prefix with `-` for descending). Default sort is `-id`.\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/fulfillments","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","fulfillments"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5150,\n      \"fulfillment_number\": \"F-5150\",\n      \"sales_order_id\": 900,\n      \"fulfillment_order_id\": 611,\n      \"fulfillment_type\": \"veracore\",\n      \"fulfillment_status\": \"fulfilled\",\n      \"shipping_method_id\": 3,\n      \"shipping_method\": \"UPS Ground\",\n      \"requested_shipping_method\": null,\n      \"requested_shipping_method_id\": 3,\n      \"requested_shipping_method_name\": \"UPS Ground\",\n      \"fulfilled_shipping_method\": null,\n      \"fulfilled_shipping_method_id\": 3,\n      \"fulfilled_shipping_method_name\": \"UPS Ground\",\n      \"fulfilled_date\": \"2026-07-01T18:22:04.000000Z\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"tracking_link\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"warehouse\": {\n        \"id\": 4,\n        \"name\": \"Veracore 3PL\",\n        \"type\": \"third_party\",\n        \"supplier_id\": null,\n        \"is_dropship\": false\n      },\n      \"warehouse_id\": 4,\n      \"fulfilled_by\": null,\n      \"fulfilled_quantity\": 2,\n      \"fulfillment_lines\": [\n        {\n          \"id\": 8123,\n          \"sales_order_line_id\": 4410,\n          \"quantity\": 2\n        }\n      ],\n      \"cost\": 8.42,\n      \"status\": \"fulfilled\",\n      \"voided_at\": null,\n      \"void_reason\": null,\n      \"voided_by\": null,\n      \"fulfilled_at\": \"2026-07-01T18:22:04.000000Z\",\n      \"marked_for_pickup_at\": null,\n      \"expected_pickup_at\": null,\n      \"packing_slip_printed_at\": null,\n      \"submitted_to_sales_channel_at\": \"2026-07-01T19:05:12.000000Z\",\n      \"last_synced_to_provider_at\": \"2026-07-01T10:14:00.000000Z\",\n      \"last_synced_from_provider_at\": \"2026-07-01T18:30:00.000000Z\",\n      \"metadata\": null,\n      \"fulfillment_sequence\": 1,\n      \"is_parent\": false,\n      \"parent_id\": null,\n      \"created_at\": \"2026-07-01T10:13:58.000000Z\",\n      \"provider_order_id\": 8675309,\n      \"sales_channel_fulfillment_link\": null,\n      \"customer_name\": \"Jane Smith\"\n    }\n  ],\n  \"first_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments?page=1\",\n  \"from\": 1,\n  \"last_page\": 12,\n  \"last_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments?page=12\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments?page=2\",\n  \"path\": \"https://app.example.com/api/veracore/integration-instances/1/fulfillments\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 178\n}"}]},{"name":"Link Order to Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]},"description":"Link a Veracore order to a SKU.io sales order fulfillment. Pass the fulfillment id as `sku_fulfillment_id` in the body — use the fulfillments list endpoint to find candidates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is a local bookkeeping change only: the link is stored on the Veracore order record in SKU.io so tracking, costs, and reconciliation can flow between the two. Nothing is sent to Veracore.\n\nReturns the updated Veracore order with its `sku_fulfillment` details populated.\n\n**Errors**\n- `400` when `sku_fulfillment_id` is missing or zero.\n- `404` when the order does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_fulfillment_id\": 5150\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 1,\n    \"veracore_id\": 8675309,\n    \"ReferenceNumber\": \"C604018.1\",\n    \"CurrentOrderStatus\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"warning\",\n    \"sku_fulfillment_id\": 5150,\n    \"sku_fulfillment_order_id\": null,\n    \"customer_name\": \"Jane Smith\",\n    \"customer_email\": \"jane.smith@example.com\",\n    \"ship_date\": \"2026-07-01T18:22:04Z\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"parcels\": [],\n    \"carrier\": \"UPS\",\n    \"carrier_description\": \"UPS Ground\",\n    \"requested_shipping\": \"Ground\",\n    \"ship_to\": {\n      \"name\": \"Jane Smith\",\n      \"company\": null,\n      \"address1\": \"123 Main St\",\n      \"address2\": null,\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"postal_code\": \"78701\",\n      \"country\": \"US\",\n      \"phone\": \"512-555-0134\",\n      \"email\": \"jane.smith@example.com\"\n    },\n    \"items\": [\n      {\n        \"sku\": \"WIDGET-BLUE\",\n        \"description\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 14.99\n      }\n    ],\n    \"sku_fulfillment\": {\n      \"id\": 5150,\n      \"link_reference\": 5150,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 5150,\n      \"link_route\": \"/orders/sales-orders/fulfillments/5150\",\n      \"status\": \"fulfilled\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"fulfilled_at\": \"2026-07-01T18:22:04+00:00\",\n      \"created_at\": \"2026-07-01T10:13:58+00:00\",\n      \"sales_order_id\": 900,\n      \"sales_order_number\": \"C604018\",\n      \"fulfillment_order_id\": null,\n      \"warehouse\": {\n        \"id\": 4,\n        \"name\": \"Veracore 3PL\"\n      }\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-02T09:15:00+00:00\",\n    \"created_at\": \"2026-07-01T02:00:18+00:00\",\n    \"updated_at\": \"2026-07-06T10:01:12+00:00\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Unlink Order from Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]},"description":"Remove the link between a Veracore order and its SKU.io sales order fulfillment. No request body is required.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is a local bookkeeping change only: the stored link on the Veracore order record is cleared. Nothing is sent to Veracore, and the fulfillment itself is not modified.\n\nReturns the updated Veracore order with `sku_fulfillment_id` cleared.\n\n**Errors**\n- `404` when the order does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"order","value":"42","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 1,\n    \"veracore_id\": 8675309,\n    \"ReferenceNumber\": \"C604018.1\",\n    \"CurrentOrderStatus\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"warning\",\n    \"sku_fulfillment_id\": null,\n    \"sku_fulfillment_order_id\": null,\n    \"customer_name\": \"Jane Smith\",\n    \"customer_email\": \"jane.smith@example.com\",\n    \"ship_date\": \"2026-07-01T18:22:04Z\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"parcels\": [],\n    \"carrier\": \"UPS\",\n    \"carrier_description\": \"UPS Ground\",\n    \"requested_shipping\": \"Ground\",\n    \"ship_to\": {\n      \"name\": \"Jane Smith\",\n      \"company\": null,\n      \"address1\": \"123 Main St\",\n      \"address2\": null,\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"postal_code\": \"78701\",\n      \"country\": \"US\",\n      \"phone\": \"512-555-0134\",\n      \"email\": \"jane.smith@example.com\"\n    },\n    \"items\": [\n      {\n        \"sku\": \"WIDGET-BLUE\",\n        \"description\": \"Blue Widget\",\n        \"quantity\": 2,\n        \"unit_price\": 14.99\n      }\n    ],\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-02T09:15:00+00:00\",\n    \"created_at\": \"2026-07-01T02:00:18+00:00\",\n    \"updated_at\": \"2026-07-06T10:05:40+00:00\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"List Report Tasks","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/report-tasks","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","report-tasks"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"List Veracore report tasks for an integration instance. A report task represents one Veracore report run used to import shipment and tracking data for a date range. Tasks are returned newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Statuses**\n- `created` — task created, not yet submitted for polling.\n- `polling` — waiting for Veracore to finish generating the report (`poll_attempts` counts checks so far).\n- `done` — report retrieved, awaiting processing.\n- `processed` — report rows applied (`rows_matched` reports how many rows matched local records).\n- `failed` — the run failed (`error_message` explains why); it can be retried.\n- `superseded` — replaced by a retry and no longer polled.\n\n**Filters**\n- `filter[status]` — exact status value from the list above.\n- `filter[date_from]` / `filter[date_to]` — created date range (inclusive, whole days).\n- Operator-suffixed filters are also available: `filter[created_at.<op>]` and `filter[processed_at.<op>]` with date operators (`is`, `is_not`, `before`, `after`, `on_or_before`, `on_or_after`, `between`, `is_empty`, `is_not_empty`, `today`, `yesterday`, `past_week`, `past_month`, `past_year`, `days_ago`, `past_days`, and more), and `filter[report_name.<op>]` with text operators (`contains`, `does_not_contain`, `is`, `is_not`, `is_one_of`, `is_not_one_of`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`, and more).\n- `filter_groups` — a base64-encoded JSON tree combining the operator-suffixed filters with nested and/or groups.\n\n**Sorting**\n`sort` accepts `id`, `status`, `report_name`, `created_at`, `processed_at`, `poll_attempts`, `rows_matched` (prefix with `-` for descending). Default sort is `-id`.\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/report-tasks","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","report-tasks"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 77,\n      \"integration_instance_id\": 1,\n      \"veracore_task_id\": \"a1b2c3d4-5678-90ab-cdef-1234567890ab\",\n      \"report_name\": \"Shipped Orders Export\",\n      \"status\": \"processed\",\n      \"status_label\": \"Processed\",\n      \"status_color\": \"success\",\n      \"filter_start_date\": \"2026-06-28T00:00:00+00:00\",\n      \"filter_end_date\": \"2026-07-05T23:59:59+00:00\",\n      \"poll_attempts\": 3,\n      \"rows_matched\": 148,\n      \"error_message\": null,\n      \"processed_at\": \"2026-07-05T06:15:22+00:00\",\n      \"created_at\": \"2026-07-05T06:00:04+00:00\",\n      \"updated_at\": \"2026-07-05T06:15:22+00:00\"\n    },\n    {\n      \"id\": 76,\n      \"integration_instance_id\": 1,\n      \"veracore_task_id\": \"0f9e8d7c-6543-21ba-fedc-0987654321ba\",\n      \"report_name\": \"Shipped Orders Export\",\n      \"status\": \"failed\",\n      \"status_label\": \"Failed\",\n      \"status_color\": \"error\",\n      \"filter_start_date\": \"2026-06-27T00:00:00+00:00\",\n      \"filter_end_date\": \"2026-07-04T23:59:59+00:00\",\n      \"poll_attempts\": 20,\n      \"rows_matched\": null,\n      \"error_message\": \"Report generation timed out after 20 poll attempts\",\n      \"processed_at\": null,\n      \"created_at\": \"2026-07-04T06:00:02+00:00\",\n      \"updated_at\": \"2026-07-04T08:40:19+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks?page=1\",\n  \"from\": 1,\n  \"last_page\": 4,\n  \"last_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks?page=4\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks?page=2\",\n  \"path\": \"https://app.example.com/api/veracore/integration-instances/1/report-tasks\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 52\n}"}]},{"name":"Retry Report Task","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/report-tasks/{report_task}/retry","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","report-tasks",":report_task","retry"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"report_task","value":"76","description":"The report task ID."}]},"description":"Retry a Veracore report task. The original task is marked `superseded` (so it stops being polled) and a fresh task is created with the same report name and date range in `created` status. A background job is queued to submit and poll the new run against the Veracore API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response returns the newly created task immediately; watch its status via the report task list.\n\n**Errors**\n- `404` when the report task does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/report-tasks/{report_task}/retry","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","report-tasks",":report_task","retry"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"report_task","value":"76","description":"The report task ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 81,\n    \"integration_instance_id\": 1,\n    \"veracore_task_id\": \"\",\n    \"report_name\": \"Shipped Orders Export\",\n    \"status\": \"created\",\n    \"status_label\": \"Created\",\n    \"status_color\": \"info\",\n    \"filter_start_date\": \"2026-06-27T00:00:00+00:00\",\n    \"filter_end_date\": \"2026-07-04T23:59:59+00:00\",\n    \"poll_attempts\": 0,\n    \"rows_matched\": null,\n    \"error_message\": null,\n    \"processed_at\": null,\n    \"created_at\": \"2026-07-06T10:12:44+00:00\",\n    \"updated_at\": \"2026-07-06T10:12:44+00:00\"\n  },\n  \"message\": \"Report task retry queued\",\n  \"status\": \"success\"\n}"}]},{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"List every carrier + service combination observed on this instance's Veracore orders, joined with any existing mapping to a SKU.io shipping method, plus the full list of SKU.io shipping methods available to map to.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach entry in `services` has a `code` in the form `Carrier|Service Description` (e.g. `UPS|UPS Ground`), how many orders were seen with that combination, and the current `mapping` (or `null` when unmapped). Combinations that were mapped previously but no longer appear on any order are still included with `order_count: 0`.\n\nAll data is read from locally stored orders; no call is made to the Veracore API.\n\nUse the returned `code` values with the map and unmap endpoints.\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"services\": [\n      {\n        \"code\": \"UPS|UPS Ground\",\n        \"carrier\": \"UPS\",\n        \"carrier_description\": \"UPS Ground\",\n        \"order_count\": 412,\n        \"mapping\": {\n          \"id\": 9,\n          \"shipping_method_id\": 3,\n          \"shipping_method_name\": \"UPS Ground\",\n          \"shipping_method_type\": \"standard\"\n        }\n      },\n      {\n        \"code\": \"FedEx|FedEx 2Day\",\n        \"carrier\": \"FedEx\",\n        \"carrier_description\": \"FedEx 2Day\",\n        \"order_count\": 57,\n        \"mapping\": null\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 3,\n        \"name\": \"Ground\",\n        \"full_name\": \"UPS Ground\",\n        \"type\": \"standard\"\n      },\n      {\n        \"id\": 7,\n        \"name\": \"2Day\",\n        \"full_name\": \"FedEx 2Day\",\n        \"type\": \"expedited\"\n      }\n    ]\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Map Shipping Method","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Create or update the mapping from a Veracore carrier + service combination to a SKU.io shipping method.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`code` is the combination identifier in the form `Carrier|Service Description` (e.g. `UPS|UPS Ground`), as returned by the shipping method list endpoint. Mapping the same `code` again replaces the previous target shipping method.\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n- `422` when `code` is missing/too long or `shipping_method_id` is not an existing shipping method.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"code\": \"UPS|UPS Ground\",\n  \"shipping_method_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9,\n    \"code\": \"UPS|UPS Ground\",\n    \"shipping_method_id\": 3\n  },\n  \"message\": \"Mapping saved\",\n  \"status\": \"success\"\n}"}]},{"name":"Delete Shipping Method Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods/map/{code}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods","map",":code"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"code","value":"UPS|UPS Ground","description":"The code ID."}]},"description":"Remove the mapping for a Veracore carrier + service combination so it is no longer translated to a SKU.io shipping method.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`code` is the combination identifier in the form `Carrier|Service Description` (e.g. `UPS|UPS Ground`). URL-encode it in the path (the pipe becomes `%7C`, spaces become `%20`); slashes inside the code are also accepted.\n\n**Errors**\n- `404` when no mapping exists for that code, or the integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/shipping-methods/map/{code}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","shipping-methods","map",":code"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"code","value":"UPS|UPS Ground","description":"The code ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping removed\",\n  \"status\": \"success\"\n}"}]},{"name":"List Source Code Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"List all source code mappings for a Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nA source code mapping determines the Veracore source code stamped on orders submitted to Veracore, based on the sales channel the order came from. A mapping with a `sub_sales_channel_id` applies only to orders from that sub channel; a mapping with `sub_sales_channel_id: null` is the catch-all for the whole sales channel.\n\nThe response is a plain array (not paginated).\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"integration_instance_id\": 1,\n      \"sales_channel_integration_instance_id\": 5,\n      \"sales_channel_integration_instance_name\": \"Shopify - Main Store\",\n      \"sub_sales_channel_id\": 8,\n      \"sub_sales_channel_name\": \"Retail\",\n      \"source_code\": \"SHOP-RETAIL\",\n      \"created_at\": \"2026-06-01T12:00:00.000000Z\",\n      \"updated_at\": \"2026-06-15T09:30:00.000000Z\"\n    },\n    {\n      \"id\": 4,\n      \"integration_instance_id\": 1,\n      \"sales_channel_integration_instance_id\": 5,\n      \"sales_channel_integration_instance_name\": \"Shopify - Main Store\",\n      \"sub_sales_channel_id\": null,\n      \"sub_sales_channel_name\": null,\n      \"source_code\": \"SHOP-DEFAULT\",\n      \"created_at\": \"2026-06-01T12:05:00.000000Z\",\n      \"updated_at\": \"2026-06-01T12:05:00.000000Z\"\n    }\n  ],\n  \"status\": \"success\"\n}"}]},{"name":"Create Source Code Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Create a source code mapping for a Veracore integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields**\n- `sales_channel_integration_instance_id` (required, integer) — the sales channel integration instance the mapping applies to; must exist.\n- `sub_sales_channel_id` (optional, integer) — restrict the mapping to one sub sales channel; must exist when provided. Omit or send `null` to create the channel's catch-all mapping.\n- `source_code` (optional, string, defaults to empty) — the Veracore source code to stamp on matching orders.\n\nOnly one mapping may exist per sales channel + sub channel combination.\n\n**Errors**\n- `404` when the integration instance does not exist or is not a Veracore instance.\n- `422` when the referenced sales channel instance or sub channel does not exist, or a mapping for the same combination already exists.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sales_channel_integration_instance_id\": 5,\n  \"sub_sales_channel_id\": 8,\n  \"source_code\": \"SHOP-RETAIL\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"integration_instance_id\": 1,\n    \"sales_channel_integration_instance_id\": 5,\n    \"sales_channel_integration_instance_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": 8,\n    \"sub_sales_channel_name\": \"Retail\",\n    \"source_code\": \"SHOP-RETAIL\",\n    \"created_at\": \"2026-07-06T10:20:00.000000Z\",\n    \"updated_at\": \"2026-07-06T10:20:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Preview Source Code for Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/preview?sales_order_id=900","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings","preview"],"query":[{"key":"sales_order_id","value":"900","description":"Id of the sales order to resolve a source code for. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]},"description":"Preview which Veracore source code would be applied to a given sales order under the current mappings. This is a read-only computation — nothing is stored and no call is made to the Veracore API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResolution order:\n1. A mapping matching the order's sales channel **and** sub sales channel (`matched_type: \"sub_channel\"`).\n2. The sales channel's catch-all mapping with no sub channel (`matched_type: \"catch_all\"`).\n3. No match — `source_code` and `matched_type` are `null`.\n\nThe response also includes the sales channel and sub channel context used for resolution so you can see why a mapping did or did not match.\n\n**Errors**\n- `404` when no sales order exists with the given `sales_order_id`, or the integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/preview?sales_order_id=900","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings","preview"],"query":[{"key":"sales_order_id","value":"900","description":"Id of the sales order to resolve a source code for. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"source_code\": \"SHOP-RETAIL\",\n    \"matched_type\": \"sub_channel\",\n    \"sales_channel_integration_instance_id\": 5,\n    \"sales_channel_integration_instance_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": 8,\n    \"sub_sales_channel_name\": \"Retail\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Update Source Code Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/{source_code_mapping}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings",":source_code_mapping"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"source_code_mapping","value":"3","description":"The source code mapping ID."}]},"description":"Update a source code mapping. Only the fields provided are changed; `null` values are ignored.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields**\n- `sub_sales_channel_id` (optional, integer) — move the mapping to a different sub sales channel; must exist when provided. Note: because `null` values are ignored, a sub-channel mapping cannot be converted to a catch-all here — delete it and create a new one instead.\n- `source_code` (optional, string) — the Veracore source code to stamp on matching orders.\n\nThe sales channel of a mapping cannot be changed.\n\n**Errors**\n- `404` when the mapping or integration instance does not exist.\n- `422` when `sub_sales_channel_id` does not reference an existing sub sales channel.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sub_sales_channel_id\": 8,\n  \"source_code\": \"SHOP-RETAIL-2026\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/{source_code_mapping}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings",":source_code_mapping"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"source_code_mapping","value":"3","description":"The source code mapping ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"integration_instance_id\": 1,\n    \"sales_channel_integration_instance_id\": 5,\n    \"sales_channel_integration_instance_name\": \"Shopify - Main Store\",\n    \"sub_sales_channel_id\": 8,\n    \"sub_sales_channel_name\": \"Retail\",\n    \"source_code\": \"SHOP-RETAIL-2026\",\n    \"created_at\": \"2026-06-01T12:00:00.000000Z\",\n    \"updated_at\": \"2026-07-06T10:25:00.000000Z\"\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Delete Source Code Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/{source_code_mapping}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings",":source_code_mapping"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"source_code_mapping","value":"3","description":"The source code mapping ID."}]},"description":"Delete a source code mapping. Orders from the affected sales channel fall back to the channel's catch-all mapping (if one exists) or to no source code.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Errors**\n- `404` when the mapping or integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/veracore/integration-instances/{integration_instance}/source-code-mappings/{source_code_mapping}","host":["{{baseUrl}}"],"path":["api","veracore","integration-instances",":integration_instance","source-code-mappings",":source_code_mapping"],"variable":[{"key":"integration_instance","value":"1","description":"The integration instance ID."},{"key":"source_code_mapping","value":"3","description":"The source code mapping ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Source code mapping deleted successfully\",\n  \"status\": \"success\"\n}"}]}]},{"name":"3PL","item":[{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/3pl/products?page=1&per_page=100","host":["{{baseUrl}}"],"path":["api","3pl","products"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"100","description":"Results per page (default 10).","disabled":true}]},"description":"Returns paginated product catalog for 3PL partners with essential fulfillment information.\nAuthentication: Requires 3PL integration Bearer token (with 3pl:read ability).\nRate limit: 120 requests per 60 seconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"List ASNs (Advanced Shipping Notices)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/3pl/asns?page=1&per_page=100&type=inbound_shipment&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","3pl","asns"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"100","description":"Results per page (default 10).","disabled":true},{"key":"type","value":"inbound_shipment","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort field; prefix with - for descending (e.g. -created_at).","disabled":true}]},"description":"Returns paginated Advanced Shipping Notices (inbound shipments and/or RMAs) destined for the 3PL's warehouses.\nAuthentication: Requires 3PL integration Bearer token (with 3pl:read ability).\nRate limit: 120 requests per 60 seconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Receive ASN (Report Receipt)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/3pl/asns/receipt","host":["{{baseUrl}}"],"path":["api","3pl","asns","receipt"]},"description":"Reports receipt of an ASN at the 3PL warehouse. Creates purchase receipts or return receipts in SKU.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest fields:\n- type (required): one of `purchase_order`, `rma`, `inbound_shipment`. Determines which entity the `line_id` values reference.\n- reference_number (required): the SKU reference of the PO / RMA / inbound shipment being received.\n- received_at (required): ISO-8601 datetime the goods were received.\n- lines (required, min 1): array of receipt lines.\n- lines[].line_id (required): the purchase order line / RMA line / inbound shipment line ID, depending on `type`.\n- lines[].quantity_received (required): quantity received for that line (>= 0).\n\nWarehouse resolution: a `purchase_order`-type ASN is accepted when the 3PL partner can access EITHER the purchase order's header destination warehouse OR any of the destination warehouses of the purchase order's inbound shipments. Received goods land in the inbound shipment's destination warehouse — which may differ from the PO header — so one PO can be received across multiple 3PL warehouses.\n\nIdempotency: Identical receipts are de-duplicated within a 10-minute window. The dedup key is (integration instance, type, reference_number, received_at, sorted line/quantity pairs) — any two requests with the same fingerprint will only materialise one receipt. The duplicate request still returns HTTP 200, but with the message `ASN receipt already processed (duplicate ignored).` This protects against client retries (e.g. Infor IONAPI Mingle re-firing with a fresh request id after a slow receive times out). To submit a genuinely distinct receipt for the same document, vary `received_at` or the line/quantity payload.\n\nAuthentication: Requires 3PL integration Bearer token (with 3pl:write ability).\nRate limit: 120 requests per 60 seconds.","body":{"mode":"raw","raw":"{\n  \"type\": \"inbound_shipment\",\n  \"reference_number\": \"IS-2024-0042\",\n  \"received_at\": \"2024-01-20T14:00:00Z\",\n  \"lines\": [\n    {\n      \"line_id\": 150,\n      \"quantity_received\": 98\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/3pl/asns/receipt","host":["{{baseUrl}}"],"path":["api","3pl","asns","receipt"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Receipt recorded successfully.\",\n  \"data\": {\n    \"type\": \"inbound_shipment\",\n    \"reference_number\": \"IS-2024-0042\",\n    \"received_at\": \"2024-01-20T14:00:00Z\",\n    \"lines\": [\n      {\n        \"line_id\": 150,\n        \"quantity_received\": 98\n      }\n    ]\n  }\n}"}]},{"name":"List Orders (Outbound Fulfillments)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/3pl/orders?page=1&per_page=100","host":["{{baseUrl}}"],"path":["api","3pl","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"100","description":"Results per page (default 10).","disabled":true}]},"description":"Returns paginated outbound fulfillment orders for the 3PL's warehouses.\nAuthentication: Requires 3PL integration Bearer token (with 3pl:read ability).\nRate limit: 120 requests per 60 seconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach order now also returns its lifecycle state: `request_status` (submitted=Released, accepted=Downloaded, acknowledged=Acknowledged), `downloaded_at`, and `acknowledged_at`. Acknowledged orders remain in this list until they ship.\n\nThe `order_number` is the FulfillmentOrder's sequenced reference `{sales_order_number}.{sequence}` (e.g. `#14522.1`) — one routed slice of the sales order. The `.{sequence}` suffix distinguishes slices and re-submits after a void; pull partners (e.g. D3) match orders on this value. Each line's `id` is the FulfillmentOrderLine id (echo it back on fulfill) and `quantity` is the remaining quantity still to ship."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/3pl/orders?page=1&per_page=100","host":["{{baseUrl}}"],"path":["api","3pl","orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"100","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 7155,\n      \"order_number\": \"#14522.1\",\n      \"order_date\": \"2026-05-13T03:15:48.000000Z\",\n      \"ship_by_date\": \"2026-06-21T14:00:00.000000Z\",\n      \"delivery_date\": null,\n      \"warehouse\": \"D3 Sydney\",\n      \"shipping_address\": {\n        \"name\": \"Brooke Walker Baxter\",\n        \"company\": \"collabbWAY\",\n        \"address1\": \"119 Eggleston Street\",\n        \"address2\": \"\",\n        \"address3\": null,\n        \"city\": \"Ocean Grove\",\n        \"province\": \"Victoria\",\n        \"province_code\": \"VIC\",\n        \"zip\": \"3226\",\n        \"country\": \"Australia\",\n        \"country_code\": \"AU\",\n        \"phone\": 401918991,\n        \"email\": \"hello@collabbway.com.au\"\n      },\n      \"shipping_method\": \"Designer Transport DT Standard\",\n      \"custom_fields\": [],\n      \"lines\": [\n        {\n          \"id\": 8111,\n          \"sales_order_line_id\": 7035,\n          \"sku\": \"T-CH01-OACA\",\n          \"quantity\": 8\n        },\n        {\n          \"id\": 8112,\n          \"sales_order_line_id\": 7036,\n          \"sku\": \"T-SS02OAK\",\n          \"quantity\": 8\n        }\n      ],\n      \"request_status\": \"accepted\",\n      \"downloaded_at\": \"2026-06-22T00:00:02.000000Z\",\n      \"acknowledged_at\": null,\n      \"created_at\": \"2026-06-18T22:31:12.000000Z\",\n      \"updated_at\": \"2026-06-22T00:00:02.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://example.sku.io/api/3pl/orders?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/3pl/orders?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/3pl/orders\",\n  \"per_page\": 100,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Fulfill Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/3pl/orders/{salesOrderFulfillment}/fulfill","host":["{{baseUrl}}"],"path":["api","3pl","orders",":salesOrderFulfillment","fulfill"],"variable":[{"key":"salesOrderFulfillment","value":"500","description":"The sales order fulfillment ID."}]},"description":"Reports that an order has been fulfilled by the 3PL. Updates fulfillment status in SKU.\nAuthentication: Requires 3PL integration Bearer token (with 3pl:write ability).\nRate limit: 120 requests per 60 seconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"id\": 600,\n      \"quantity_fulfilled\": 3\n    }\n  ],\n  \"fulfilled_at\": \"2024-01-17T15:00:00Z\",\n  \"shipping_method\": \"UPS Ground\",\n  \"tracking_number\": \"1Z999AA10123456784\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Create Inventory Adjustment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/3pl/inventory-adjustments","host":["{{baseUrl}}"],"path":["api","3pl","inventory-adjustments"]},"description":"Creates an inventory adjustment from the 3PL partner for their warehouse.\nAuthentication: Requires 3PL integration Bearer token (with 3pl:write ability).\nRate limit: 120 requests per 60 seconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"sku\": \"WIDGET-001\",\n  \"quantity\": 5,\n  \"adjustment_type\": \"decrease\",\n  \"notes\": \"Damaged in transit\",\n  \"adjustment_date\": \"2024-01-20\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Fulfill Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/3pl/orders/fulfillmentOrder/fulfill","host":["{{baseUrl}}"],"path":["api","3pl","orders","fulfillmentOrder","fulfill"]},"description":"Report a shipment for a fulfillment order — the partner confirms what it shipped. Creates one SalesOrderFulfillment against the FO (inventory + COGS post at ship-time), decrements each line's remaining, and advances the FO Open → Incomplete (\"Partially shipped\") → Closed.\n\nBody:\n- `lines` (required, min 1): `{id, quantity_fulfilled}` where `id` is the FULFILLMENT ORDER LINE id (from List Orders), `quantity_fulfilled` numeric ≥ 0 (clamped to remaining).\n- `fulfilled_at` (required date): the actual shipped timestamp (drives COGS dating).\n- `shipping_method`, `tracking_number` (optional).\n- `provider_shipment_id` (optional): idempotent dedup — a retried fulfill never records a duplicate shipment.\n\nAll-zero report → 422.\n\nAuth: 3PL Integration Token (Bearer).","body":{"mode":"raw","raw":"{\n  \"lines\": [\n    {\n      \"id\": 9,\n      \"quantity_fulfilled\": 2\n    }\n  ],\n  \"fulfilled_at\": \"2026-06-03T14:10:00Z\",\n  \"shipping_method\": \"UPS Ground\",\n  \"tracking_number\": \"1Z999AA10123456784\",\n  \"provider_shipment_id\": \"SHP-7781\"\n}","options":{"raw":{"language":"json"}}}}},{"name":"Acknowledge Order","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/3pl/orders/fulfillmentOrder/acknowledge","host":["{{baseUrl}}"],"path":["api","3pl","orders","fulfillmentOrder","acknowledge"]},"description":"OPTIONAL pull-provider acknowledgment. After the partner has downloaded an order (the List Orders poll marks each served order as \"downloaded\" / request_status = accepted), the partner may explicitly acknowledge it — \"we have it and will ship it\" — advancing it to request_status = acknowledged and stamping acknowledged_at.\n\nThis is OPTIONAL and never gates the shipment: a partner that skips it simply ships from the downloaded state via Fulfill Order. Idempotent — re-acknowledging is a no-op (acknowledged_at is preserved). An acknowledged order still appears in List Orders until it ships.\n\nPath param: `fulfillmentOrder` — the FO id (from List Orders).\n\nNo request body.\n\nResponses: 200 (acknowledged, returns the order); 422 (the order is completed or cancelled); 404 (the order is not at one of this partner's mapped warehouses).\n\nAuth: 3PL Integration Token (Bearer)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/3pl/orders/fulfillmentOrder/acknowledge","host":["{{baseUrl}}"],"path":["api","3pl","orders","fulfillmentOrder","acknowledge"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Fulfillment order acknowledged.\",\n  \"data\": {\n    \"id\": 500,\n    \"order_number\": \"SO-0204\",\n    \"order_date\": \"2026-06-18\",\n    \"ship_by_date\": \"2026-06-20\",\n    \"delivery_date\": null,\n    \"warehouse\": \"EXT_WAREHOUSE_001\",\n    \"shipping_address\": {\n      \"name\": \"Jane Doe\",\n      \"company\": null,\n      \"address1\": \"12 Erskine Park Rd\",\n      \"address2\": null,\n      \"address3\": null,\n      \"city\": \"Erskine Park\",\n      \"province\": \"NSW\",\n      \"province_code\": \"NSW\",\n      \"zip\": \"2759\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\",\n      \"phone\": \"+61 2 1234 5678\",\n      \"email\": \"jane@example.com\"\n    },\n    \"shipping_method\": \"TNT Express\",\n    \"custom_fields\": [],\n    \"lines\": [\n      {\n        \"id\": 9,\n        \"sales_order_line_id\": 7683,\n        \"sku\": \"SS-ST31BR\",\n        \"quantity\": 1\n      }\n    ],\n    \"request_status\": \"acknowledged\",\n    \"downloaded_at\": \"2026-06-18T02:59:25+00:00\",\n    \"acknowledged_at\": \"2026-06-18T13:36:26+00:00\",\n    \"created_at\": \"2026-06-18T15:13:46+00:00\",\n    \"updated_at\": \"2026-06-18T13:36:26+00:00\"\n  }\n}"}]},{"name":"Create 3PL Integration Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/3pl/tokens","host":["{{baseUrl}}"],"path":["api","3pl","tokens"]},"description":"Creates an integration instance and generates an API token for a 3PL shipping provider.\nAuthentication: Requires Sanctum Bearer token (regular user auth).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"integration_name\": \"D3\",\n  \"name\": \"D3 Production Instance\",\n  \"warehouse_mappings\": [\n    {\n      \"warehouse_id\": 1,\n      \"external_warehouse_id\": \"EXT-WH-001\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete 3PL Integration Token","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/3pl/tokens/{integrationInstance}","host":["{{baseUrl}}"],"path":["api","3pl","tokens",":integrationInstance"],"variable":[{"key":"integrationInstance","value":"25","description":"The integration instance ID."}]},"description":"Deletes a 3PL integration instance and all associated tokens and warehouse mappings.\nAuthentication: Requires Sanctum Bearer token (regular user auth).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}}]},{"name":"Trackstar","item":[{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances"]},"description":"Create a new Trackstar WMS integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- name (required, string, unique): Display name for this integration\n- integration_id (required, integer): ID of the Trackstar integration type\n- connection_settings.access_token (optional, string): Trackstar API access token\n- connection_settings.connection_id (optional, string): Trackstar connection identifier\n- integration_settings.enable_fulfillment (optional, boolean): Enable fulfillment via Trackstar\n- is_automatic_sync_enabled (optional, boolean): Toggle automatic background sync","body":{"mode":"raw","raw":"{\n  \"name\": \"My Trackstar WMS\",\n  \"integration_id\": 5,\n  \"connection_settings\": {\n    \"access_token\": \"tk_live_abc123\",\n    \"connection_id\": \"conn_xyz789\"\n  },\n  \"integration_settings\": {\n    \"enable_fulfillment\": true\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"My Trackstar WMS\",\n    \"integration_id\": 5,\n    \"connection_settings\": {\n      \"connection_id\": \"conn_xyz789\"\n    },\n    \"integration_settings\": {\n      \"enable_fulfillment\": true\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-01T12:00:00.000Z\"\n  }\n}"}]},{"name":"Preview Connection Name","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/connections/preview","host":["{{baseUrl}}"],"path":["api","trackstar","connections","preview"]},"description":"Preview the WMS integration name for a connection before it is saved. Requires Bearer token.\n\nGiven an access token and connection ID, this looks up the matching connection and returns a suggested display name (e.g. \"Mintsoft\") so a create form can auto-default the integration name. No integration instance is created and nothing is persisted.\n\nRequest body fields:\n- access_token (required, string): Access token for the connection\n- connection_id (required, string): Identifier of the connection to look up\n\nResponse fields (under `data`):\n- matched (boolean): Whether a connection matched the supplied connection ID\n- connection_id (string): The connection ID that was looked up\n- integration_name (string|null): Machine name of the matched WMS (e.g. \"mintsoft\")\n- integration_display_name (string|null): Human-friendly WMS name (e.g. \"Mintsoft\")\n- suggested_name (string|null): Recommended default name (display name, falling back to machine name)\n- message (string|null): Explanation when no match was found or the lookup could not be completed","body":{"mode":"raw","raw":"{\n  \"access_token\": \"tk_live_abc123\",\n  \"connection_id\": \"conn_xyz789\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/connections/preview","host":["{{baseUrl}}"],"path":["api","trackstar","connections","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched\": true,\n    \"connection_id\": \"conn_xyz789\",\n    \"integration_name\": \"mintsoft\",\n    \"integration_display_name\": \"Mintsoft\",\n    \"suggested_name\": \"Mintsoft\",\n    \"message\": null\n  }\n}"}]},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Retrieve a single Trackstar integration instance with its settings. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"My Trackstar WMS\",\n    \"integration_id\": 5,\n    \"connection_settings\": {\n      \"connection_id\": \"conn_xyz789\"\n    },\n    \"integration_settings\": {\n      \"enable_fulfillment\": true\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-01T12:00:00.000Z\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Update an existing Trackstar integration instance. All fields optional. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nintegration_settings includes:\n- fulfillment_cost_financial_line_type_id (optional, int|null): COST financial line type used for Trackstar shipping cost lines. null = auto (default \"Shipping Cost\"). Must be a cost type or returns 422.\n\nWhen the effective cost-line type changes, a reconcile tracked job is dispatched (rewires existing Trackstar cost lines old→new and backfills missing from stored payloads) and the response includes reconcile_tracked_job_log_id.","body":{"mode":"raw","raw":"{\n  \"integration_settings\": {\n    \"fulfillment_cost_financial_line_type_id\": 10\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"name\": \"My Trackstar WMS Updated\",\n    \"integration_id\": 5,\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-20T10:00:00.000Z\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Delete a Trackstar integration instance and all associated data. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Integration instance deleted successfully\"\n}"}]},{"name":"Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get dashboard summary metrics for a Trackstar integration instance (order counts, inventory totals, sync status, etc.). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders_count\": 1250,\n    \"inventory_items_count\": 320,\n    \"products_count\": 180,\n    \"bills_count\": 450,\n    \"last_order_sync_at\": \"2024-06-20T08:30:00.000Z\",\n    \"last_inventory_sync_at\": \"2024-06-20T07:00:00.000Z\"\n  }\n}"}]},{"name":"Test Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Test the connection to the Trackstar API for this integration instance. Returns success/failure with any error details. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Connection successful\",\n    \"response_time_ms\": 245\n  }\n}"}]},{"name":"Preview Cost Line Type Impact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integrationInstance}/cost-line-type/preview","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integrationInstance","cost-line-type","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Trackstar integration instance ID"}]},"description":"Preview how many Trackstar cost financial lines and sales orders would be touched if the fulfillment-cost financial line type changed to new_type_id. Read-only. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- new_type_id (optional, int|null): Proposed cost financial line type id. null = auto default. Must exist.\n\nbackfill_lines counts Trackstar fulfillments whose stored payload carries shipping_cost but have no line yet.","body":{"mode":"raw","raw":"{\n  \"new_type_id\": 10\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integrationInstance}/cost-line-type/preview","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integrationInstance","cost-line-type","preview"],"variable":[{"key":"integrationInstance","value":"1","description":"Trackstar integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"rewire_lines\": 4,\n    \"backfill_lines\": 318,\n    \"sales_orders_impacted\": 320,\n    \"is_noop\": false\n  }\n}"}]},{"name":"Get Connection Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/connection","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","connection"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Fetch the live Trackstar connection payload for the instance — connection metadata, the WMS `available_actions` (which capabilities this WMS supports), and sync schedules. Read-only; degrades gracefully with a `success: false` + message if the connection cannot be reached. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/connection","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","connection"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": null,\n    \"connection\": {\n      \"connection_id\": \"conn_9d04a322e67043b683406f1b609f9a53\",\n      \"integration_name\": \"mintsoft\",\n      \"integration_display_name\": \"Mintsoft\",\n      \"available_actions\": [\n        \"get_inventory\",\n        \"get_products\",\n        \"get_orders\",\n        \"get_inbound_shipments\",\n        \"get_returns\"\n      ],\n      \"sync_schedules\": [\n        {\n          \"function_name\": \"get_inventory\",\n          \"sync_frequency\": 3600,\n          \"sync_status\": \"enabled\",\n          \"last_crawl_start\": \"2026-07-08T00:00:00Z\",\n          \"last_crawl_end\": \"2026-07-08T00:05:00Z\"\n        }\n      ]\n    },\n    \"available_actions\": [\n      \"get_inventory\",\n      \"get_products\",\n      \"get_orders\",\n      \"get_inbound_shipments\",\n      \"get_returns\"\n    ],\n    \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Refresh Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/connection/refresh","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","connection","refresh"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Re-fetch the Trackstar connection and persist the snapshot (and derived `available_actions`) onto the instance so capability-aware behaviour reflects any change in what the WMS supports. Returns the same shape as Get Connection Info. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/connection/refresh","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","connection","refresh"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"success\": true,\n    \"message\": null,\n    \"connection\": {\n      \"connection_id\": \"conn_9d04a322e67043b683406f1b609f9a53\",\n      \"integration_name\": \"mintsoft\",\n      \"integration_display_name\": \"Mintsoft\",\n      \"available_actions\": [\n        \"get_inventory\",\n        \"get_products\",\n        \"get_orders\",\n        \"get_inbound_shipments\",\n        \"get_returns\"\n      ],\n      \"sync_schedules\": [\n        {\n          \"function_name\": \"get_inventory\",\n          \"sync_frequency\": 3600,\n          \"sync_status\": \"enabled\",\n          \"last_crawl_start\": \"2026-07-08T00:00:00Z\",\n          \"last_crawl_end\": \"2026-07-08T00:05:00Z\"\n        }\n      ]\n    },\n    \"available_actions\": [\n      \"get_inventory\",\n      \"get_products\",\n      \"get_orders\",\n      \"get_inbound_shipments\",\n      \"get_returns\"\n    ],\n    \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n  }\n}"}]},{"name":"List Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List all Trackstar warehouse-to-SKU.io warehouse mappings for an integration instance. Returns full warehouse details including locations. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"integration_instance_id\": 10,\n      \"trackstar_warehouse_id\": \"wh_abc123\",\n      \"trackstar_warehouse\": {\n        \"id\": 5,\n        \"trackstar_warehouse_id\": \"wh_abc123\",\n        \"name\": \"East Coast Warehouse\",\n        \"code\": \"ECW\",\n        \"address1\": \"123 Storage Blvd\",\n        \"city\": \"Newark\",\n        \"state\": \"NJ\",\n        \"postal_code\": \"07102\",\n        \"country\": \"US\",\n        \"locations\": []\n      },\n      \"warehouse_id\": 3,\n      \"warehouse_name\": \"NJ Warehouse\",\n      \"is_active\": true,\n      \"created_at\": \"2024-06-01T12:00:00.000Z\",\n      \"updated_at\": \"2024-06-01T12:00:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Create Warehouse Mapping","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Create a mapping between a Trackstar warehouse and a SKU.io warehouse. Returns 422 if the Trackstar warehouse is not found or the mapping already exists. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- trackstar_warehouse_id (required, string): The Trackstar warehouse identifier\n- warehouse_id (optional, integer): The SKU.io warehouse ID to map to","body":{"mode":"raw","raw":"{\n  \"trackstar_warehouse_id\": \"wh_abc123\",\n  \"warehouse_id\": 3\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_instance_id\": 10,\n    \"trackstar_warehouse_id\": \"wh_abc123\",\n    \"warehouse_id\": 3,\n    \"warehouse_name\": \"NJ Warehouse\",\n    \"is_active\": true,\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-01T12:00:00.000Z\"\n  }\n}"}]},{"name":"Sync Warehouses from Trackstar","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/sync-warehouses","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings","sync-warehouses"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull warehouses from Trackstar API, sync them to the local database, and auto-create warehouse mappings for any new warehouses. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/sync-warehouses","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings","sync-warehouses"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouses\": {\n      \"synced\": 3,\n      \"created\": 1,\n      \"updated\": 2\n    },\n    \"mappings_created\": 1\n  },\n  \"message\": \"Synced 3 warehouses (1 created, 2 updated). Created 1 new mappings.\"\n}"}]},{"name":"Update Warehouse Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_mapping}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings",":warehouse_mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"warehouse_mapping","value":"1","description":"Warehouse mapping ID"}]},"description":"Update a warehouse mapping — change the SKU.io warehouse it maps to or toggle active status. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields (all optional):\n- warehouse_id (integer|null): SKU.io warehouse ID (null to unmap)\n- is_active (boolean): Activate or deactivate the mapping","body":{"mode":"raw","raw":"{\n  \"warehouse_id\": 4,\n  \"is_active\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_mapping}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings",":warehouse_mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"warehouse_mapping","value":"1","description":"Warehouse mapping ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"integration_instance_id\": 10,\n    \"trackstar_warehouse_id\": \"wh_abc123\",\n    \"warehouse_id\": 4,\n    \"warehouse_name\": \"CA Warehouse\",\n    \"is_active\": true,\n    \"updated_at\": \"2024-06-20T10:00:00.000Z\"\n  }\n}"}]},{"name":"Delete Warehouse Mapping","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_mapping}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings",":warehouse_mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"warehouse_mapping","value":"1","description":"Warehouse mapping ID"}]},"description":"Delete a warehouse mapping. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/warehouse-mappings/{warehouse_mapping}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","warehouse-mappings",":warehouse_mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"warehouse_mapping","value":"1","description":"Warehouse mapping ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null,\n  \"message\": \"Warehouse mapping deleted successfully\"\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List Trackstar orders for an integration instance with pagination, filtering, and sorting.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters (Spatie QueryBuilder):\n- filter[search]: Partial match on order_number or trackstar_order_id\n- filter[status]: Exact enum match. Values: processing, picked, packed, fulfilled, cancelled, other\n- filter[has_fulfillment]: true/1 or false/0\n- filter[date_from]: Orders on or after this date (reads from json_object.order_date or created_date)\n- filter[date_to]: Orders on or before this date\n\nAllowed sorts: id, order_number, status, created_at, updated_at\nDefault sort: -created_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 301,\n      \"integration_instance_id\": 10,\n      \"trackstar_id\": \"ts-ord-001\",\n      \"order_number\": \"ORD-12345\",\n      \"status\": \"fulfilled\",\n      \"warehouse\": \"wh_abc123\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"order_date\": \"2024-06-01T00:00:00.000Z\",\n      \"shipped_at\": \"2024-06-03T14:00:00.000Z\",\n      \"channel_id\": \"SO-2024-001\",\n      \"channel_name\": \"Shopify Store\",\n      \"created_at\": \"2024-06-01T12:00:00.000Z\",\n      \"updated_at\": \"2024-06-03T14:00:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 84,\n  \"per_page\": 15,\n  \"total\": 1250,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Sync Orders (Queued)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync?start_date=2024-01-01&end_date=2024-06-30","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync"],"query":[{"key":"start_date","value":"2024-01-01","description":"Optional start date for order sync range","disabled":true},{"key":"end_date","value":"2024-06-30","description":"Optional end date for order sync range","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Queue a background job to sync orders from Trackstar API. Returns a tracked_job_log_id to monitor progress via the sync-progress endpoint. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- start_date (optional): Date range start for sync\n- end_date (optional): Date range end for sync\n- status (optional): Filter by order status; pass 'all' to sync all statuses"},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync?start_date=2024-01-01&end_date=2024-06-30","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync"],"query":[{"key":"start_date","value":"2024-01-01","description":"Optional start date for order sync range","disabled":true},{"key":"end_date","value":"2024-06-30","description":"Optional end date for order sync range","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 892\n  },\n  \"message\": \"Order sync job has been queued\"\n}"}]},{"name":"Get Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackedJobLogId","value":"892","description":"Tracked job log ID from sync response"}]},"description":"Poll the progress of a queued order sync job. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackedJobLogId","value":"892","description":"Tracked job log ID from sync response"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 892,\n    \"job_name\": \"Sync Trackstar Orders: My Trackstar WMS\",\n    \"status\": \"processing\",\n    \"progress\": 45,\n    \"total\": 100,\n    \"created_at\": \"2024-06-20T09:00:00.000Z\",\n    \"updated_at\": \"2024-06-20T09:01:30.000Z\"\n  }\n}"}]},{"name":"Show Order by Trackstar ID","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/by-trackstar-id/{trackstar_id}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","by-trackstar-id",":trackstar_id"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackstar_id","value":"ts-ord-001","description":"The Trackstar order ID string"}]},"description":"Retrieve an order by its Trackstar ID string. Includes json_object in the response. Returns 404 if not found. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/by-trackstar-id/{trackstar_id}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","by-trackstar-id",":trackstar_id"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackstar_id","value":"ts-ord-001","description":"The Trackstar order ID string"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 301,\n    \"integration_instance_id\": 10,\n    \"trackstar_id\": \"ts-ord-001\",\n    \"order_number\": \"ORD-12345\",\n    \"status\": \"fulfilled\",\n    \"warehouse\": \"wh_abc123\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"order_date\": \"2024-06-01T00:00:00.000Z\",\n    \"shipped_at\": \"2024-06-03T14:00:00.000Z\",\n    \"channel_id\": \"SO-2024-001\",\n    \"channel_name\": \"Shopify Store\",\n    \"json_object\": {\n      \"id\": \"ts-ord-001\",\n      \"order_number\": \"ORD-12345\",\n      \"shipments\": []\n    },\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-03T14:00:00.000Z\"\n  }\n}"}]},{"name":"Show Order by Database ID","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]},"description":"Retrieve an order by its database ID. Includes json_object. Verifies the order belongs to the integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 301,\n    \"integration_instance_id\": 10,\n    \"trackstar_id\": \"ts-ord-001\",\n    \"order_number\": \"ORD-12345\",\n    \"status\": \"fulfilled\",\n    \"json_object\": {\n      \"id\": \"ts-ord-001\",\n      \"shipments\": [\n        {\n          \"shipped_date\": \"2024-06-03\",\n          \"packages\": [\n            {\n              \"tracking_number\": \"1Z999AA10123456784\",\n              \"carrier_name\": \"UPS\"\n            }\n          ]\n        }\n      ]\n    },\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-03T14:00:00.000Z\"\n  }\n}"}]},{"name":"Order Detail (Raw JSON)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]},"description":"Get the full raw json_object for an order as stored from the Trackstar API. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"json_object\": {\n      \"id\": \"ts-ord-001\",\n      \"order_number\": \"ORD-12345\",\n      \"status\": \"fulfilled\",\n      \"shipments\": [\n        {\n          \"shipped_date\": \"2024-06-03\",\n          \"packages\": [\n            {\n              \"tracking_number\": \"1Z999AA10123456784\",\n              \"carrier_name\": \"UPS\"\n            }\n          ]\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Sync Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]},"description":"Pull fresh order detail from the Trackstar API and update the local record. Returns the updated order data. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"301","description":"Order database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 301,\n    \"integration_instance_id\": 10,\n    \"trackstar_id\": \"ts-ord-001\",\n    \"order_number\": \"ORD-12345\",\n    \"status\": \"fulfilled\",\n    \"warehouse_id\": null,\n    \"order_date\": \"2024-06-01\",\n    \"sku_fulfillment_id\": 55,\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipped_at\": \"2024-06-03T14:00:00.000Z\",\n    \"created_at\": \"2024-06-01T12:00:00.000Z\",\n    \"updated_at\": \"2024-06-20T10:00:00.000Z\"\n  }\n}"}]},{"name":"Get Raw Order from Trackstar","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"1","description":"Order database ID"}]},"description":"Fetch the order LIVE from the Trackstar API as the raw, untransformed payload (nothing is persisted). The order payload is returned under `data.product`. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"1","description":"Order database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": \"ord_2b7c1e\",\n      \"order_number\": \"915404R\",\n      \"reference_id\": \"#915404R\",\n      \"status\": \"fulfilled\",\n      \"warehouse_id\": \"3\",\n      \"line_items\": [\n        {\n          \"sku\": \"TEST-UK-001\",\n          \"product_id\": \"prod_18\",\n          \"quantity\": 2\n        }\n      ],\n      \"created_date\": \"2026-05-20T07:38:00Z\",\n      \"updated_date\": \"2026-06-02T02:10:00Z\"\n    }\n  },\n  \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n}"}]},{"name":"Get Orders Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Baseline info for the Refresh Orders modal: the latest synced order (identifier + date) and the total synced count, so the UI can offer a \"fetch since latest sync\" option. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_number\": \"915404R\",\n    \"latest_order_date\": \"2026-06-02T02:10:00.000000Z\",\n    \"total_orders\": 42\n  }\n}"}]},{"name":"Search Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Search Trackstar live for orders matching a query (order number / reference, or a Trackstar order id). Each result is flagged with whether it already exists locally so the caller can decide to download vs update. Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"query\": \"915404R\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"ord_2b7c1e\",\n      \"order_number\": \"915404R\",\n      \"reference_id\": \"#915404R\",\n      \"status\": \"fulfilled\",\n      \"created_date\": \"2026-05-20T07:38:00Z\",\n      \"total_price\": 129.99,\n      \"currency\": \"USD\",\n      \"exists_in_database\": true\n    }\n  ]\n}"}]},{"name":"Download Order from Trackstar","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Download (or update) a single order live from Trackstar by its Trackstar order id and persist it. Backs the search tab's per-result Download/Update action. Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"ord_2b7c1e\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1\n  },\n  \"message\": \"Order refreshed from Trackstar\"\n}"}]},{"name":"Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"1","description":"Order database ID"}]},"description":"Paginated activity log for a single order (order detail page Activity Log tab). Supports `filter[search]`, `per_page`. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order","value":"1","description":"Order database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"TrackstarOrder\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"fulfilled\"\n        }\n      },\n      \"causer_name\": \"System\",\n      \"created_at\": \"2026-07-08T12:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Order Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/order-shipments?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","order-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List outbound fulfillment shipments for a Trackstar integration instance, with pagination, filtering, and sorting.\n\nAuthentication: Requires Bearer token.\n\nEach shipment is scoped to the integration instance through its parent order.\n\nSearch:\n- filter[search]: Partial match across tracking_number, trackstar_shipment_id, carrier, and shipping_method\n\nOperator filters use the form filter[column.operator]=value (a bare filter[column]=value is treated as an exact 'is' match):\n- Text columns (tracking_number, trackstar_shipment_id, carrier, shipping_method): is, is_not, contains, does_not_contain, starts_with, ends_with, is_one_of, is_not_one_of, is_empty, is_not_empty\n- Numeric columns (id, shipping_cost): is, is_not, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_one_of, is_empty, is_not_empty\n- Date-time columns (shipped_at, created_at, updated_at): is, before, after, on_or_before, on_or_after, between, today, yesterday, past_week, past_month, past_year, past_days, is_empty, is_not_empty\n\nAllowed sorts: id, trackstar_shipment_id, tracking_number, carrier, shipping_method, shipping_cost, shipped_at, created_at, updated_at\nDefault sort: -shipped_at\nPagination default: 10 per page"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/order-shipments?page=1&per_page=10","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","order-shipments"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5001,\n      \"trackstar_order_id\": 301,\n      \"trackstar_shipment_id\": \"ts-ship-001\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"shipping_method\": \"Ground\",\n      \"shipping_cost\": 12.45,\n      \"shipped_at\": \"2024-06-03T14:00:00+00:00\",\n      \"created_at\": \"2024-06-03T14:05:00+00:00\",\n      \"updated_at\": \"2024-06-03T14:05:00+00:00\",\n      \"order\": {\n        \"id\": 301,\n        \"order_number\": \"ORD-12345\",\n        \"trackstar_order_id\": \"ts-ord-001\",\n        \"link_reference\": \"ORD-12345\",\n        \"link_type_label\": \"Trackstar Order\",\n        \"link_id\": 301,\n        \"link_route\": \"/integrations/trackstar/10/orders/301\"\n      },\n      \"sku_sales_order_fulfillment_id\": 8801,\n      \"sku_fulfillment\": {\n        \"id\": 8801,\n        \"link_reference\": 8801,\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 8801,\n        \"link_route\": \"/orders/sales-orders/fulfillments/8801\",\n        \"status\": \"shipped\",\n        \"tracking_number\": \"1Z999AA10123456784\",\n        \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n        \"sales_order_id\": 4501,\n        \"sales_order_number\": \"SO-2024-001\"\n      },\n      \"sales_order_id\": 4501,\n      \"sales_order_number\": \"SO-2024-001\",\n      \"warehouse\": {\n        \"id\": 12,\n        \"name\": \"Main Warehouse\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 12,\n  \"per_page\": 10,\n  \"total\": 118,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Get Order Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/order-shipments/{order_shipment}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","order-shipments",":order_shipment"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order_shipment","value":"5001","description":"Order shipment database ID"}]},"description":"Retrieve a single order shipment by its database ID, scoped to the integration instance. The response always includes the raw json_object payload received from Trackstar. Returns 404 if the shipment does not exist or does not belong to the integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/order-shipments/{order_shipment}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","order-shipments",":order_shipment"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"order_shipment","value":"5001","description":"Order shipment database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5001,\n    \"trackstar_order_id\": 301,\n    \"trackstar_shipment_id\": \"ts-ship-001\",\n    \"tracking_number\": \"1Z999AA10123456784\",\n    \"carrier\": \"UPS\",\n    \"shipping_method\": \"Ground\",\n    \"shipping_cost\": 12.45,\n    \"shipped_at\": \"2024-06-03T14:00:00+00:00\",\n    \"created_at\": \"2024-06-03T14:05:00+00:00\",\n    \"updated_at\": \"2024-06-03T14:05:00+00:00\",\n    \"order\": {\n      \"id\": 301,\n      \"order_number\": \"ORD-12345\",\n      \"trackstar_order_id\": \"ts-ord-001\",\n      \"link_reference\": \"ORD-12345\",\n      \"link_type_label\": \"Trackstar Order\",\n      \"link_id\": 301,\n      \"link_route\": \"/integrations/trackstar/10/orders/301\"\n    },\n    \"sku_sales_order_fulfillment_id\": 8801,\n    \"sku_fulfillment\": {\n      \"id\": 8801,\n      \"link_reference\": 8801,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 8801,\n      \"link_route\": \"/orders/sales-orders/fulfillments/8801\",\n      \"status\": \"shipped\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"tracking_url\": \"https://www.ups.com/track?tracknum=1Z999AA10123456784\",\n      \"sales_order_id\": 4501,\n      \"sales_order_number\": \"SO-2024-001\"\n    },\n    \"sales_order_id\": 4501,\n    \"sales_order_number\": \"SO-2024-001\",\n    \"warehouse\": {\n      \"id\": 12,\n      \"name\": \"Main Warehouse\"\n    },\n    \"json_object\": {\n      \"id\": \"ts-ship-001\",\n      \"order_id\": \"ts-ord-001\",\n      \"tracking_number\": \"1Z999AA10123456784\",\n      \"carrier\": \"UPS\",\n      \"shipping_method\": \"Ground\",\n      \"shipping_cost\": 12.45,\n      \"shipped_date\": \"2024-06-03T14:00:00Z\"\n    }\n  }\n}"}]},{"name":"List Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List all inventory items for a Trackstar integration instance. Optionally filter by warehouse. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- warehouse_id (optional, string): Trackstar warehouse ID to filter by"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 201,\n      \"integration_instance_id\": 10,\n      \"sku\": \"PROD-001\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"on_hand\": 150,\n      \"available\": 120,\n      \"committed\": 30,\n      \"incoming\": 50,\n      \"json_object\": {},\n      \"created_at\": \"2024-06-01T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-20T06:00:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Sync Inventory","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull current inventory levels from the Trackstar API and update the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory synced successfully\",\n  \"synced_count\": 320\n}"}]},{"name":"Low Stock Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/low-stock?threshold=10","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","low-stock"],"query":[{"key":"threshold","value":"10","description":"Available quantity threshold (default: 10). Items with available <= threshold are returned.","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get inventory items with available quantity at or below the threshold. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- threshold (optional, integer): Available quantity ceiling (default: 10)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/low-stock?threshold=10","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","low-stock"],"query":[{"key":"threshold","value":"10","description":"Available quantity threshold (default: 10). Items with available <= threshold are returned.","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 202,\n      \"integration_instance_id\": 10,\n      \"sku\": \"PROD-LOW-001\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"on_hand\": 8,\n      \"available\": 5,\n      \"committed\": 3,\n      \"incoming\": 0,\n      \"created_at\": \"2024-06-01T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-20T06:00:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Out of Stock Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/out-of-stock","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","out-of-stock"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get inventory items with zero available quantity. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/out-of-stock","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","out-of-stock"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 203,\n      \"sku\": \"PROD-OOS-001\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"on_hand\": 0,\n      \"available\": 0,\n      \"committed\": 0,\n      \"incoming\": 25\n    }\n  ]\n}"}]},{"name":"Totals by SKU","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/totals-by-sku","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","totals-by-sku"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get inventory quantities aggregated (summed) by SKU across all warehouses. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/totals-by-sku","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","totals-by-sku"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"PROD-001\",\n      \"on_hand\": 300,\n      \"available\": 240,\n      \"committed\": 60,\n      \"incoming\": 100\n    },\n    {\n      \"sku\": \"PROD-002\",\n      \"on_hand\": 80,\n      \"available\": 80,\n      \"committed\": 0,\n      \"incoming\": 0\n    }\n  ]\n}"}]},{"name":"Inventory Discrepancies","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/discrepancies","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","discrepancies"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Compare Trackstar inventory levels to SKU.io inventory and return items where quantities differ. Also returns warehouse list and last sync timestamp. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/discrepancies","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","discrepancies"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"PROD-001\",\n      \"trackstar_qty\": 150,\n      \"sku_qty\": 140,\n      \"discrepancy\": 10\n    }\n  ],\n  \"warehouses\": [\n    {\n      \"id\": \"wh_abc123\",\n      \"name\": \"East Coast Warehouse\"\n    }\n  ],\n  \"last_synced_at\": \"2024-06-20T07:00:00+00:00\"\n}"}]},{"name":"Items Without SKU Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/without-sku-products","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","without-sku-products"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get Trackstar inventory items that have no matching SKU.io product (by SKU). Useful for finding new products to create. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/without-sku-products","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","without-sku-products"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"sku\": \"NEW-SKU-001\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"on_hand\": 25,\n      \"available\": 25\n    }\n  ]\n}"}]},{"name":"SKU Products Without Trackstar Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/without-trackstar-inventory","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","without-trackstar-inventory"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get SKU.io products that have no matching Trackstar inventory record. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/without-trackstar-inventory","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","without-trackstar-inventory"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"sku\": \"PROD-MISSING\",\n      \"name\": \"Missing Product\"\n    }\n  ]\n}"}]},{"name":"Get Last Synced At","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/last-synced-at","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","last-synced-at"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get the timestamp of the most recent inventory sync for this integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/last-synced-at","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","last-synced-at"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"last_synced_at\": \"2024-06-20T07:00:00+00:00\"\n  }\n}"}]},{"name":"Create Stock Take from Discrepancies","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/create-stock-take","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","create-stock-take"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Create a SKU.io stock take pre-populated with quantities from Trackstar inventory discrepancies. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- product_ids (optional, array of integers): Limit stock take to specific product IDs\n- warehouse_id (optional, integer): SKU.io warehouse ID for the stock take\n- notes (optional, string, max 500): Notes for the stock take\n- date (optional, date Y-m-d): Stock take date\n- status (optional, string): draft, open, or closed","body":{"mode":"raw","raw":"{\n  \"product_ids\": [\n    55,\n    56,\n    57\n  ],\n  \"warehouse_id\": 3,\n  \"notes\": \"Stock take from Trackstar discrepancy report\",\n  \"date\": \"2024-06-20\",\n  \"status\": \"open\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory/create-stock-take","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory","create-stock-take"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"warehouse_id\": 3,\n    \"status\": \"open\",\n    \"date\": \"2024-06-20\",\n    \"notes\": \"Stock take from Trackstar discrepancy report\",\n    \"lines_count\": 3\n  },\n  \"message\": \"Stock take created successfully from Trackstar discrepancies\"\n}"}]},{"name":"List Inventory Ledger","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List paginated inventory ledger entries (movement history) for a Trackstar integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"integration_instance_id\": 10,\n      \"trackstar_ledger_id\": \"led_001\",\n      \"inventory_item_id\": \"item_abc\",\n      \"sku\": \"PROD-001\",\n      \"quantity\": -5,\n      \"event_type\": \"outbound\",\n      \"raw_event_type\": \"SHIP\",\n      \"reason\": \"Order fulfillment\",\n      \"object_id\": \"ts-ord-001\",\n      \"object_type\": \"order\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"location_id\": \"loc_001\",\n      \"additional_fields\": null,\n      \"entry_date\": \"2024-06-03T14:00:00.000Z\",\n      \"trackstar_created_at\": \"2024-06-03T14:05:00.000Z\",\n      \"trackstar_updated_at\": \"2024-06-03T14:05:00.000Z\",\n      \"event_type_display\": \"Outbound\",\n      \"formatted_quantity\": \"-5\",\n      \"created_at\": \"2024-06-03T14:10:00.000Z\",\n      \"updated_at\": \"2024-06-03T14:10:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 200,\n  \"per_page\": 15,\n  \"total\": 3000\n}"}]},{"name":"Sync Inventory Ledger","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull inventory ledger entries from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inventory ledger synced successfully\",\n  \"synced\": 150,\n  \"created\": 80,\n  \"updated\": 70\n}"}]},{"name":"Get Ledger Filters","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/filters","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","filters"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get available filter options for the inventory ledger (distinct event types, object types, and warehouse IDs). Useful for populating filter dropdowns in the UI. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/filters","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","filters"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"event_types\": [\n    \"inbound\",\n    \"outbound\",\n    \"adjustment\",\n    \"transfer\"\n  ],\n  \"object_types\": [\n    \"order\",\n    \"receipt\",\n    \"adjustment\"\n  ],\n  \"warehouse_ids\": [\n    \"wh_abc123\",\n    \"wh_def456\"\n  ]\n}"}]},{"name":"Get Ledger Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/summary","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","summary"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get summary statistics for the inventory ledger (totals by event type, date ranges, etc.). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inventory-ledger/summary","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inventory-ledger","summary"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_entries\": 3000,\n  \"total_inbound\": 1200,\n  \"total_outbound\": 1800,\n  \"earliest_entry\": \"2024-01-01T00:00:00.000Z\",\n  \"latest_entry\": \"2024-06-20T14:00:00.000Z\"\n}"}]},{"name":"List Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List all Trackstar products for an integration instance. Supports search and active-only filtering. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- search (optional, string): Search by SKU or product name\n- active_only (optional, boolean): Return only active products"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 401,\n      \"integration_instance_id\": 10,\n      \"trackstar_product_id\": \"prod_abc123\",\n      \"sku\": \"PROD-001\",\n      \"name\": \"Blue Widget\",\n      \"gtin\": 12345678901,\n      \"unit_price\": 24.99,\n      \"is_kit\": false,\n      \"active\": true,\n      \"supplier\": \"Acme Corp\",\n      \"country_of_origin\": \"US\",\n      \"harmonized_code\": \"8473.30\",\n      \"warehouse_customer_id\": \"cust_001\",\n      \"inventory_items\": [],\n      \"supplier_products\": [],\n      \"trackstar_tags\": [\n        \"widget\",\n        \"blue\"\n      ],\n      \"additional_fields\": null,\n      \"external_system_url\": null,\n      \"json_object\": {},\n      \"trackstar_created_at\": \"2024-01-01T00:00:00.000Z\",\n      \"trackstar_updated_at\": \"2024-06-01T00:00:00.000Z\",\n      \"created_at\": \"2024-01-01T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-01T00:00:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Sync Products","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull all products from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Products synced successfully\",\n  \"synced_count\": 180\n}"}]},{"name":"List Kit Products","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/kits","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","kits"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get all Trackstar products that are kits (is_kit = true). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/kits","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","kits"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 402,\n      \"sku\": \"KIT-001\",\n      \"name\": \"Widget Bundle\",\n      \"is_kit\": true,\n      \"active\": true,\n      \"inventory_items\": [\n        {\n          \"sku\": \"PROD-001\",\n          \"quantity\": 2\n        },\n        {\n          \"sku\": \"PROD-002\",\n          \"quantity\": 1\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Get Product by SKU","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/by-sku?sku=PROD-001","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","by-sku"],"query":[{"key":"sku","value":"PROD-001","description":"The SKU to look up","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Find a Trackstar product by its SKU. Returns null data if not found or if sku parameter is missing. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- sku (optional, string): Product SKU to find"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/by-sku?sku=PROD-001","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","by-sku"],"query":[{"key":"sku","value":"PROD-001","description":"The SKU to look up","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 401,\n    \"trackstar_product_id\": \"prod_abc123\",\n    \"sku\": \"PROD-001\",\n    \"name\": \"Blue Widget\",\n    \"active\": true,\n    \"unit_price\": 24.99\n  }\n}"}]},{"name":"Show Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"401","description":"Trackstar product database ID"}]},"description":"Get a single Trackstar product by database ID. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"401","description":"Trackstar product database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 401,\n    \"integration_instance_id\": 10,\n    \"trackstar_product_id\": \"prod_abc123\",\n    \"sku\": \"PROD-001\",\n    \"name\": \"Blue Widget\",\n    \"gtin\": 12345678901,\n    \"unit_price\": 24.99,\n    \"is_kit\": false,\n    \"active\": true,\n    \"supplier\": \"Acme Corp\",\n    \"country_of_origin\": \"US\",\n    \"harmonized_code\": \"8473.30\",\n    \"warehouse_customer_id\": \"cust_001\",\n    \"inventory_items\": [],\n    \"supplier_products\": [],\n    \"trackstar_tags\": [\n      \"widget\",\n      \"blue\"\n    ],\n    \"trackstar_created_at\": \"2024-01-01T00:00:00.000Z\",\n    \"trackstar_updated_at\": \"2024-06-01T00:00:00.000Z\",\n    \"created_at\": \"2024-01-01T00:00:00.000Z\",\n    \"updated_at\": \"2024-06-01T00:00:00.000Z\"\n  }\n}"}]},{"name":"Get Raw Product from Trackstar","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"1","description":"Product database ID"}]},"description":"Fetch the product LIVE from the Trackstar API as the raw, untransformed payload (nothing is persisted). The product payload is returned under `data.product`. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"1","description":"Product database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": \"prod_18\",\n      \"sku\": \"EasyRemote\",\n      \"name\": \"Remote for Max, Ultimate and Horizon\",\n      \"active\": true,\n      \"unit_price\": 0,\n      \"inventory_items\": [\n        {\n          \"inventory_item_id\": \"ii_101\",\n          \"quantity\": 42\n        }\n      ]\n    }\n  },\n  \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n}"}]},{"name":"Get Products Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/sync-info","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","sync-info"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Baseline for the Refresh Products modal: latest synced product + total count. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/sync-info","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products","sync-info"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_product_title\": \"Rouge Max G3 Wall Mounted\",\n    \"latest_product_date\": \"2026-07-08T15:05:00.000000Z\",\n    \"total_products\": 19\n  }\n}"}]},{"name":"Product Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}/activity-log","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product","activity-log"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"1","description":"Product database ID"}]},"description":"Paginated activity log for a single product (product detail page Activity Log tab). Supports `filter[search]`, `per_page`. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/products/{product}/activity-log","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","products",":product","activity-log"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"product","value":"1","description":"Product database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"TrackstarOrder\",\n      \"subject_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"fulfilled\"\n        }\n      },\n      \"causer_name\": \"System\",\n      \"created_at\": \"2026-07-08T12:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"List Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List paginated Trackstar bills (WMS charges) for an integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilters (Spatie QueryBuilder):\n- filter[search]: Partial match on trackstar_bill_id, object_id, warehouse_customer_id, charge_type\n- filter[charge_type]: Exact match on charge type\n- filter[object_type]: Exact match on object type\n- filter[object_id]: Exact match on object ID\n- filter[date_from]: Bills with trackstar_created_at on or after this date\n- filter[date_to]: Bills with trackstar_created_at on or before this date\n\nAllowed sorts: id, charge_type, object_type, amount, trackstar_created_at, created_at\nDefault sort: -trackstar_created_at"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 601,\n      \"integration_instance_id\": 10,\n      \"trackstar_bill_id\": \"bill_001\",\n      \"warehouse_customer_id\": \"cust_001\",\n      \"object_id\": \"ts-ord-001\",\n      \"object_type\": \"order\",\n      \"charge_type\": \"pick_and_pack\",\n      \"amount\": 3.5,\n      \"currency_code\": \"USD\",\n      \"formatted_amount\": \"$3.50\",\n      \"additional_fields\": null,\n      \"trackstar_created_at\": \"2024-06-03T15:00:00.000Z\",\n      \"trackstar_updated_at\": \"2024-06-03T15:00:00.000Z\",\n      \"created_at\": \"2024-06-03T15:05:00.000Z\",\n      \"updated_at\": \"2024-06-03T15:05:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 30,\n  \"per_page\": 15,\n  \"total\": 450\n}"}]},{"name":"Sync Bills","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull bills from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Bills synced successfully\",\n  \"synced_count\": 450\n}"}]},{"name":"Get Charge Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/charge-types","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","charge-types"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get all distinct charge types present in bills for this integration instance. Useful for populating filter dropdowns. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/charge-types","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","charge-types"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"pick_and_pack\",\n    \"receiving\",\n    \"storage\",\n    \"shipping\",\n    \"special_handling\"\n  ]\n}"}]},{"name":"Get Object Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/object-types","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","object-types"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get all distinct object types present in bills for this integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/object-types","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","object-types"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"order\",\n    \"receipt\",\n    \"adjustment\"\n  ]\n}"}]},{"name":"Bills Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/summary","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","summary"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get bill totals grouped by charge type and currency. Provides a financial overview of WMS charges. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/bills/summary","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","bills","summary"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"charge_type\": \"pick_and_pack\",\n      \"total_amount\": 1575,\n      \"bill_count\": 450,\n      \"currency_code\": \"USD\"\n    },\n    {\n      \"charge_type\": \"receiving\",\n      \"total_amount\": 320,\n      \"bill_count\": 64,\n      \"currency_code\": \"USD\"\n    },\n    {\n      \"charge_type\": \"storage\",\n      \"total_amount\": 890.5,\n      \"bill_count\": 90,\n      \"currency_code\": \"USD\"\n    }\n  ]\n}"}]},{"name":"List Shipping Methods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List every Trackstar shipping method for this integration instance together with the SKU.io shipping methods available to map onto. Drives the mapping editor. Requires a Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"services\": [\n      {\n        \"id\": 12,\n        \"trackstar_shipping_method_id\": \"sm_9f3a2b7c\",\n        \"name\": \"Ground\",\n        \"carrier\": \"UPS\",\n        \"carrier_name\": \"UPS\",\n        \"carrier_id\": \"ups\",\n        \"scac\": \"UPSN\",\n        \"shipping_method_id\": 5,\n        \"sku_shipping_method_name\": \"UPS Ground\"\n      },\n      {\n        \"id\": 13,\n        \"trackstar_shipping_method_id\": \"sm_1a2b3c4d\",\n        \"name\": \"Priority Mail\",\n        \"carrier\": \"USPS\",\n        \"carrier_name\": \"USPS\",\n        \"carrier_id\": \"usps\",\n        \"scac\": \"USPS\",\n        \"shipping_method_id\": null,\n        \"sku_shipping_method_name\": null\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 5,\n        \"name\": \"Ground\",\n        \"full_name\": \"UPS Ground\",\n        \"type\": \"domestic\"\n      },\n      {\n        \"id\": 6,\n        \"name\": \"Priority Mail\",\n        \"full_name\": \"USPS Priority Mail\",\n        \"type\": \"domestic\"\n      }\n    ]\n  }\n}"}]},{"name":"Sync Shipping Methods","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull shipping methods from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shipping methods synced successfully\",\n  \"synced_count\": 15\n}"}]},{"name":"Get Carriers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/carriers","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","carriers"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get a list of distinct carrier names available in Trackstar shipping methods for this integration. Useful for populating carrier filter dropdowns. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/carriers","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","carriers"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    \"DHL\",\n    \"FedEx\",\n    \"UPS\",\n    \"USPS\"\n  ]\n}"}]},{"name":"Update Shipping Method Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/{trackstar_shipping_method}/mapping","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods",":trackstar_shipping_method","mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackstar_shipping_method","value":"701","description":"Trackstar shipping method database ID"}]},"description":"Map a Trackstar shipping method to a SKU.io shipping method. Set shipping_method_id to null to unmap. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body fields:\n- shipping_method_id (nullable, integer): SKU.io shipping method ID to map to","body":{"mode":"raw","raw":"{\n  \"shipping_method_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/{trackstar_shipping_method}/mapping","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods",":trackstar_shipping_method","mapping"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"trackstar_shipping_method","value":"701","description":"Trackstar shipping method database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 701,\n    \"trackstar_shipping_method_id\": \"sm_001\",\n    \"name\": \"UPS Ground\",\n    \"carrier\": \"UPS\",\n    \"shipping_method_id\": 12,\n    \"sku_shipping_method\": {\n      \"id\": 12,\n      \"name\": \"UPS Ground\",\n      \"full_name\": \"UPS Ground - Standard\",\n      \"carrier_name\": \"UPS\"\n    },\n    \"updated_at\": \"2024-06-20T10:00:00.000Z\"\n  }\n}"}]},{"name":"Bulk Map Shipping Methods","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Map many Trackstar shipping methods (by their SKU.io record id) to a single SKU.io shipping method in one call. Set shipping_method_id to null to clear the mappings. Requires a Bearer token.\n\nBody: ids (array of integers, required) — the Trackstar shipping-method ids; shipping_method_id (integer, nullable) — the SKU.io shipping method to assign, or null to unmap.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    12,\n    13,\n    14\n  ],\n  \"shipping_method_id\": 5\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"updated_count\": 3\n  },\n  \"message\": \"3 mapping(s) saved\"\n}"}]},{"name":"Auto-match Shipping Methods","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/auto-match","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","auto-match"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Auto-link unmapped Trackstar shipping methods to SKU.io shipping methods whose name matches (case, spacing and punctuation are ignored; also tries carrier + name). Never overwrites an existing mapping. Runs automatically on sync; this endpoint re-runs it on demand. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/auto-match","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","auto-match"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"matched_count\": 5\n  },\n  \"message\": \"5 method(s) auto-matched\"\n}"}]},{"name":"Export Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Download the current shipping-method mappings as a re-importable CSV (columns: trackstar_shipping_method_id, name, carrier, carrier_name, scac, shipping_method_id, shipping_method_name). A row with a blank shipping method clears that mapping on import. Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"trackstar_shipping_method_id,name,carrier,carrier_name,scac,shipping_method_id,shipping_method_name\nsm_9f3a2b7c,Ground,UPS,UPS,UPSN,5,UPS Ground\nsm_1a2b3c4d,Priority Mail,USPS,USPS,USPS,,\n"}]},{"name":"Import Shipping Method Mappings","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Import shipping-method mappings from a CSV. Each row is matched to a Trackstar method by trackstar_shipping_method_id and resolves the SKU.io method by shipping_method_id (preferred) or shipping_method_name. Requires a Bearer token.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 2,\n    \"updated\": 1,\n    \"deleted\": 0,\n    \"errors\": [\n      \"Line 4: SKU shipping method id '99999' not found\"\n    ]\n  },\n  \"message\": \"Import processed\"\n}"}]},{"name":"List Inbound Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List paginated inbound shipments (receipts/PO receipts) for a Trackstar integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 801,\n      \"integration_instance_id\": 10,\n      \"trackstar_id\": \"ship_001\",\n      \"purchase_order_number\": \"PO-2024-001\",\n      \"status\": \"received\",\n      \"warehouse\": \"wh_abc123\",\n      \"expected_arrival_date\": \"2024-06-15\",\n      \"created_at\": \"2024-06-01T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-15T12:00:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 15,\n  \"total\": 72\n}"}]},{"name":"Sync Inbound Shipments","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull inbound shipments from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Inbound shipments synced successfully\",\n  \"synced_count\": 72\n}"}]},{"name":"In-Transit Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/in-transit","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments","in-transit"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get inbound shipments currently in transit (not yet received). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/in-transit","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments","in-transit"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 802,\n      \"trackstar_id\": \"ship_002\",\n      \"purchase_order_number\": \"PO-2024-002\",\n      \"status\": \"in_transit\",\n      \"warehouse\": \"wh_abc123\",\n      \"expected_arrival_date\": \"2024-06-25\"\n    }\n  ]\n}"}]},{"name":"Show Inbound Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments",":inbound_shipment"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"inbound_shipment","value":"801","description":"Inbound shipment database ID"}]},"description":"Get a single inbound shipment. Includes json_object in the response. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/{inbound_shipment}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments",":inbound_shipment"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"inbound_shipment","value":"801","description":"Inbound shipment database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 801,\n    \"integration_instance_id\": 10,\n    \"trackstar_id\": \"ship_001\",\n    \"purchase_order_number\": \"PO-2024-001\",\n    \"status\": \"received\",\n    \"warehouse\": \"wh_abc123\",\n    \"expected_arrival_date\": \"2024-06-15\",\n    \"json_object\": {\n      \"id\": \"ship_001\",\n      \"purchase_order_number\": \"PO-2024-001\",\n      \"line_items\": []\n    },\n    \"created_at\": \"2024-06-01T00:00:00.000Z\",\n    \"updated_at\": \"2024-06-15T12:00:00.000Z\"\n  }\n}"}]},{"name":"Get Inbound Shipment Raw Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/{inbound_shipment}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments",":inbound_shipment","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"inbound_shipment","value":"1","description":"Inbound shipment database ID"}]},"description":"Fetch an inbound shipment LIVE from the Trackstar API (untransformed) for the raw-data viewer. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/inbound-shipments/{inbound_shipment}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","inbound-shipments",":inbound_shipment","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"inbound_shipment","value":"1","description":"Inbound shipment database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": \"ship_2b7c1e\",\n      \"purchase_order_number\": \"PO-915404\",\n      \"status\": \"in_transit\",\n      \"warehouse_id\": \"3\",\n      \"line_items\": [\n        {\n          \"sku\": \"TEST-UK-001\",\n          \"product_id\": \"prod_18\",\n          \"expected_quantity\": 100,\n          \"received_quantity\": 0\n        }\n      ],\n      \"expected_arrival_date\": \"2026-06-10T00:00:00Z\",\n      \"created_date\": \"2026-05-20T07:38:00Z\",\n      \"updated_date\": \"2026-06-02T02:10:00Z\"\n    }\n  },\n  \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n}"}]},{"name":"List Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List paginated customer returns for a Trackstar integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Items per page","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 901,\n      \"integration_instance_id\": 10,\n      \"trackstar_id\": \"ret_001\",\n      \"order_id\": \"ts-ord-001\",\n      \"status\": \"received\",\n      \"raw_status\": \"RECEIVED\",\n      \"warehouse_customer_id\": \"cust_001\",\n      \"warehouse_id\": \"wh_abc123\",\n      \"tracking_number\": \"1Z999AA10123456999\",\n      \"carrier\": \"UPS\",\n      \"notes\": \"Customer return - wrong size\",\n      \"notes_array\": [\n        \"Customer return - wrong size\"\n      ],\n      \"line_items\": [\n        {\n          \"inventory_item_id\": \"item_abc\",\n          \"sku\": \"PROD-001\",\n          \"quantity\": 1,\n          \"return_reason\": \"wrong_size\",\n          \"restocked_quantity\": 1\n        }\n      ],\n      \"shipments\": [],\n      \"trackstar_created_date\": \"2024-06-10T00:00:00.000Z\",\n      \"trackstar_updated_date\": \"2024-06-12T00:00:00.000Z\",\n      \"created_at\": \"2024-06-10T00:00:00.000Z\",\n      \"updated_at\": \"2024-06-12T00:00:00.000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 55\n}"}]},{"name":"Sync Returns","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Pull returns from the Trackstar API and sync to the local database. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/sync","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns","sync"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Returns synced successfully\",\n  \"synced_count\": 55\n}"}]},{"name":"Pending Returns","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/pending","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns","pending"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get returns that are in a pending state (not yet received/processed). Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/pending","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns","pending"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 902,\n      \"trackstar_id\": \"ret_002\",\n      \"status\": \"pending\",\n      \"order_id\": \"ts-ord-005\",\n      \"line_items\": [\n        {\n          \"sku\": \"PROD-002\",\n          \"quantity\": 2\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Show Return","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/{return}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns",":return"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"return","value":"901","description":"Return database ID"}]},"description":"Get a single return by database ID. Includes json_object in the response. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/{return}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns",":return"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"return","value":"901","description":"Return database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 901,\n    \"integration_instance_id\": 10,\n    \"trackstar_id\": \"ret_001\",\n    \"order_id\": \"ts-ord-001\",\n    \"status\": \"received\",\n    \"raw_status\": \"RECEIVED\",\n    \"tracking_number\": \"1Z999AA10123456999\",\n    \"carrier\": \"UPS\",\n    \"line_items\": [\n      {\n        \"sku\": \"PROD-001\",\n        \"quantity\": 1,\n        \"return_reason\": \"wrong_size\",\n        \"restocked_quantity\": 1\n      }\n    ],\n    \"json_object\": {\n      \"id\": \"ret_001\",\n      \"status\": \"RECEIVED\"\n    },\n    \"created_at\": \"2024-06-10T00:00:00.000Z\",\n    \"updated_at\": \"2024-06-12T00:00:00.000Z\"\n  }\n}"}]},{"name":"Get Return Raw Data","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/{return}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns",":return","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"return","value":"1","description":"Return database ID"}]},"description":"Fetch a return LIVE from the Trackstar API (untransformed) for the raw-data viewer. Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/returns/{return}/raw","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","returns",":return","raw"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"return","value":"1","description":"Return database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product\": {\n      \"id\": \"ret_2b7c1e\",\n      \"order_id\": \"ord_2b7c1e\",\n      \"reference_id\": \"#915404R\",\n      \"status\": \"received\",\n      \"warehouse_id\": \"3\",\n      \"line_items\": [\n        {\n          \"sku\": \"TEST-UK-001\",\n          \"product_id\": \"prod_18\",\n          \"quantity\": 1,\n          \"condition\": \"sellable\"\n        }\n      ],\n      \"created_date\": \"2026-05-20T07:38:00Z\",\n      \"updated_date\": \"2026-06-02T02:10:00Z\"\n    }\n  },\n  \"fetched_at\": \"2026-07-08T12:00:00.000000Z\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events?limit=50","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events"],"query":[{"key":"limit","value":"50","description":"Number of recent events to return (default: 50)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"List recent webhook events received from Trackstar for an integration instance. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nQuery parameters:\n- limit (optional, integer): Number of most recent events to return (default: 50)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events?limit=50","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events"],"query":[{"key":"limit","value":"50","description":"Number of recent events to return (default: 50)","disabled":true}],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"integration_instance_id\": 10,\n      \"event_type\": \"order.shipped\",\n      \"trackstar_event_id\": \"evt_abc123\",\n      \"processed\": true,\n      \"processed_at\": \"2024-06-20T09:01:00.000Z\",\n      \"error_message\": null,\n      \"payload\": {\n        \"order_id\": \"ts-ord-001\",\n        \"status\": \"shipped\"\n      },\n      \"created_at\": \"2024-06-20T09:00:00.000Z\",\n      \"updated_at\": \"2024-06-20T09:01:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Unprocessed Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events/unprocessed","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events","unprocessed"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]},"description":"Get all webhook events that have not yet been processed. Useful for debugging stuck or failed webhook handlers. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events/unprocessed","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events","unprocessed"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1002,\n      \"event_type\": \"inventory.updated\",\n      \"trackstar_event_id\": \"evt_def456\",\n      \"processed\": false,\n      \"processed_at\": null,\n      \"error_message\": \"SKU not found\",\n      \"payload\": {\n        \"sku\": \"UNKNOWN-SKU\",\n        \"quantity\": 10\n      },\n      \"created_at\": \"2024-06-20T08:00:00.000Z\",\n      \"updated_at\": \"2024-06-20T08:00:00.000Z\"\n    }\n  ]\n}"}]},{"name":"Show Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"webhook_event","value":"1001","description":"Webhook event database ID"}]},"description":"Get a single webhook event by database ID. Includes full payload. Requires Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/trackstar/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","trackstar","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"10","description":"Integration instance ID"},{"key":"webhook_event","value":"1001","description":"Webhook event database ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1001,\n    \"integration_instance_id\": 10,\n    \"event_type\": \"order.shipped\",\n    \"trackstar_event_id\": \"evt_abc123\",\n    \"payload\": {\n      \"order_id\": \"ts-ord-001\",\n      \"status\": \"shipped\",\n      \"tracking\": \"1Z999AA10123456784\"\n    },\n    \"processed_at\": \"2024-06-20T09:01:00.000Z\",\n    \"created_at\": \"2024-06-20T09:00:00.000Z\",\n    \"updated_at\": \"2024-06-20T09:01:00.000Z\"\n  }\n}"}]}]},{"name":"Starshipit","item":[{"name":"Get Orders Chart (Date Range)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders-chart?start_date=2026-04-29&end_date=2026-05-29","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders-chart"],"query":[{"key":"start_date","value":"2026-04-29","description":"Start date of the range (YYYY-MM-DD). Required.","disabled":true},{"key":"end_date","value":"2026-05-29","description":"End date of the range (YYYY-MM-DD). Must be on or after start_date. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a daily order-count time series for a StarShipIt integration instance over the given date range.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains one bucket per day in [start_date, end_date], filling zero-counts for days with no orders. Used by the dashboard chart to render the orders trend.\n\nQuery parameters:\n- start_date (required, YYYY-MM-DD): start of the range\n- end_date (required, YYYY-MM-DD): end of the range; must be >= start_date\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders-chart?start_date=2026-04-29&end_date=2026-05-29","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders-chart"],"query":[{"key":"start_date","value":"2026-04-29","description":"Start date of the range (YYYY-MM-DD). Required.","disabled":true},{"key":"end_date","value":"2026-05-29","description":"End date of the range (YYYY-MM-DD). Must be on or after start_date. Required.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"date\": \"2026-04-29\",\n      \"orders_count\": 0\n    },\n    {\n      \"date\": \"2026-04-30\",\n      \"orders_count\": 3\n    },\n    {\n      \"date\": \"2026-05-01\",\n      \"orders_count\": 7\n    },\n    {\n      \"date\": \"2026-05-02\",\n      \"orders_count\": 12\n    }\n  ]\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns the configuration for a single StarShipIt integration instance, including connection credentials and behavioural settings.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`connection_settings` keys:\n- `apiKey` — StarShipIt API key.\n- `subscriptionKey` — StarShipIt subscription (Ocp-Apim) key sent with every API call.\n- `webhookSecret` — optional; used to verify signatures on inbound webhook notifications.\n\n`integration_settings` keys (all optional):\n- `fulfillment.enabledWarehousesIds` / `fulfillment.automatedWarehousesIds` — warehouse routing selection (see the warehouse routing endpoint).\n- `sync_days_back` — default sync window in days when no start date is set (default 30).\n- `order_start_date` — earliest order date to sync.\n- `last_sync.orders` / `last_sync.tracking_info` — timestamps maintained automatically by the background sync processes.\n\nReturns 404 when the instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"StarShipIt AU\",\n    \"integration_id\": 24,\n    \"connection_settings\": {\n      \"apiKey\": \"f2a1c9e4-0000-4b1a-9e77-example\",\n      \"subscriptionKey\": \"0123456789abcdef0123456789abcdef\",\n      \"webhookSecret\": \"whsec_example_secret\"\n    },\n    \"integration_settings\": {\n      \"fulfillment\": {\n        \"enabledWarehousesIds\": [\n          1,\n          3\n        ],\n        \"automatedWarehousesIds\": [\n          3\n        ]\n      },\n      \"sync_days_back\": 30,\n      \"order_start_date\": \"2026-01-01\",\n      \"last_sync\": {\n        \"orders\": \"2026-07-06T02:15:00.000000Z\",\n        \"tracking_info\": \"2026-07-06T02:20:00.000000Z\"\n      }\n    },\n    \"is_automatic_sync_enabled\": true,\n    \"created_at\": \"2026-03-10T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T02:20:01+00:00\"\n  }\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Updates a StarShipIt integration instance. All body fields are optional — send only what should change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nMerge semantics: top-level keys inside `connection_settings` and `integration_settings` are merged into the stored objects. Keys you send overwrite existing values; keys you omit are preserved. For example, sending only `integration_settings.sync_days_back` leaves the stored `fulfillment` routing untouched.\n\nBody fields:\n- `name` (string, optional) — must remain unique across all integration instances.\n- `connection_settings` (object, optional) — any of `apiKey`, `subscriptionKey`, `webhookSecret`.\n- `integration_settings` (object, optional) — any of `sync_days_back`, `order_start_date`, `fulfillment` (with `enabledWarehousesIds` / `automatedWarehousesIds`).\n- `is_automatic_sync_enabled` (boolean, optional).\n\nA PATCH request to the same URL behaves identically to PUT.\n\nReturns the full updated instance. Returns 422 when the new `name` is already taken; 404 when the instance does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"StarShipIt AU (Main)\",\n  \"connection_settings\": {\n    \"apiKey\": \"f2a1c9e4-1111-4b1a-9e77-rotated\"\n  },\n  \"integration_settings\": {\n    \"sync_days_back\": 60,\n    \"fulfillment\": {\n      \"enabledWarehousesIds\": [\n        1,\n        3\n      ],\n      \"automatedWarehousesIds\": [\n        3\n      ]\n    }\n  },\n  \"is_automatic_sync_enabled\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"StarShipIt AU (Main)\",\n    \"integration_id\": 24,\n    \"connection_settings\": {\n      \"apiKey\": \"f2a1c9e4-1111-4b1a-9e77-rotated\",\n      \"subscriptionKey\": \"0123456789abcdef0123456789abcdef\",\n      \"webhookSecret\": \"whsec_example_secret\"\n    },\n    \"integration_settings\": {\n      \"fulfillment\": {\n        \"enabledWarehousesIds\": [\n          1,\n          3\n        ],\n        \"automatedWarehousesIds\": [\n          3\n        ]\n      },\n      \"sync_days_back\": 60,\n      \"order_start_date\": \"2026-01-01\",\n      \"last_sync\": {\n        \"orders\": \"2026-07-06T02:15:00.000000Z\",\n        \"tracking_info\": \"2026-07-06T02:20:00.000000Z\"\n      }\n    },\n    \"is_automatic_sync_enabled\": false,\n    \"created_at\": \"2026-03-10T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-06T11:41:12+00:00\"\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Deletes a StarShipIt integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe deletion is performed asynchronously: this endpoint queues a background job and returns immediately. The background job removes the instance's cached orders, webhook events, and API logs before deleting the instance record itself. Large instances may take a while to fully disappear.\n\nReturns 404 when the instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Integration instance deleted successfully\"\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances"]},"description":"Creates a new StarShipIt integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields:\n- `name` (string, required) — must be unique across all integration instances.\n- `connection_settings` (object, required) — credentials: `apiKey` (StarShipIt API key), `subscriptionKey` (subscription key), and optionally `webhookSecret` for verifying inbound webhook signatures.\n- `integration_settings` (object, optional) — behavioural settings such as `sync_days_back`, `order_start_date`, and `fulfillment` warehouse routing (`enabledWarehousesIds`, `automatedWarehousesIds`).\n- `is_automatic_sync_enabled` (boolean, optional) — whether scheduled syncs run automatically.\n\nCreating an instance immediately queues a background job that backfills orders from StarShipIt. Shipping methods are derived from carriers observed on synced orders, so the same backfill also populates shipping method data. Progress is reported through the tracked background job facilities.\n\nReturns 422 when validation fails (missing/duplicate `name`, missing `connection_settings`).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"StarShipIt AU\",\n  \"connection_settings\": {\n    \"apiKey\": \"f2a1c9e4-0000-4b1a-9e77-example\",\n    \"subscriptionKey\": \"0123456789abcdef0123456789abcdef\",\n    \"webhookSecret\": \"whsec_example_secret\"\n  },\n  \"integration_settings\": {\n    \"sync_days_back\": 30,\n    \"order_start_date\": \"2026-01-01\"\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"StarShipIt AU\"\n  }\n}"}]},{"name":"Test Connection","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Verifies the stored StarShipIt credentials by making a live call to the StarShipIt API (it fetches a single unshipped order). No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 200 with a success message when StarShipIt accepts the credentials, or 400 when the call fails (bad API key / subscription key, network failure).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/test-connection","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","test-connection"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Connection successful\"\n}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns aggregated operational metrics for the instance:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `totalOrders` — total orders in the local cache.\n- `ordersByStatus` — count per order status. Statuses: `Unshipped`, `Printed`, `Shipped`, `Delivered`, `Saved`, `Cancelled`, `Archived`, `Error`, `Unknown` (every status is present, zero-filled).\n- `ordersByCarrier` — top carriers by order count (up to 20).\n- `unprocessedWebhookEvents` / `failedWebhookEvents` — inbound webhook events not yet processed, and events that recorded an error.\n- `unlinkedOrders` — cached orders not linked to a sales order fulfillment.\n- `ordersLastSyncedAt` / `trackingInfoLastUpdatedAt` — ISO-8601 timestamps of the most recent order sync and tracking refresh (null when never run).\n- `ordersChart` — orders per day for the last 30 days, zero-filled so the series is continuous.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalOrders\": 1482,\n    \"ordersByStatus\": [\n      {\n        \"status\": \"Unshipped\",\n        \"status_label\": \"Unshipped\",\n        \"count\": 34\n      },\n      {\n        \"status\": \"Printed\",\n        \"status_label\": \"Printed\",\n        \"count\": 6\n      },\n      {\n        \"status\": \"Shipped\",\n        \"status_label\": \"Shipped\",\n        \"count\": 1287\n      },\n      {\n        \"status\": \"Delivered\",\n        \"status_label\": \"Delivered\",\n        \"count\": 112\n      },\n      {\n        \"status\": \"Saved\",\n        \"status_label\": \"Saved\",\n        \"count\": 0\n      },\n      {\n        \"status\": \"Cancelled\",\n        \"status_label\": \"Cancelled\",\n        \"count\": 28\n      },\n      {\n        \"status\": \"Archived\",\n        \"status_label\": \"Archived\",\n        \"count\": 12\n      },\n      {\n        \"status\": \"Error\",\n        \"status_label\": \"Error\",\n        \"count\": 3\n      },\n      {\n        \"status\": \"Unknown\",\n        \"status_label\": \"Unknown\",\n        \"count\": 0\n      }\n    ],\n    \"ordersByCarrier\": [\n      {\n        \"carrier\": \"Australia Post\",\n        \"count\": 903\n      },\n      {\n        \"carrier\": \"Aramex\",\n        \"count\": 421\n      },\n      {\n        \"carrier\": \"DHL Express\",\n        \"count\": 118\n      }\n    ],\n    \"unprocessedWebhookEvents\": 2,\n    \"failedWebhookEvents\": 1,\n    \"ordersLastSyncedAt\": \"2026-07-06T02:15:00+00:00\",\n    \"trackingInfoLastUpdatedAt\": \"2026-07-06T02:20:00+00:00\",\n    \"unlinkedOrders\": 17,\n    \"ordersChart\": [\n      {\n        \"date\": \"2026-06-07\",\n        \"orders_count\": 42\n      },\n      {\n        \"date\": \"2026-06-08\",\n        \"orders_count\": 0\n      },\n      {\n        \"date\": \"2026-06-09\",\n        \"orders_count\": 51\n      }\n    ]\n  }\n}"}]},{"name":"Get Warehouse Routing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/warehouse-routing","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","warehouse-routing"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns the data used to configure which warehouses route fulfillments through this StarShipIt instance:\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n- `warehouses` — every warehouse eligible for routing (supplier-owned warehouses are excluded), with `id`, `name`, and `supplier_name`.\n- `fulfillment.enabledWarehousesIds` — warehouses currently enabled for this instance (fulfillments from these warehouses may be submitted to StarShipIt).\n- `fulfillment.automatedWarehousesIds` — warehouses whose fulfillments are submitted automatically without user action.\n- `automated_warehouses` — a map keyed by warehouse ID of warehouses already automated by a *different* shipping provider instance (`integration_instance_id`, `integration_name`). A warehouse can only be automated by one shipping provider at a time, so these warehouses cannot be automated here until released by the other provider.\n\nTo change the selection, write `integration_settings.fulfillment` via the update endpoint.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/warehouse-routing","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","warehouse-routing"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"warehouses\": [\n      {\n        \"id\": 1,\n        \"name\": \"Melbourne DC\",\n        \"supplier_name\": null\n      },\n      {\n        \"id\": 3,\n        \"name\": \"Sydney 3PL\",\n        \"supplier_name\": null\n      }\n    ],\n    \"fulfillment\": {\n      \"enabledWarehousesIds\": [\n        1,\n        3\n      ],\n      \"automatedWarehousesIds\": [\n        3\n      ]\n    },\n    \"automated_warehouses\": {\n      \"5\": {\n        \"integration_instance_id\": 7,\n        \"integration_name\": \"ShipStation\"\n      }\n    }\n  }\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]},"description":"Returns the full details for a single Starshipit order including resolved destination, sender, flags, writeback status, tracking URL, and the linked SKU.io sales order fulfillment (if any).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nWhen `include_json=1` is supplied, the raw StarShipIt JSON payload is included as `json_object` (used by the order detail page's \"Raw\" panel).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"12345\",\n    \"order_number\": \"SO-1234\",\n    \"reference\": \"ACME-PO-9999\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier\": \"starshipit_australia_post\",\n    \"carrier_name\": \"Australia Post\",\n    \"carrier_service_code\": \"AUS_PARCEL_REGULAR\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n    \"order_date\": \"2026-05-25\",\n    \"shipped_at\": \"2026-05-26T03:14:00+00:00\",\n    \"manifest_number\": \"MAN-2026-05-26-001\",\n    \"total_shipping_price\": 12.45,\n    \"currency\": \"AUD\",\n    \"declared_value\": 199.99,\n    \"insurance_value\": 200,\n    \"type\": \"international\",\n    \"export_type\": \"permanent\",\n    \"shipping_description\": \"Books and apparel\",\n    \"flags\": {\n      \"signature_required\": true,\n      \"dangerous_goods\": false,\n      \"add_insurance\": true,\n      \"dtp\": false,\n      \"plt\": true,\n      \"create_return\": false,\n      \"address_validation\": true\n    },\n    \"writeback\": {\n      \"status\": \"Success\",\n      \"details\": \"Tracking pushed to Shopify\",\n      \"success\": true\n    },\n    \"destination\": {\n      \"name\": \"Jane Doe\",\n      \"email\": \"jane@example.com\",\n      \"phone\": \"+61 400 000 000\",\n      \"company\": null,\n      \"street\": \"1 Smith Street\",\n      \"suburb\": \"Richmond\",\n      \"city\": \"Melbourne\",\n      \"state\": \"VIC\",\n      \"post_code\": \"3121\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\",\n      \"delivery_instructions\": \"Leave at front door\"\n    },\n    \"sender\": {\n      \"name\": \"Acme Warehouse\",\n      \"company\": \"Acme Pty Ltd\",\n      \"email\": \"ops@acme.example\",\n      \"phone\": \"+61 3 9000 0000\",\n      \"street\": \"10 Industrial Way\",\n      \"suburb\": \"Port Melbourne\",\n      \"city\": \"Melbourne\",\n      \"state\": \"VIC\",\n      \"post_code\": \"3207\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\"\n    },\n    \"sku_fulfillment\": {\n      \"id\": 4321,\n      \"link_reference\": 4321,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4321,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4321\"\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-26T03:15:00+00:00\",\n    \"created_at\": \"2026-05-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-05-26T03:15:01+00:00\"\n  }\n}"}]},{"name":"Get Order Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/webhook-events","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]},"description":"Returns the most recent webhook events (up to 25) related to this Starshipit order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEvents are matched by the order's `order_number` OR `tracking_number` against the `starshipit_webhook_events` table. Each event includes the event type, tracking status, processed flag, and any error message.\n\nUsed by the Order Detail page to render a per-order webhook audit trail (operational debugging — \"did we receive the delivered event?\").\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/webhook-events","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9011,\n      \"integration_instance_id\": 2,\n      \"event_type\": \"tracking_update\",\n      \"tracking_status\": \"delivered\",\n      \"tracking_status_label\": \"Delivered\",\n      \"tracking_status_color\": \"success\",\n      \"order_number\": \"SO-1234\",\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"signature_valid\": true,\n      \"payload\": {\n        \"status\": \"delivered\",\n        \"tracking_number\": \"TRK-AU-1234567890\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-05-27T08:01:11+00:00\",\n      \"error_message\": null,\n      \"created_at\": \"2026-05-27T08:01:09+00:00\",\n      \"updated_at\": \"2026-05-27T08:01:11+00:00\"\n    }\n  ]\n}"}]},{"name":"Download Label (PDF base64)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/label","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","label"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]},"description":"Proxies StarShipIt's GET /api/orders/labels endpoint and returns the base64-encoded PDF label for the order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains `filename`, `mime_type`, and `base64`. The frontend decodes the base64 string client-side and triggers a download.\n\nReturns 400 if the local order has no `starshipit_order_id` (i.e. was never submitted to Starshipit). Returns 502 if the StarShipIt API call fails or returns no label.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/label","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","label"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"filename\": \"starshipit-label-SO-1234.pdf\",\n    \"mime_type\": \"application/pdf\",\n    \"base64\": \"JVBERi0xLjQKJ...truncated\"\n  }\n}"}]},{"name":"Download Packing Slip (PDF base64)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/packing-slip","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","packing-slip"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]},"description":"Proxies StarShipIt's GET /api/orders/packingslip endpoint and returns the base64-encoded PDF packing slip for the order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe response contains `filename`, `mime_type`, and `base64`. The frontend decodes the base64 string client-side and triggers a download.\n\nReturns 400 if the local order has no `starshipit_order_id`. Returns 502 if the StarShipIt API call fails or returns no packing slip.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/packing-slip","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","packing-slip"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"filename\": \"starshipit-packing-slip-SO-1234.pdf\",\n    \"mime_type\": \"application/pdf\",\n    \"base64\": \"JVBERi0xLjQKJ...truncated\"\n  }\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders?filter[status]=Shipped","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders"],"query":[{"key":"filter[status]","value":"Shipped","description":"Exact match on status (Unshipped, Shipped, Cancelled, Archived, Error)","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List Starshipit orders for the integration instance (paginated). Each order includes a `tracking_numbers` array of per-package tracking (tracking_number, tracking_url, name, carrier_service_name, delivery_status) — multi-package orders carry more than one entry, while the scalar `tracking_number` holds only the single value Starshipit returns at the order root. Authenticate with a Personal Access Token (PAT) Bearer token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders?filter[status]=Shipped","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders"],"query":[{"key":"filter[status]","value":"Shipped","description":"Exact match on status (Unshipped, Shipped, Cancelled, Archived, Error)","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 172468,\n      \"integration_instance_id\": 6,\n      \"starshipit_order_id\": \"711344099\",\n      \"order_number\": \"BG125116.1\",\n      \"reference\": \"SKUio_production676781\",\n      \"status\": \"Shipped\",\n      \"status_label\": \"Shipped\",\n      \"status_color\": \"success\",\n      \"carrier\": \"AusPost\",\n      \"carrier_name\": \"Australia Post\",\n      \"carrier_service_code\": \"7D85\",\n      \"tracking_number\": \"4H2388922102000935105\",\n      \"tracking_url\": \"https://track.starshipit.com/track/4H2388922102000935105\",\n      \"tracking_numbers\": [\n        {\n          \"tracking_number\": \"4H2388922101000931506\",\n          \"tracking_url\": \"https://track.starshipit.com/track/4H2388922101000931506\",\n          \"name\": \"Box A\",\n          \"carrier_service_name\": \"PARCEL POST + SIGNATURE\",\n          \"delivery_status\": \"Delivered\"\n        },\n        {\n          \"tracking_number\": \"4H2388922102000935105\",\n          \"tracking_url\": \"https://track.starshipit.com/track/4H2388922102000935105\",\n          \"name\": \"Box B\",\n          \"carrier_service_name\": \"PARCEL POST + SIGNATURE\",\n          \"delivery_status\": \"Delivered\"\n        }\n      ],\n      \"order_date\": \"2023-03-10\",\n      \"shipped_at\": \"2023-03-10T09:02:00+00:00\",\n      \"manifest_number\": \"117908497\",\n      \"total_shipping_price\": 13.24,\n      \"currency\": \"AUD\",\n      \"type\": \"Outgoing\",\n      \"customer_name\": \"Kim Moran\",\n      \"sku_fulfillment\": {\n        \"id\": 256917,\n        \"link_reference\": 256917,\n        \"link_type_label\": \"Sales Order Fulfillment\",\n        \"link_id\": 256917,\n        \"link_route\": \"/orders/sales-orders/fulfillments/256917\"\n      },\n      \"has_detailed_data\": true,\n      \"details_last_updated\": \"2026-06-08T12:42:00+00:00\",\n      \"created_at\": \"2026-06-09T04:47:00+00:00\",\n      \"updated_at\": \"2026-06-09T05:42:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Sync Orders (Queue Job)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background (tracked) job to sync orders from StarShipIt into SKU.io. Progress is reported through the tracked job log endpoints and can also be polled via **Get Order Sync Progress**.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters (all optional):**\n- `mode` — one of `since_latest` | `date_range` | `all`.\n  - `since_latest`: sync orders dated on/after the most recently synced order. Send the latest synced order date as `date_from`.\n  - `date_range`: sync orders between `date_from` and `date_to` (inclusive). StarShipIt's API only bounds the start date, so the end date (`date_to`) is applied by post-filtering fetched pages.\n  - `all`: pull full order history; `date_from`/`date_to` are ignored.\n- `date_from` — start date (`YYYY-MM-DD`). Lower bound for `since_latest` and `date_range`.\n- `date_to` — end date (`YYYY-MM-DD`). Upper bound for `date_range` only.\n- `since_date` — **legacy** alias for `date_from`, kept for backward compatibility with the previous one-click refresh. Used only when `date_from` is absent.\n\nWhen `mode` is omitted the job falls back to the instance's configured order start date (or its sync-days-back window).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"mode\": \"since_latest\",\n  \"date_from\": \"2026-05-01\",\n  \"date_to\": \"2026-05-31\",\n  \"since_date\": \"2026-05-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4321\n  },\n  \"message\": \"Order sync queued\",\n  \"status\": \"Success\"\n}"}]},{"name":"Get Order Sync Progress","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4321","description":"The tracked job log ID."}]},"description":"Poll the progress of a queued order sync job by its tracked job log ID (returned from **Sync Orders**). On completion, `results` carries the sync summary — `orders_fetched` (orders retrieved from StarShipIt) and `orders_saved` (orders upserted into SKU.io).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 404 if no job exists for the given ID.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync-progress/{trackedJobLogId}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync-progress",":trackedJobLogId"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"trackedJobLogId","value":"4321","description":"The tracked job log ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4321,\n    \"status\": \"completed\",\n    \"job_name\": \"Refresh StarShipIt Orders: 6 (Curvy AU)\",\n    \"total_items\": 250,\n    \"processed_items\": 250,\n    \"progress_percentage\": 100,\n    \"messages\": [\n      \"Fetched 250 orders\",\n      \"Saved 250 orders\"\n    ],\n    \"results\": {\n      \"orders_fetched\": 250,\n      \"orders_saved\": 250\n    },\n    \"attempted_at\": \"2026-05-26T03:14:00.000000Z\",\n    \"completed_at\": \"2026-05-26T03:15:02.000000Z\"\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Get Order Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Header data for the orders refresh modal: the most recently dated order (`latest_order_number` + `latest_order_date`, keyed on `order_date`), the total order count, and the **effective** order start date the \"Fetch from Start Date\" mode will use.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n`order_start_date` (`YYYY-MM-DD`) is always returned and resolves through a fallback chain, with `order_start_date_source` naming where it came from:\n- `StarShipIt Order Start Date` — the instance's configured Order Start Date (StarShipIt settings)\n- `Inventory Start Date` — the general inventory start date, when no StarShipIt start date is set\n- `Default sync window (last N days)` — a `now − sync_days_back` window, when neither start date is configured\n\nThe frontend uses this to seed the \"since latest\" and \"from start date\" sync modes (always showing the resolved date and its source) and to show how many orders are currently stored.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/sync-info","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","sync-info"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"latest_order_number\": \"SO-1234\",\n    \"latest_order_date\": \"2026-05-25T00:00:00+00:00\",\n    \"total_orders\": 250,\n    \"order_start_date\": \"2026-01-01\",\n    \"order_start_date_source\": \"StarShipIt Order Start Date\"\n  },\n  \"status\": \"Success\"\n}"}]},{"name":"Search Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Search StarShipIt **live** for orders matching a phrase, for the refresh modal's \"Search Specific Order\" tab. StarShipIt's `/orders/search` matches across order number, reference, recipient, and the internal order id, so a single phrase covers every identifier a user might paste in. Each result is flagged with whether it already exists in this instance's local cache so the UI can offer Download (new) vs Update (existing).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters:**\n- `query` — **required** string (max 255). The order number, reference, recipient, or StarShipIt order id to search for.\n\nErrors:\n- 422 if `query` is missing\n- 502 if the upstream StarShipIt call fails\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"query\": \"SO-1234\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/search","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","search"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"starshipit_order_id\": \"708495527\",\n      \"order_number\": \"SO-1234\",\n      \"status\": \"Shipped\",\n      \"order_date\": \"2026-05-25T00:00:00Z\",\n      \"email\": \"customer@example.com\",\n      \"exists_in_database\": true,\n      \"database_id\": 650\n    },\n    {\n      \"starshipit_order_id\": \"708495530\",\n      \"order_number\": \"SO-1240\",\n      \"status\": \"Unshipped\",\n      \"order_date\": \"2026-05-27T00:00:00Z\",\n      \"email\": \"another@example.com\",\n      \"exists_in_database\": false,\n      \"database_id\": null\n    }\n  ],\n  \"status\": \"Success\"\n}"}]},{"name":"Refresh Single Order (Download)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Download (or update) a **single** order live from StarShipIt by its StarShipIt order id and persist it to the local cache. Backs the search tab's per-result Download / Update buttons.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body parameters:**\n- `uniqueId` — **required** string. The StarShipIt order id (the `starshipit_order_id` returned by **Search Orders**).\n\nFetches the order via StarShipIt's `GET /orders?order_id=`, upserts it (with detailed fields), and returns the refreshed order resource (with `json_object` included).\n\nErrors:\n- 422 if `uniqueId` is missing\n- 502 if the upstream StarShipIt call fails or the order cannot be persisted\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"uniqueId\": \"708495527\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/refresh-order","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","refresh-order"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Order refreshed from StarShipIt\",\n  \"data\": {\n    \"id\": 650,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"708495527\",\n    \"order_number\": \"SO-1234\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier_name\": \"Australia Post\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"shipped_at\": \"2026-05-26T03:14:00+00:00\",\n    \"order_date\": \"2026-05-25T00:00:00+00:00\",\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-26T03:18:00+00:00\",\n    \"json_object\": {\n      \"order_id\": \"708495527\",\n      \"order_number\": \"SO-1234\"\n    }\n  }\n}"}]},{"name":"Refresh Order Tracking","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/tracking","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","tracking"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"650","description":"Local StarShipIt order ID (numeric primary key on `starshipit_orders`)"}]},"description":"Refreshes live tracking events for a single order by calling Starshipit's GET /track endpoint with the order's `order_number`. The carrier-reported events are persisted to `starshipit_orders.json_object.events` so the order detail page can render an up-to-date tracking timeline.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAlso updates: `tracking_number`, `carrier_name` (when previously empty), local `status` (mapped from the tracking status enum), and `details_last_updated`.\n\nReturns the refreshed order resource (with `json_object` included) and a success message.\n\nErrors:\n- 400 if the order has no `order_number` (Starshipit requires it to look up tracking)\n- 404 if the order does not belong to the given integration instance\n- 502 if the upstream Starshipit /track call fails (auth, network, etc.)\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/tracking","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","tracking"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"650","description":"Local StarShipIt order ID (numeric primary key on `starshipit_orders`)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Tracking refreshed from StarShipIt\",\n  \"data\": {\n    \"id\": 650,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"708495527\",\n    \"order_number\": \"SO-1234\",\n    \"status\": \"shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier_name\": \"Australia Post\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n    \"shipped_at\": \"2026-05-26T03:14:00+00:00\",\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-05-26T03:18:00+00:00\",\n    \"json_object\": {\n      \"order_id\": \"708495527\",\n      \"order_number\": \"SO-1234\",\n      \"tracking_status\": \"InTransit\",\n      \"events\": [\n        {\n          \"status\": \"Manifested\",\n          \"timestamp\": \"2026-05-25T10:00:00Z\",\n          \"location\": \"Sydney DC\",\n          \"description\": \"Shipment manifested\"\n        },\n        {\n          \"status\": \"InTransit\",\n          \"timestamp\": \"2026-05-26T08:00:00Z\",\n          \"location\": \"Melbourne Hub\",\n          \"description\": \"In transit to delivery hub\"\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Get Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]},"description":"Paginated Spatie activity-log entries for a single Starshipit order (by local row id) — the order detail page's Activity Log tab. Each entry: id, description, event (created/updated/deleted), subject_type, subject_id, properties (changed attributes), causer_name, created_at. Ordered newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPagination: page (default 1), per_page (default 15).\n\nAuthentication: Requires Bearer token.\n\nFilters: filter[event] (exact event), filter[source] (matches properties->source), filter[batch_uuid] (exact batch uuid), filter[search] (LIKE over causer name / properties / event)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/activity-log","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","activity-log"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"Internal StarshipitOrder ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 90412,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"StarshipitOrder\",\n      \"subject_id\": 656,\n      \"properties\": {\n        \"attributes\": {\n          \"tracking_number\": \"1Z999AA10123456784\"\n        },\n        \"old\": {\n          \"tracking_number\": null\n        }\n      },\n      \"causer_name\": \"Sync Job\",\n      \"created_at\": \"2026-06-11T14:33:00.000000Z\"\n    },\n    {\n      \"id\": 90380,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"StarshipitOrder\",\n      \"subject_id\": 656,\n      \"properties\": {\n        \"attributes\": {\n          \"order_number\": \"SO-100245\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-10T09:15:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/starshipit/...?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Order Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]},"description":"Returns the locally cached raw StarShipIt payload for a single order.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResponse fields:\n- `json_object` — the raw order payload as last received from StarShipIt (items, packages, destination, tracking events, writeback status, etc.).\n- `has_detailed_data` — whether a full per-order detail fetch has ever been performed. List syncs store a summary payload; the detail fetch enriches it.\n- `details_last_updated` — when the detail payload was last refreshed from StarShipIt (null when never).\n\nThis endpoint reads only the local cache and never calls StarShipIt. To refresh the payload live from StarShipIt, use the companion `POST .../orders/:order/sync-detail` endpoint.\n\nReturns 404 when the order does not belong to this instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/detail","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"json_object\": {\n      \"order_id\": 123456789,\n      \"order_number\": \"SO-1234\",\n      \"reference\": \"ACME-PO-9999\",\n      \"status\": \"Shipped\",\n      \"carrier\": \"AusPost\",\n      \"carrier_name\": \"Australia Post\",\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"currency\": \"AUD\",\n      \"destination\": {\n        \"name\": \"Jane Doe\",\n        \"street\": \"1 Smith Street\",\n        \"city\": \"Melbourne\",\n        \"state\": \"VIC\",\n        \"post_code\": \"3121\",\n        \"country\": \"Australia\"\n      },\n      \"items\": [\n        {\n          \"sku\": \"TSHIRT-BLK-M\",\n          \"description\": \"T-Shirt Black M\",\n          \"quantity\": 2,\n          \"weight\": 0.2,\n          \"value\": 29.95\n        }\n      ],\n      \"packages\": [\n        {\n          \"name\": \"Box A\",\n          \"tracking_number\": \"TRK-AU-1234567890\",\n          \"carrier_service_name\": \"Parcel Post\",\n          \"delivery_status\": \"Delivered\"\n        }\n      ]\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-05T22:10:00+00:00\"\n  }\n}"}]},{"name":"Sync Order Detail","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]},"description":"Fetches the latest data for a single order live from the StarShipIt API and persists it to the local cache (updating `json_object`, setting `has_detailed_data` and `details_last_updated`). Returns the refreshed order, including the raw payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis is the live-refresh companion to `GET .../orders/:order/detail`, which reads the cache without calling StarShipIt.\n\nIf the order has no StarShipIt order ID yet (for example a deferred submission placeholder), the order is returned unchanged. Returns 404 when the order does not belong to this instance, and 502 when the StarShipIt API call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/sync-detail","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","sync-detail"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"external_url\": \"https://app2.starshipit.com/orders/new/123456789\",\n    \"reference\": \"ACME-PO-9999\",\n    \"status\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier\": \"AusPost\",\n    \"carrier_name\": \"Australia Post\",\n    \"carrier_service_code\": \"AUS_PARCEL_REGULAR\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n    \"tracking_numbers\": [\n      {\n        \"tracking_number\": \"TRK-AU-1234567890\",\n        \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n        \"name\": \"Box A\",\n        \"carrier_service_name\": \"Parcel Post\",\n        \"delivery_status\": \"Delivered\"\n      }\n    ],\n    \"order_date\": \"2026-06-25\",\n    \"shipped_at\": \"2026-06-26T03:14:00+00:00\",\n    \"manifest_number\": \"MAN-2026-06-26-001\",\n    \"total_shipping_price\": 12.45,\n    \"currency\": \"AUD\",\n    \"declared_value\": 199.99,\n    \"insurance_value\": 200,\n    \"type\": \"international\",\n    \"export_type\": \"permanent\",\n    \"shipping_description\": \"Books and apparel\",\n    \"flags\": {\n      \"signature_required\": true,\n      \"dangerous_goods\": false,\n      \"add_insurance\": true,\n      \"dtp\": false,\n      \"plt\": false,\n      \"create_return\": false,\n      \"address_validation\": true\n    },\n    \"writeback\": {\n      \"status\": \"Success\",\n      \"details\": \"Tracking pushed to Shopify\",\n      \"success\": true\n    },\n    \"customer_name\": \"Jane Doe\",\n    \"destination\": {\n      \"name\": \"Jane Doe\",\n      \"email\": \"jane@example.com\",\n      \"phone\": \"+61 400 000 000\",\n      \"company\": null,\n      \"street\": \"1 Smith Street\",\n      \"suburb\": \"Richmond\",\n      \"city\": \"Melbourne\",\n      \"state\": \"VIC\",\n      \"post_code\": \"3121\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\",\n      \"delivery_instructions\": \"Leave at front door\"\n    },\n    \"sender\": {\n      \"name\": \"Acme Warehouse\",\n      \"company\": \"Acme Pty Ltd\",\n      \"email\": \"ops@acme.example\",\n      \"phone\": \"+61 3 9000 0000\",\n      \"street\": \"10 Industrial Way\",\n      \"suburb\": \"Port Melbourne\",\n      \"city\": \"Melbourne\",\n      \"state\": \"VIC\",\n      \"post_code\": \"3207\",\n      \"country\": \"Australia\",\n      \"country_code\": \"AU\"\n    },\n    \"sku_fulfillment\": {\n      \"id\": 4321,\n      \"link_reference\": \"F-4321\",\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4321,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4321\",\n      \"status\": \"shipped\",\n      \"sales_order_id\": 887,\n      \"sales_order_number\": \"SO-1234\",\n      \"fulfillment_order_id\": 5120\n    },\n    \"items\": [\n      {\n        \"sku\": \"TSHIRT-BLK-M\",\n        \"description\": \"T-Shirt Black M\",\n        \"quantity\": 2,\n        \"weight\": 0.2,\n        \"value\": 29.95,\n        \"product_id\": 1045\n      }\n    ],\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-06T11:42:00+00:00\",\n    \"created_at\": \"2026-06-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-07-06T11:42:00+00:00\",\n    \"json_object\": {\n      \"order_id\": 123456789,\n      \"order_number\": \"SO-1234\",\n      \"status\": \"Shipped\"\n    }\n  }\n}"}]},{"name":"Link Order To Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]},"description":"Manually links a cached StarShipIt order to a sales order fulfillment. Use this to repair orders the automatic matching could not link (they show as \"unlinked\" on the dashboard metrics).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `sku_fulfillment_id` (integer, required) — the sales order fulfillment ID to link.\n\nReturns the updated order, including the linked fulfillment summary under `sku_fulfillment`. Returns 400 when `sku_fulfillment_id` is missing, and 404 when the order cannot be found.\n\nTo remove the link again, use the unlink endpoint.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_fulfillment_id\": 4321\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/link-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","link-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"status\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier_name\": \"Australia Post\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"sku_fulfillment\": {\n      \"id\": 4321,\n      \"link_reference\": \"F-4321\",\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4321,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4321\",\n      \"status\": \"shipped\",\n      \"sales_order_id\": 887,\n      \"sales_order_number\": \"SO-1234\",\n      \"fulfillment_order_id\": null\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-05T22:10:00+00:00\",\n    \"created_at\": \"2026-06-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-07-06T11:45:00+00:00\"\n  }\n}"}]},{"name":"Unlink Order From Fulfillment","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]},"description":"Removes the manual link between a cached StarShipIt order and its sales order fulfillment. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the updated order with `sku_fulfillment` cleared (unless the order still resolves to a fulfillment through its fulfillment-order association, which this endpoint does not touch). Returns 404 when the order does not belong to this instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/{order}/unlink-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders",":order","unlink-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"656","description":"The order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"status\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier_name\": \"Australia Post\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"sku_fulfillment\": null,\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-05T22:10:00+00:00\",\n    \"created_at\": \"2026-06-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-07-06T11:47:00+00:00\"\n  }\n}"}]},{"name":"Submit Fulfillment","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/submit-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","submit-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Manually submits a sales order fulfillment to StarShipIt through the canonical fulfillment dispatch flow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody:\n- `sku_fulfillment_id` (integer, required) — the sales order fulfillment whose parent sales order should be dispatched.\n\nThe dispatch runs synchronously and covers the whole parent sales order: it performs duplicate-order detection and is idempotent — fulfillments already submitted to the carrier (or in a terminal state) are skipped rather than resubmitted.\n\nReturns 400 when `sku_fulfillment_id` is missing, 404 when the fulfillment or its sales order cannot be found, and 502 when the dispatch fails (for example a StarShipIt API error).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_fulfillment_id\": 4321\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/orders/submit-fulfillment","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","orders","submit-fulfillment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sales_order_id\": 887\n  },\n  \"message\": \"Order dispatched to StarShipIt\"\n}"}]},{"name":"Submit Open Orders (Power User)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/submit-orders","host":["{{baseUrl}}"],"path":["api","starshipit","submit-orders"]},"description":"**Warning: this GET request has side effects — it queues a bulk submission of orders to StarShipIt.** It is a legacy power-user endpoint kept for backward compatibility; treat it as an action, not a read.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nQueues a background job that submits every open, not-yet-submitted fulfillment routed to a StarShipIt-enabled warehouse to the carrier. The sweep is idempotent: fulfillments already submitted or in a terminal state are skipped.\n\nThis endpoint is not instance-scoped — it resolves the single active StarShipIt integration instance itself. When no StarShipIt instance is configured, it returns HTTP 200 with an error payload (code `StarshipitNotIntegrated`).\n\nRequires the power user role.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/submit-orders","host":["{{baseUrl}}"],"path":["api","starshipit","submit-orders"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to the queue, it will be processed shortly\"\n}"}]},{"name":"Get Order For Fulfillment (Power User)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/view-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","starshipit","view-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"4321","description":"The sales order fulfillment ID."}]},"description":"Returns the locally cached StarShipIt order linked to the given sales order fulfillment. Read-only — no calls to StarShipIt are made. This is a legacy power-user endpoint kept for backward compatibility; it is not instance-scoped and resolves the single active StarShipIt integration instance itself.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nReturns 404 when the fulfillment exists but has no linked StarShipIt order (or the fulfillment ID is unknown). When no StarShipIt instance is configured, it returns HTTP 200 with an error payload (code `StarshipitNotIntegrated`).\n\nRequires the power user role.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/view-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","starshipit","view-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"4321","description":"The sales order fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"external_url\": \"https://app2.starshipit.com/orders/new/123456789\",\n    \"reference\": \"ACME-PO-9999\",\n    \"status\": \"Shipped\",\n    \"status_label\": \"Shipped\",\n    \"status_color\": \"success\",\n    \"carrier\": \"AusPost\",\n    \"carrier_name\": \"Australia Post\",\n    \"carrier_service_code\": \"AUS_PARCEL_REGULAR\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n    \"order_date\": \"2026-06-25\",\n    \"shipped_at\": \"2026-06-26T03:14:00+00:00\",\n    \"manifest_number\": \"MAN-2026-06-26-001\",\n    \"total_shipping_price\": 12.45,\n    \"currency\": \"AUD\",\n    \"customer_name\": \"Jane Doe\",\n    \"sku_fulfillment\": {\n      \"id\": 4321,\n      \"link_reference\": \"F-4321\",\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4321,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4321\",\n      \"status\": \"shipped\",\n      \"sales_order_id\": 887,\n      \"sales_order_number\": \"SO-1234\",\n      \"fulfillment_order_id\": 5120\n    },\n    \"has_detailed_data\": true,\n    \"details_last_updated\": \"2026-07-05T22:10:00+00:00\",\n    \"created_at\": \"2026-06-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-07-06T02:20:00+00:00\"\n  }\n}"}]},{"name":"Update Order From Fulfillment (Power User)","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","starshipit","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"4321","description":"The sales order fulfillment ID."}]},"description":"Pushes the current state of a sales order fulfillment to StarShipIt. If the fulfillment already has a linked StarShipIt order, that order is updated live via the StarShipIt API (preserving existing line identifiers); otherwise a new StarShipIt order is created. The result is persisted to the local order cache and returned.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nThe path parameter is the sales order fulfillment ID. No request body.\n\nBefore submitting, the fulfillment is validated as a StarShipIt order payload (destination address, line items, etc.); when validation fails, a 400 is returned with per-field errors. A 502 is returned when the StarShipIt API call fails.\n\nThis is a legacy power-user endpoint kept for backward compatibility; it is not instance-scoped and resolves the single active StarShipIt integration instance itself. When no StarShipIt instance is configured, it returns HTTP 200 with an error payload (code `StarshipitNotIntegrated`).\n\nRequires the power user role.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/starshipit/update-order/{sales_order_fulfillment}","host":["{{baseUrl}}"],"path":["api","starshipit","update-order",":sales_order_fulfillment"],"variable":[{"key":"sales_order_fulfillment","value":"4321","description":"The sales order fulfillment ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 656,\n    \"integration_instance_id\": 2,\n    \"starshipit_order_id\": \"123456789\",\n    \"order_number\": \"SO-1234\",\n    \"external_url\": \"https://app2.starshipit.com/orders/new/123456789\",\n    \"status\": \"Unshipped\",\n    \"status_label\": \"Unshipped\",\n    \"status_color\": \"info\",\n    \"carrier\": \"AusPost\",\n    \"carrier_name\": \"Australia Post\",\n    \"carrier_service_code\": \"AUS_PARCEL_REGULAR\",\n    \"tracking_number\": null,\n    \"tracking_url\": null,\n    \"order_date\": \"2026-07-05\",\n    \"shipped_at\": null,\n    \"total_shipping_price\": 12.45,\n    \"customer_name\": \"Jane Doe\",\n    \"sku_fulfillment\": {\n      \"id\": 4321,\n      \"link_reference\": \"F-4321\",\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 4321,\n      \"link_route\": \"/orders/sales-orders/fulfillments/4321\",\n      \"status\": \"pending\",\n      \"sales_order_id\": 887,\n      \"sales_order_number\": \"SO-1234\",\n      \"fulfillment_order_id\": 5120\n    },\n    \"has_detailed_data\": false,\n    \"details_last_updated\": null,\n    \"created_at\": \"2026-07-05T14:02:00+00:00\",\n    \"updated_at\": \"2026-07-06T11:50:00+00:00\"\n  },\n  \"message\": \"The Starshipit Order 'SO-1234' updated successfully\"\n}"}]},{"name":"List Packages","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/packages","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","packages"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Paginated list of packages across all orders for this Starshipit integration instance. Each package is promoted out of its parent order's `json_object.packages[]` array into its own row so packages are searchable by their per-package `tracking_number` (multi-package orders carry distinct tracking numbers that the order-level tracking_number drops).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSupports Spatie QueryBuilder filtering, sorting, and pagination.\n\nFilters:\n- `filter[search]` — partial match across tracking_number, starshipit_package_id, carrier_service_name, and the parent order's order_number\n- `filter[delivery_status]` — exact match on delivery status (e.g. Pending, InTransit, Delivered)\n- `filter[order_id]` — exact match on the local parent order id (starshipit_orders.id)\n- Advanced per-column operators are available for: id, tracking_number, starshipit_package_id, name, carrier_service_name, carrier_service_code, delivery_status, packaging_type, shipment_type, weight (numeric), label_created_date, created_at, updated_at (datetime)\n\nAllowed sorts: id, tracking_number, name, weight, delivery_status, carrier_service_name, packaging_type, shipment_type, label_created_date, created_at, updated_at, order (sorts by the related order number) (prefix with `-` for DESC; default `-id`).\n\nPagination: `page` (default 1), `per_page` (default 10).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/packages","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","packages"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"integration_instance_id\": 2,\n      \"order_id\": 656,\n      \"package_index\": 0,\n      \"starshipit_package_id\": \"778812\",\n      \"name\": \"Carton\",\n      \"weight\": 1.5,\n      \"height\": 0.2,\n      \"width\": 0.3,\n      \"length\": 0.4,\n      \"packaging_type\": \"Box\",\n      \"carrier_service_code\": \"eParcel\",\n      \"carrier_service_name\": \"Australia Post eParcel\",\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n      \"delivery_status\": \"Delivered\",\n      \"shipment_type\": \"Domestic\",\n      \"label_created_date\": \"2026-05-26T03:14:00+00:00\",\n      \"order\": {\n        \"id\": 656,\n        \"order_number\": \"SO-1234\",\n        \"starshipit_order_id\": \"12345\",\n        \"link_reference\": \"SO-1234\",\n        \"link_type_label\": \"Starshipit Order\",\n        \"link_id\": 656,\n        \"link_route\": \"/integrations/starshipit/2/orders/656\"\n      },\n      \"created_at\": \"2026-05-25T14:02:00+00:00\",\n      \"updated_at\": \"2026-05-26T03:15:01+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/starshipit/integration-instances/2/packages?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}{{domain}}/api/starshipit/integration-instances/2/packages?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/starshipit/integration-instances/2/packages\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Package","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/packages/{package}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","packages",":package"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"package","value":"9001","description":"Internal StarshipitPackage ID"}]},"description":"Returns a single Starshipit package by its internal id, including its dimensions, carrier service, per-package tracking number/URL, delivery status, and a cross-link (`order`) back to the parent Starshipit order detail page. The raw package payload is always included as `json_object`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/packages/{package}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","packages",":package"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"package","value":"9001","description":"Internal StarshipitPackage ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9001,\n    \"integration_instance_id\": 2,\n    \"order_id\": 656,\n    \"package_index\": 0,\n    \"starshipit_package_id\": \"778812\",\n    \"name\": \"Carton\",\n    \"weight\": 1.5,\n    \"height\": 0.2,\n    \"width\": 0.3,\n    \"length\": 0.4,\n    \"packaging_type\": \"Box\",\n    \"carrier_service_code\": \"eParcel\",\n    \"carrier_service_name\": \"Australia Post eParcel\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"tracking_url\": \"https://track.starshipit.com/track/TRK-AU-1234567890\",\n    \"delivery_status\": \"Delivered\",\n    \"shipment_type\": \"Domestic\",\n    \"label_created_date\": \"2026-05-26T03:14:00+00:00\",\n    \"order\": {\n      \"id\": 656,\n      \"order_number\": \"SO-1234\",\n      \"starshipit_order_id\": \"12345\",\n      \"link_reference\": \"SO-1234\",\n      \"link_type_label\": \"Starshipit Order\",\n      \"link_id\": 656,\n      \"link_route\": \"/integrations/starshipit/2/orders/656\"\n    },\n    \"created_at\": \"2026-05-25T14:02:00+00:00\",\n    \"updated_at\": \"2026-05-26T03:15:01+00:00\",\n    \"json_object\": {\n      \"package_id\": \"778812\",\n      \"name\": \"Carton\",\n      \"weight\": 1.5,\n      \"height\": 0.2,\n      \"width\": 0.3,\n      \"length\": 0.4,\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"carrier_service_code\": \"eParcel\",\n      \"carrier_service_name\": \"Australia Post eParcel\"\n    }\n  }\n}"}]},{"name":"List Shipping Method Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]},"description":"Lists every distinct carrier + service pair observed on previously synced Starshipit orders for this integration instance, joined with any existing SKU shipping-method mapping. Stored-but-no-longer-observed mappings are also included.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach service carries a stable `code` of the form `\"{carrier}|{carrier_service_code}\"` which is the key used by the map / bulk-map / unmap endpoints. `mapping` is null when the pair is not yet mapped.\n\n`sku_shipping_methods` lists the available (non-archived) SKU shipping methods to map onto, ordered by full name.\n\nThis endpoint takes no query parameters.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"services\": [\n      {\n        \"code\": \"AusPost|eParcel\",\n        \"carrier\": \"AusPost\",\n        \"carrier_name\": \"Australia Post\",\n        \"carrier_service_code\": \"eParcel\",\n        \"order_count\": 128,\n        \"mapping\": {\n          \"id\": 41,\n          \"shipping_method_id\": 7,\n          \"shipping_method_name\": \"Australia Post - eParcel\",\n          \"shipping_method_type\": \"standard\"\n        }\n      },\n      {\n        \"code\": \"DHL|Express\",\n        \"carrier\": \"DHL\",\n        \"carrier_name\": \"DHL Express\",\n        \"carrier_service_code\": \"Express\",\n        \"order_count\": 16,\n        \"mapping\": null\n      }\n    ],\n    \"sku_shipping_methods\": [\n      {\n        \"id\": 7,\n        \"name\": \"eParcel\",\n        \"full_name\": \"Australia Post - eParcel\",\n        \"type\": \"standard\"\n      },\n      {\n        \"id\": 8,\n        \"name\": \"Express\",\n        \"full_name\": \"DHL Express - Express\",\n        \"type\": \"express\"\n      }\n    ]\n  }\n}"}]},{"name":"Export Mappings (CSV)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]},"description":"Downloads the current carrier/service-to-SKU-shipping-method mappings as a CSV file (Content-Type `text/csv`, Content-Disposition `attachment`). Filename: `starshipit-shipping-methods-{instanceId}-{YYYY-MM-DD}.csv`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nColumns: `code`, `carrier`, `carrier_name`, `carrier_service_code`, `order_count`, `shipping_method_id`, `shipping_method_name`. Rows for unmapped pairs leave `shipping_method_id` / `shipping_method_name` blank.\n\nThis is the template for the Import endpoint: export, edit the shipping method columns, then re-import. Response is a file download, not JSON.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/export","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","export"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"code,carrier,carrier_name,carrier_service_code,order_count,shipping_method_id,shipping_method_name\nAusPost|eParcel,AusPost,Australia Post,eParcel,128,7,Australia Post - eParcel\nDHL|Express,DHL,DHL Express,Express,16,,\n"}]},{"name":"Import Mappings (CSV)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]},"description":"Bulk-applies carrier/service-to-SKU-shipping-method mappings from an uploaded CSV (multipart/form-data, field `file`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPer row the target SKU shipping method is resolved by `shipping_method_id` first (authoritative), then by `shipping_method_name` (case-insensitive, matches the method name or full name). A row with both shipping-method columns blank removes the mapping for that code. The `code` is taken from the `code` column, or derived from `carrier` + `carrier_service_code` as `\"{carrier}|{carrier_service_code}\"`.\n\nReturns a summary of created / updated / deleted counts plus a list of human-readable per-line `errors` (e.g. unknown shipping method, missing code). Rows with errors are skipped; valid rows still apply.\n\nValidation: `file` is required, must be a file of type csv or txt, max 2048 KB.\n\nAuthentication: Requires Bearer token.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/import","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","import"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Import processed\",\n  \"data\": {\n    \"created\": 3,\n    \"updated\": 5,\n    \"deleted\": 1,\n    \"errors\": [\n      \"Line 9: shipping method id '9999' not found\",\n      \"Line 12: missing code (and carrier/service)\"\n    ]\n  }\n}"}]},{"name":"Map Carrier/Service","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]},"description":"Creates or updates the mapping for a single carrier/service `code` to a SKU shipping method.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `code` (string, required, max 255) — the carrier/service code, format `\"{carrier}|{carrier_service_code}\"`\n- `shipping_method_id` (integer, required) — must exist in `shipping_methods`\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"code\": \"AusPost|eParcel\",\n  \"shipping_method_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/map","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","map"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping saved\",\n  \"data\": {\n    \"id\": 41,\n    \"code\": \"AusPost|eParcel\",\n    \"shipping_method_id\": 7\n  }\n}"}]},{"name":"Bulk Map Carrier/Services","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]},"description":"Maps many carrier/service codes to a single SKU shipping method in one call (used by the bulk-select \"Apply to selected\" action on the mappings page). Codes are de-duplicated and blank entries skipped.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequest body:\n- `codes` (array of string, required, min 1; each max 255) — the carrier/service codes to map, format `\"{carrier}|{carrier_service_code}\"`\n- `shipping_method_id` (integer, required) — must exist in `shipping_methods`\n\nReturns the number of mappings written.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"codes\": [\n    \"AusPost|eParcel\",\n    \"DHL|Express\",\n    \"FedEx|Priority\"\n  ],\n  \"shipping_method_id\": 7\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/bulk-map","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","bulk-map"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 mapping(s) saved\",\n  \"data\": {\n    \"updated_count\": 3\n  }\n}"}]},{"name":"Unmap Carrier/Service","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/map/{code}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","map",":code"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"},{"key":"code","value":"AusPost|eParcel","description":"Carrier/service code to unmap, format \"{carrier}|{carrier_service_code}\". May contain a pipe; the route allows any characters."}]},"description":"Removes the mapping for a single carrier/service `code`. The `code` path segment may contain a pipe and other special characters (the route is registered with `where('code', '.*')`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 404 if no mapping exists for that code on this instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/shipping-methods/map/{code}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","shipping-methods","map",":code"],"variable":[{"key":"integration_instance","value":"6","description":"Starshipit integration instance ID"},{"key":"code","value":"AusPost|eParcel","description":"Carrier/service code to unmap, format \"{carrier}|{carrier_service_code}\". May contain a pipe; the route allows any characters."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Mapping removed\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a paginated list of inbound webhook events received from StarShipIt for this instance, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach event records the raw payload, whether its signature was valid, the extracted `order_number` / `tracking_number` / `tracking_status`, and its processing state: `processed` + `processed_at` when handled successfully, or `error_message` when processing failed (failed events can be re-queued via the retry endpoint).\n\n`tracking_status` values: `Printed`, `Dispatched`, `InTransit`, `OutForDelivery`, `Delivered`, `PickupInStore`, `AttemptedDelivery`, `Exception`, `AwaitingCollection`, `Cancelled`, `Manifested`, `ReturnPickupPrinted`, `ReturnDropoffPrinted`, `DroppedOff`, `ReturnLink`, `ReturnLabel`.\n\nFiltering uses operator-aware syntax: `filter[column.operator]=value` (text operators: `contains`, `does_not_contain`, `is`, `is_not`, `is_one_of`, `is_not_one_of`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`; datetime operators include `between`). A bare `filter[column]=value` acts as `is`.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9011,\n      \"integration_instance_id\": 2,\n      \"event_type\": \"tracking_updated\",\n      \"tracking_status\": \"Delivered\",\n      \"tracking_status_label\": \"Delivered\",\n      \"tracking_status_color\": \"success\",\n      \"order_number\": \"SO-1234\",\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"signature_valid\": true,\n      \"payload\": {\n        \"order_number\": \"SO-1234\",\n        \"tracking_number\": \"TRK-AU-1234567890\",\n        \"tracking_status\": \"Delivered\",\n        \"carrier_name\": \"Australia Post\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-07-05T08:01:11+00:00\",\n      \"error_message\": null,\n      \"created_at\": \"2026-07-05T08:01:09+00:00\",\n      \"updated_at\": \"2026-07-05T08:01:11+00:00\"\n    },\n    {\n      \"id\": 9008,\n      \"integration_instance_id\": 2,\n      \"event_type\": \"tracking_updated\",\n      \"tracking_status\": \"InTransit\",\n      \"tracking_status_label\": \"In Transit\",\n      \"tracking_status_color\": \"primary\",\n      \"order_number\": \"SO-1230\",\n      \"tracking_number\": \"TRK-AU-0009988776\",\n      \"signature_valid\": true,\n      \"payload\": {\n        \"order_number\": \"SO-1230\",\n        \"tracking_number\": \"TRK-AU-0009988776\",\n        \"tracking_status\": \"InTransit\"\n      },\n      \"processed\": false,\n      \"processed_at\": null,\n      \"error_message\": \"No matching order found for order_number SO-1230\",\n      \"created_at\": \"2026-07-04T21:14:33+00:00\",\n      \"updated_at\": \"2026-07-04T21:14:35+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events?page=1\",\n  \"from\": 1,\n  \"last_page\": 34,\n  \"last_page_url\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events?page=34\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events?page=2\",\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events?page=2\",\n  \"path\": \"https://example.sku.io/api/starshipit/integration-instances/2/webhook-events\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 502\n}"}]},{"name":"Get Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"9011","description":"The webhook event ID."}]},"description":"Returns a single inbound webhook event, including the full raw payload StarShipIt delivered, the signature verification result, and the processing outcome (`processed` / `processed_at` on success, `error_message` on failure).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 404 when the event does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events/{webhook_event}","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events",":webhook_event"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"9011","description":"The webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9011,\n    \"integration_instance_id\": 2,\n    \"event_type\": \"tracking_updated\",\n    \"tracking_status\": \"Delivered\",\n    \"tracking_status_label\": \"Delivered\",\n    \"tracking_status_color\": \"success\",\n    \"order_number\": \"SO-1234\",\n    \"tracking_number\": \"TRK-AU-1234567890\",\n    \"signature_valid\": true,\n    \"payload\": {\n      \"order_number\": \"SO-1234\",\n      \"tracking_number\": \"TRK-AU-1234567890\",\n      \"tracking_status\": \"Delivered\",\n      \"carrier_name\": \"Australia Post\",\n      \"carrier_service\": \"Parcel Post\"\n    },\n    \"processed\": true,\n    \"processed_at\": \"2026-07-05T08:01:11+00:00\",\n    \"error_message\": null,\n    \"created_at\": \"2026-07-05T08:01:09+00:00\",\n    \"updated_at\": \"2026-07-05T08:01:11+00:00\"\n  }\n}"}]},{"name":"Retry Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events/{webhook_event}/retry","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events",":webhook_event","retry"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"9008","description":"The webhook event ID."}]},"description":"Queues a background job to reprocess a webhook event — typically one that failed and recorded an `error_message`. No request body.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReprocessing re-applies the stored payload as if the webhook had just arrived: the event is matched to a cached order by order number or tracking number, the tracking status is applied (which can update order status, record fulfillment shipment, and push tracking to the sales channel), and the event is marked `processed` on success or gets a fresh `error_message` on failure. The job retries up to 5 times with increasing backoff.\n\nRetrying is safe: events already marked as processed are skipped by the background job, so re-queuing a successful event is a no-op.\n\nReturns 404 when the event does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/starshipit/integration-instances/{integration_instance}/webhook-events/{webhook_event}/retry","host":["{{baseUrl}}"],"path":["api","starshipit","integration-instances",":integration_instance","webhook-events",":webhook_event","retry"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhook_event","value":"9008","description":"The webhook event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook event queued for retry\"\n}"}]}]},{"name":"API Shipping Provider","item":[{"name":"Create Provider","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers","host":["{{baseUrl}}"],"path":["api","api-shipping-providers"]},"description":"Create a new API Shipping Provider integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body Fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `name` | string | **Yes** | Display name for the provider (max 255 chars) |\n\n**Post-Request Script:**\n\nAutomatically sets the {{provider-id}} collection variable on success.","body":{"mode":"raw","raw":"{\n  \"name\": \"My 3PL Provider\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/api-shipping-providers","host":["{{baseUrl}}"],"path":["api","api-shipping-providers"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My 3PL Provider\",\n    \"integration_id\": 15,\n    \"connection_settings\": null,\n    \"integration_settings\": null,\n    \"sync_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"warehouse_mappings\": [],\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:30:00.000000Z\"\n  }\n}"}]},{"name":"Show Provider","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Show a single shipping provider integration instance by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My 3PL Provider\",\n    \"integration_id\": 15,\n    \"connection_settings\": null,\n    \"integration_settings\": {\n      \"ignore_fulfillments_without_tracking\": false\n    },\n    \"sync_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"warehouse_mappings\": [\n      {\n        \"id\": 1,\n        \"warehouse_id\": 5,\n        \"external_warehouse_id\": \"WH-001\",\n        \"warehouse\": {\n          \"id\": 5,\n          \"name\": \"Main Warehouse\"\n        }\n      }\n    ],\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-01-15T10:30:00.000000Z\"\n  }\n}"}]},{"name":"Update Provider","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Update a shipping provider integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body Fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `name` | string | No | Display name for the provider |\n| `integration_settings` | object | No | Provider-specific settings |\n| `integration_settings.ignore_fulfillments_without_tracking` | boolean | No | Skip fulfillments that lack tracking numbers |\n| `warehouse_mappings` | array | No | Warehouse mapping array |\n| `warehouse_mappings.*.warehouse_id` | integer | Required with warehouse_mappings | SKU.io warehouse ID |\n| `warehouse_mappings.*.external_warehouse_id` | string | Required with warehouse_mappings | External warehouse identifier |","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Provider Name\",\n  \"integration_settings\": {\n    \"ignore_fulfillments_without_tracking\": true\n  },\n  \"warehouse_mappings\": [\n    {\n      \"warehouse_id\": 5,\n      \"external_warehouse_id\": \"WH-001\"\n    },\n    {\n      \"warehouse_id\": 8,\n      \"external_warehouse_id\": \"WH-002\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Provider Name\",\n    \"integration_id\": 15,\n    \"connection_settings\": null,\n    \"integration_settings\": {\n      \"ignore_fulfillments_without_tracking\": true\n    },\n    \"sync_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"warehouse_mappings\": [\n      {\n        \"id\": 1,\n        \"warehouse_id\": 5,\n        \"external_warehouse_id\": \"WH-001\",\n        \"warehouse\": {\n          \"id\": 5,\n          \"name\": \"Main Warehouse\"\n        }\n      }\n    ],\n    \"created_at\": \"2026-01-15T10:30:00.000000Z\",\n    \"updated_at\": \"2026-01-15T12:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Provider","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Delete a shipping provider integration instance and all associated data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `integrationInstance` | integer | The integration instance ID |\n\n**Response:** HTTP 204 No Content on success."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Get Dashboard Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/dashboard","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","dashboard"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Get dashboard statistics for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n\n**Response:** Returns aggregated stats for the provider."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/dashboard","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","dashboard"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_events\": 150,\n    \"processed_events\": 120,\n    \"failed_events\": 10,\n    \"pending_events\": 15,\n    \"skipped_events\": 5\n  }\n}"}]},{"name":"List Tokens","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"List all API tokens for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n\n**Note:** Token values are not returned - only metadata (name, abilities, last used, created at)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Production Token\",\n      \"abilities\": [\n        \"*\"\n      ],\n      \"last_used_at\": \"2026-01-20T08:00:00.000000Z\",\n      \"created_at\": \"2026-01-15T10:30:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Generate Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Generate a new API token for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body Fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `name` | string | **Yes** | Descriptive name for the token (max 255 chars) |\n\n**Important:** Store the token securely after generation - the plain text token cannot be retrieved again.","body":{"mode":"raw","raw":"{\n  \"name\": \"Production Token\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"token\": \"1|laravel_sanctum_abcdefghijklmnop1234567890\",\n    \"name\": \"Production Token\"\n  },\n  \"message\": \"Token generated successfully.\"\n}"}]},{"name":"Revoke Token","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens/{token-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens",":token-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."},{"key":"token-id","value":"","description":"The token ID."}]},"description":"Revoke a specific API token.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n| `tokenId` | integer | The token ID to revoke |\n\n**Note:** Once revoked, the token can no longer be used for authentication."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/tokens/{token-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","tokens",":token-id"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."},{"key":"token-id","value":"","description":"The token ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Token revoked successfully.\"\n}"}]},{"name":"List Inbound Events (Paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events"],"query":[{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"List paginated inbound events for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n\n**Query Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `per_page` | integer | Items per page (default: 10) |\n| `page` | integer | Page number |\n| `filter[status]` | string | Filter by processing_status |\n| `filter[endpoint]` | string | Filter by endpoint |\n| `filter[linked_resource]` | string | yes/no - filter by linked resource presence |\n| `filter[date_from]` | string | Filter from date (YYYY-MM-DD) |\n| `filter[date_to]` | string | Filter to date (YYYY-MM-DD) |\n| `filter[search]` | string | Advanced search across ID, unique_id, linked resource |\n| `sort` | string | Sort field (prefix with - for descending) |"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events"],"query":[{"key":"per_page","value":"10","description":"Items per page (default: 10)","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"integration_instance_id\": 1,\n      \"endpoint\": \"3pl.orders.fulfill\",\n      \"http_method\": \"POST\",\n      \"processing_status\": \"success\",\n      \"ip_address\": \"203.0.113.10\",\n      \"user_agent\": \"D3-Logistics/1.0\",\n      \"request_payload\": {\n        \"lines\": [\n          {\n            \"id\": 88,\n            \"quantity_fulfilled\": 5\n          }\n        ],\n        \"tracking_number\": \"TRACK123456\",\n        \"shipping_method\": \"FedEx Ground\"\n      },\n      \"response_payload\": {\n        \"message\": \"Order fulfillment processed successfully.\"\n      },\n      \"request_headers\": {\n        \"content-type\": [\n          \"application/json\"\n        ],\n        \"authorization\": [\n          \"[REDACTED]\"\n        ]\n      },\n      \"linked_resource_type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n      \"linked_resource_id\": 88,\n      \"unique_id\": null,\n      \"created_at\": \"2026-06-12T22:48:00.000000Z\",\n      \"processed_at\": \"2026-06-12T22:48:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 13,\n  \"per_page\": 10,\n  \"total\": 124,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"{{protocol}}{{domain}}/api/api-shipping-providers/1/inbound-events?page=1\",\n  \"next_page_url\": \"{{protocol}}{{domain}}/api/api-shipping-providers/1/inbound-events?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}{{domain}}/api/api-shipping-providers/1/inbound-events\"\n}"}]},{"name":"Get Inbound Event Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events/stats","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events","stats"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Get inbound event statistics and distinct endpoints for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n\n**Response:** Returns counts by status and a list of distinct endpoints."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events/stats","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events","stats"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total\": 124,\n    \"success\": 118,\n    \"error\": 6,\n    \"endpoints\": [\n      \"3pl.products.index\",\n      \"3pl.orders.index\",\n      \"3pl.orders.fulfill\",\n      \"3pl.inventory-adjustments.store\"\n    ]\n  }\n}"}]},{"name":"Show Inbound Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/inbound-events/{event-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers","inbound-events",":event-id"],"variable":[{"key":"event-id","value":"","description":"The event ID."}]},"description":"Show a single inbound event with full payload details.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `eventId` | integer | The inbound event ID |\n\n**Note:** This endpoint is not scoped to a provider instance since event IDs are globally unique."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/inbound-events/{event-id}","host":["{{baseUrl}}"],"path":["api","api-shipping-providers","inbound-events",":event-id"],"variable":[{"key":"event-id","value":"","description":"The event ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 1,\n    \"endpoint\": \"3pl.orders.fulfill\",\n    \"http_method\": \"POST\",\n    \"processing_status\": \"success\",\n    \"ip_address\": \"203.0.113.10\",\n    \"user_agent\": \"D3-Logistics/1.0\",\n    \"request_payload\": {\n      \"lines\": [\n        {\n          \"id\": 88,\n          \"quantity_fulfilled\": 5\n        }\n      ],\n      \"tracking_number\": \"TRACK123456\",\n      \"shipping_method\": \"FedEx Ground\"\n    },\n    \"response_payload\": {\n      \"message\": \"Order fulfillment processed successfully.\"\n    },\n    \"request_headers\": {\n      \"content-type\": [\n        \"application/json\"\n      ],\n      \"authorization\": [\n        \"[REDACTED]\"\n      ]\n    },\n    \"linked_resource_type\": \"App\\\\Models\\\\SalesOrderFulfillment\",\n    \"linked_resource_id\": 88,\n    \"unique_id\": null,\n    \"created_at\": \"2026-06-12T22:48:00.000000Z\",\n    \"processed_at\": \"2026-06-12T22:48:00.000000Z\"\n  }\n}"}]},{"name":"Bulk Delete Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/inbound-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","api-shipping-providers","inbound-events","bulk-delete"]},"description":"Bulk delete multiple inbound events.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Request Body Fields:**\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `ids` | array | **Yes** | Array of event IDs to delete (min: 1) |\n| `ids.*` | integer | **Yes** | Individual event ID |"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/inbound-events/bulk-delete","host":["{{baseUrl}}"],"path":["api","api-shipping-providers","inbound-events","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 event(s) deleted.\"\n}"}]},{"name":"Delete All Events for Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events/delete-all","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events","delete-all"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]},"description":"Delete all inbound events for a shipping provider instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**URL Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | The integration instance ID |\n\n**Warning:** This is a destructive operation that removes all events."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/api-shipping-providers/{provider-id}/inbound-events/delete-all","host":["{{baseUrl}}"],"path":["api","api-shipping-providers",":provider-id","inbound-events","delete-all"],"variable":[{"key":"provider-id","value":"","description":"The provider ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"42 event(s) deleted.\"\n}"}]}]},{"name":"Shippit","item":[{"name":"Test Connection","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/test","host":["{{baseUrl}}"],"path":["api","shippit","test"]},"description":"Validates a Shippit API key without saving a connection. Shippit is a courier aggregator; this probes the supplied key against Shippit's merchant endpoint and returns the merchant profile it resolves to, so you can confirm the key is correct before creating an instance.\n\nBody fields:\n- api_key (string, required): the Shippit API key to validate. Minimum 8 characters.\n- environment (string, optional): which Shippit environment the key belongs to, either \"production\" or \"sandbox\". Defaults to \"production\".\n\nReturns 200 with the resolved merchant name and company/contact details when the key is accepted. Returns 422 with a \"code\" of \"invalid_key\" when Shippit rejects the key, or \"api_error\" when Shippit could not be reached. Returns 422 with field errors when the request body itself is invalid.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"api_key\": \"sku_live_9f2c1a7b4e6d0c3a8f5b2e91\",\n  \"environment\": \"production\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/test","host":["{{baseUrl}}"],"path":["api","shippit","test"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"merchant\": {\n      \"name\": \"Acme Fulfillment\",\n      \"company_name\": \"Acme Fulfillment Pty Ltd\",\n      \"contact_name\": \"Jordan Blake\"\n    }\n  },\n  \"message\": \"Connection successful\"\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances","host":["{{baseUrl}}"],"path":["api","shippit","instances"]},"description":"Creates and connects a new Shippit integration instance for the current account, then returns it together with a live dashboard summary (merchant profile, order-state counts, courier and warehouse-mapping counts, and the webhook URL to paste into your Shippit account).\n\nBody fields:\n- name (string, required): a label for this connection. Max 255 characters.\n- api_key (string, required): the Shippit API key. Minimum 8 characters.\n- environment (string, optional): \"production\" or \"sandbox\". Defaults to \"production\".\n- auto_book (boolean, optional): automatically book shipments with Shippit. Defaults to true.\n- record_shipping_costs (boolean, optional): capture Shippit shipping costs against orders. Defaults to true.\n- default_courier_type (string, optional, nullable): default Shippit courier type to request, e.g. \"standard\" or \"express\". Max 100 characters.\n\nReturns 201 with the created instance and its dashboard summary. Returns 422 with field errors when validation fails.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Shippit AU\",\n  \"api_key\": \"sku_live_9f2c1a7b4e6d0c3a8f5b2e91\",\n  \"environment\": \"production\",\n  \"auto_book\": true,\n  \"record_shipping_costs\": true,\n  \"default_courier_type\": \"standard\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances","host":["{{baseUrl}}"],"path":["api","shippit","instances"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Shippit AU\",\n    \"environment\": \"production\",\n    \"is_sandbox\": false,\n    \"is_automatic_sync_enabled\": true,\n    \"auto_book\": true,\n    \"default_courier_type\": \"standard\",\n    \"record_shipping_costs\": true,\n    \"sync_start_date\": \"2026-01-01T00:00:00+00:00\",\n    \"sync_status\": \"idle\",\n    \"merchant\": {\n      \"name\": \"Acme Fulfillment\",\n      \"company_name\": \"Acme Fulfillment Pty Ltd\",\n      \"contact_name\": \"Jordan Blake\"\n    },\n    \"order_state_counts\": {\n      \"ready_for_pickup\": 12,\n      \"in_transit\": 340,\n      \"delivered\": 1180,\n      \"cancelled\": 8\n    },\n    \"order_count\": 1540,\n    \"courier_count\": 6,\n    \"warehouse_mapping_count\": 3,\n    \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n    \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n    \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n    \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n    \"is_connected\": true,\n    \"created_at\": \"2026-03-10T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-08T01:30:01+00:00\"\n  },\n  \"merchant\": {\n    \"name\": \"Acme Fulfillment\",\n    \"company_name\": \"Acme Fulfillment Pty Ltd\",\n    \"contact_name\": \"Jordan Blake\"\n  },\n  \"order_state_counts\": {\n    \"ready_for_pickup\": 12,\n    \"in_transit\": 340,\n    \"delivered\": 1180,\n    \"cancelled\": 8\n  },\n  \"order_count\": 1540,\n  \"courier_count\": 6,\n  \"warehouse_mapping_count\": 3,\n  \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n  \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n  \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n  \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n  \"is_connected\": true\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a single Shippit integration instance together with a live dashboard summary: the resolved Shippit merchant profile, per-state order counts, total order/courier/warehouse-mapping counts, the webhook URL, and the last webhook and sync timestamps.\n\nPath parameter:\n- instance: the numeric ID of the Shippit integration instance.\n\nReturns 404 when the instance does not exist.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Shippit AU\",\n    \"environment\": \"production\",\n    \"is_sandbox\": false,\n    \"is_automatic_sync_enabled\": true,\n    \"auto_book\": true,\n    \"default_courier_type\": \"standard\",\n    \"record_shipping_costs\": true,\n    \"sync_start_date\": \"2026-01-01T00:00:00+00:00\",\n    \"sync_status\": \"idle\",\n    \"merchant\": {\n      \"name\": \"Acme Fulfillment\",\n      \"company_name\": \"Acme Fulfillment Pty Ltd\",\n      \"contact_name\": \"Jordan Blake\"\n    },\n    \"order_state_counts\": {\n      \"ready_for_pickup\": 12,\n      \"in_transit\": 340,\n      \"delivered\": 1180,\n      \"cancelled\": 8\n    },\n    \"order_count\": 1540,\n    \"courier_count\": 6,\n    \"warehouse_mapping_count\": 3,\n    \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n    \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n    \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n    \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n    \"is_connected\": true,\n    \"created_at\": \"2026-03-10T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-08T01:30:01+00:00\"\n  },\n  \"merchant\": {\n    \"name\": \"Acme Fulfillment\",\n    \"company_name\": \"Acme Fulfillment Pty Ltd\",\n    \"contact_name\": \"Jordan Blake\"\n  },\n  \"order_state_counts\": {\n    \"ready_for_pickup\": 12,\n    \"in_transit\": 340,\n    \"delivered\": 1180,\n    \"cancelled\": 8\n  },\n  \"order_count\": 1540,\n  \"courier_count\": 6,\n  \"warehouse_mapping_count\": 3,\n  \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n  \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n  \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n  \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n  \"is_connected\": true\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Updates settings on an existing Shippit integration instance. All fields are optional — send only what should change; omitted fields are left untouched. Returns the updated instance with a refreshed dashboard summary.\n\nPath parameter:\n- instance: the numeric ID of the Shippit integration instance.\n\nBody fields (all optional):\n- name (string): connection label. Max 255 characters.\n- api_key (string): rotate the Shippit API key. Minimum 8 characters.\n- environment (string): \"production\" or \"sandbox\".\n- auto_book (boolean): automatically book shipments with Shippit.\n- record_shipping_costs (boolean): capture Shippit shipping costs against orders.\n- default_courier_type (string, nullable): default Shippit courier type. Max 100 characters.\n- sync_start_date (date, nullable): earliest order date to sync (YYYY-MM-DD).\n- is_automatic_sync_enabled (boolean): whether scheduled syncs run automatically.\n\nReturns 422 with field errors when validation fails; 404 when the instance does not exist.\n\nAuthentication: Requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Shippit AU (Primary)\",\n  \"api_key\": \"sku_live_1a2b3c4d5e6f7g8h9i0j1k2l\",\n  \"environment\": \"production\",\n  \"auto_book\": false,\n  \"record_shipping_costs\": true,\n  \"default_courier_type\": \"express\",\n  \"sync_start_date\": \"2026-01-01\",\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"Shippit AU (Primary)\",\n    \"environment\": \"production\",\n    \"is_sandbox\": false,\n    \"is_automatic_sync_enabled\": true,\n    \"auto_book\": false,\n    \"default_courier_type\": \"express\",\n    \"record_shipping_costs\": true,\n    \"sync_start_date\": \"2026-01-01T00:00:00+00:00\",\n    \"sync_status\": \"idle\",\n    \"merchant\": {\n      \"name\": \"Acme Fulfillment\",\n      \"company_name\": \"Acme Fulfillment Pty Ltd\",\n      \"contact_name\": \"Jordan Blake\"\n    },\n    \"order_state_counts\": {\n      \"ready_for_pickup\": 12,\n      \"in_transit\": 340,\n      \"delivered\": 1180,\n      \"cancelled\": 8\n    },\n    \"order_count\": 1540,\n    \"courier_count\": 6,\n    \"warehouse_mapping_count\": 3,\n    \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n    \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n    \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n    \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n    \"is_connected\": true,\n    \"created_at\": \"2026-03-10T09:00:00+00:00\",\n    \"updated_at\": \"2026-07-08T02:05:11+00:00\"\n  },\n  \"merchant\": {\n    \"name\": \"Acme Fulfillment\",\n    \"company_name\": \"Acme Fulfillment Pty Ltd\",\n    \"contact_name\": \"Jordan Blake\"\n  },\n  \"order_state_counts\": {\n    \"ready_for_pickup\": 12,\n    \"in_transit\": 340,\n    \"delivered\": 1180,\n    \"cancelled\": 8\n  },\n  \"order_count\": 1540,\n  \"courier_count\": 6,\n  \"warehouse_mapping_count\": 3,\n  \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n  \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n  \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n  \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n  \"is_connected\": true\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Disconnects and removes a Shippit integration instance. The teardown runs asynchronously: this endpoint records the disconnect and hands the cascade cleanup (cached orders, couriers, webhook events, and related records) to a background job, then returns immediately with no content.\n\nPath parameter:\n- instance: the numeric ID of the Shippit integration instance.\n\nReturns 204 No Content on success. Returns 404 when the instance does not exist.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Get Dashboard Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns just the live dashboard summary for a Shippit integration instance — the lightweight refresh endpoint for the dashboard widget, without the full instance settings payload.\n\nPath parameter:\n- instance: the numeric ID of the Shippit integration instance.\n\nThe response \"data\" object contains:\n- merchant: the resolved Shippit merchant profile (name, company_name, contact_name), or an \"error\" message when the merchant lookup failed.\n- environment: \"production\" or \"sandbox\".\n- order_state_counts: a map of Shippit order state to count.\n- order_count / courier_count / warehouse_mapping_count: totals for the instance.\n- auto_book / record_shipping_costs: current setting values.\n- last_webhook_at / last_synced_at: ISO-8601 timestamps, or null when never run.\n- webhook_url: the URL to paste into your Shippit account for webhook delivery.\n- is_connected: whether the Shippit merchant lookup currently succeeds.\n\nReturns 404 when the instance does not exist.\n\nAuthentication: Requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/dashboard","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","dashboard"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"merchant\": {\n      \"name\": \"Acme Fulfillment\",\n      \"company_name\": \"Acme Fulfillment Pty Ltd\",\n      \"contact_name\": \"Jordan Blake\"\n    },\n    \"environment\": \"production\",\n    \"order_state_counts\": {\n      \"ready_for_pickup\": 12,\n      \"in_transit\": 340,\n      \"delivered\": 1180,\n      \"cancelled\": 8\n    },\n    \"order_count\": 1540,\n    \"courier_count\": 6,\n    \"warehouse_mapping_count\": 3,\n    \"auto_book\": true,\n    \"record_shipping_costs\": true,\n    \"last_webhook_at\": \"2026-07-07T22:14:05+00:00\",\n    \"last_synced_at\": \"2026-07-08T01:30:00+00:00\",\n    \"webhook_url\": \"https://acme.sku.io/api/webhooks/shippit/abc123def456\",\n    \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\",\n    \"is_connected\": true\n  }\n}"}]},{"name":"List Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Paginated, filterable list of Shippit orders for the integration instance.\n\nEvery filter[&lt;column>] parameter also accepts an operator suffix as filter[&lt;column>.&lt;operator>]=&lt;value>; a bare filter[&lt;column>]=&lt;value> is treated as \"is\".\n\n- Text columns support: contains, does_not_contain, is, is_not, is_one_of, is_not_one_of, starts_with, does_not_start_with, ends_with, does_not_end_with, is_empty, is_not_empty.\n- Numeric columns support: is, is_not, is_one_of, is_not_one_of, greater_than, less_than, greater_than_or_equal, less_than_or_equal, between, is_empty, is_not_empty.\n- Date columns support: is, is_not, before, after, on_or_before, on_or_after, between, today, yesterday, tomorrow, past_week, past_month, past_year, next_week, next_month, next_year, days_ago, days_from_now, past_days, next_days, is_empty, is_not_empty.\n\nfilter[search] does a fuzzy partial match across tracking_number, retailer_order_number, retailer_reference, receiver_name and courier_name.\n\nSort with the sort parameter (prefix - for descending). Allowed sort fields: id, shippit_id, state, courier_type, courier_name, tracking_number, receiver_name, retailer_order_number, retailer_reference, price, expected_delivery_date, details_last_updated, created_at, updated_at. The default sort is -id (newest first).\n\nResults are paginated; per_page defaults to 10.\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"integration_instance_id\": 3,\n      \"shippit_id\": 7712345,\n      \"tracking_number\": \"DZ1000456789\",\n      \"slug\": \"acme-couriers\",\n      \"courier_type\": \"standard\",\n      \"courier_allocation\": \"CouriersPlease\",\n      \"courier_name\": \"CouriersPlease\",\n      \"service_level\": \"standard\",\n      \"state\": \"ready_for_pickup\",\n      \"processing_state\": \"completed\",\n      \"retailer_order_number\": \"SO-100482\",\n      \"retailer_reference\": \"ACME-REF-9931\",\n      \"receiver_name\": \"Jane Doe\",\n      \"delivery_address\": \"1 Smith Street\",\n      \"delivery_suburb\": \"Richmond\",\n      \"delivery_postcode\": \"3121\",\n      \"delivery_state\": \"VIC\",\n      \"delivery_country_code\": \"AU\",\n      \"authority_to_leave\": true,\n      \"price\": 8.95,\n      \"tracking_url\": \"https://www.shippit.com/tracking/DZ1000456789\",\n      \"expected_delivery_date\": \"2026-07-11T00:00:00+00:00\",\n      \"details_last_updated\": \"2026-07-08T04:15:00+00:00\",\n      \"external_url\": \"https://app.shippit.com/orders/DZ1000456789\",\n      \"sku_fulfillment_order_id\": 55210,\n      \"sales_order_number\": \"SO-100482\",\n      \"link_type_label\": \"Fulfillment Order\",\n      \"link_id\": 55210,\n      \"link_reference\": \"SO-100482\",\n      \"link_route\": \"/orders/sales-orders/8842?tab=fulfillment\",\n      \"created_at\": \"2026-07-07T22:40:00+00:00\",\n      \"updated_at\": \"2026-07-08T04:15:01+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 48,\n  \"from\": 1,\n  \"to\": 10,\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/shippit/instances/3/orders?page=1\",\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/shippit/instances/3/orders?page=5\",\n  \"next_page_url\": \"{{protocol}}://{{domain}}/api/shippit/instances/3/orders?page=2\",\n  \"prev_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/shippit/instances/3/orders\"\n}"}]},{"name":"Sync Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background job that reconciles the current state of existing Shippit orders for this instance (Shippit has no bulk order list, so the sweep refreshes each non-terminal order individually via its tracking number). The response returns the tracked job log id, which you can poll for progress.\n\nAll body fields are optional — send an empty body {} to sweep every non-terminal order.\n\n- since — only refresh orders last updated before this date/time (ISO 8601 or Y-m-d). Targets stale rows.\n- date_from — only include orders created on or after this date (Y-m-d).\n- date_to — only include orders created on or before this date (Y-m-d); must be on or after date_from.\n- tracking_number — refresh only the single order carrying this tracking number (max 255 chars).\n\nAuthentication: requires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"since\": \"2026-07-01T00:00:00+00:00\",\n  \"date_from\": \"2026-07-01\",\n  \"date_to\": \"2026-07-08\",\n  \"tracking_number\": \"DZ1000456789\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4321\n  },\n  \"message\": \"Order sync started — track progress in the job tray.\"\n}"}]},{"name":"Get Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/{order}?include_json=1","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders",":order"],"query":[{"key":"include_json","value":"1","description":"Set to 1 to include the stored provider payload as json_object in the response.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"4821","description":"Internal Shippit order id (scoped to the instance)."}]},"description":"Returns the full details for a single Shippit order scoped to the integration instance. Includes the raw provider identifiers (shippit_id, tracking_number, state), courier and delivery fields, price, tracking URL, a deep link to the Shippit merchant portal (external_url), and cross-link fields to the originating fulfillment order / sales order.\n\nWhen include_json=1 is supplied, the response also includes items — normalized line items with each SKU resolved to its product id for cross-linking — and the stored provider payload as json_object.\n\nA tracking number / instance mismatch returns 404.\n\nAuthentication: requires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/{order}?include_json=1","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders",":order"],"query":[{"key":"include_json","value":"1","description":"Set to 1 to include the stored provider payload as json_object in the response.","disabled":true}],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"4821","description":"Internal Shippit order id (scoped to the instance)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"integration_instance_id\": 3,\n    \"shippit_id\": 7712345,\n    \"tracking_number\": \"DZ1000456789\",\n    \"slug\": \"acme-couriers\",\n    \"courier_type\": \"standard\",\n    \"courier_allocation\": \"CouriersPlease\",\n    \"courier_name\": \"CouriersPlease\",\n    \"service_level\": \"standard\",\n    \"state\": \"ready_for_pickup\",\n    \"processing_state\": \"completed\",\n    \"retailer_order_number\": \"SO-100482\",\n    \"retailer_reference\": \"ACME-REF-9931\",\n    \"receiver_name\": \"Jane Doe\",\n    \"delivery_address\": \"1 Smith Street\",\n    \"delivery_suburb\": \"Richmond\",\n    \"delivery_postcode\": \"3121\",\n    \"delivery_state\": \"VIC\",\n    \"delivery_country_code\": \"AU\",\n    \"authority_to_leave\": true,\n    \"price\": 8.95,\n    \"tracking_url\": \"https://www.shippit.com/tracking/DZ1000456789\",\n    \"expected_delivery_date\": \"2026-07-11T00:00:00+00:00\",\n    \"details_last_updated\": \"2026-07-08T04:15:00+00:00\",\n    \"external_url\": \"https://app.shippit.com/orders/DZ1000456789\",\n    \"sku_fulfillment_order_id\": 55210,\n    \"sales_order_number\": \"SO-100482\",\n    \"link_type_label\": \"Fulfillment Order\",\n    \"link_id\": 55210,\n    \"link_reference\": \"SO-100482\",\n    \"link_route\": \"/orders/sales-orders/8842?tab=fulfillment\",\n    \"items\": [\n      {\n        \"sku\": \"ACME-WIDGET-01\",\n        \"name\": \"Acme Widget\",\n        \"quantity\": 2,\n        \"price\": 24.5,\n        \"weight\": 0.35,\n        \"product_id\": 90231\n      }\n    ],\n    \"json_object\": {\n      \"retailer_order_number\": \"SO-100482\",\n      \"products\": [\n        {\n          \"sku\": \"ACME-WIDGET-01\",\n          \"title\": \"Acme Widget\",\n          \"quantity\": 2,\n          \"price\": 24.5,\n          \"weight\": 0.35\n        }\n      ],\n      \"last_tracking\": {\n        \"current_state\": \"ready_for_pickup\"\n      }\n    },\n    \"created_at\": \"2026-07-07T22:40:00+00:00\",\n    \"updated_at\": \"2026-07-08T04:15:01+00:00\"\n  }\n}"}]},{"name":"Book Order","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/{order}/book","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders",":order","book"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"4821","description":"Internal Shippit order id (scoped to the instance)."}]},"description":"Books a courier pickup for an already-created Shippit order (transitions it out of order_placed toward despatch). Runs as a background job; the response returns the tracked job log id, which you can poll for progress.\n\nNo request body is required. A tracking number / instance mismatch returns 404.\n\nAuthentication: requires a Bearer token.","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/orders/{order}/book","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","orders",":order","book"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"order","value":"4821","description":"Internal Shippit order id (scoped to the instance)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4322\n  },\n  \"message\": \"Booking started — track progress in the job tray.\"\n}"}]},{"name":"List Shipments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List shipments (consignments) for the shipping-provider instance, paginated. Each shipment carries the despatch data — courier job, tracking number and URL, service level, price, parcel count, and despatch/delivery timestamps — a deep link into the Shippit portal (`external_url`), plus a cross-link to the fulfillment it realized (link_type_label / link_reference / link_route). Shipments belonging to another instance are not returned.\n\nSort field. Prefix with - for descending. Allowed: id, shippit_order_id, courier_name, tracking_number, shipping_price, number_of_parcels, despatched_at, delivered_at, created_at, updated_at. Default: -id (newest first).\n\nAuthenticate with a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 4821,\n      \"shippit_order_id\": 3310,\n      \"order_tracking_number\": \"SPT-AU-88213345\",\n      \"courier_job_id\": \"JOB-7GQ2K\",\n      \"courier_name\": \"Australia Post\",\n      \"tracking_number\": \"AP4H2388922102000935105\",\n      \"tracking_url\": \"https://app.shippit.com/tracking/AP4H2388922102000935105\",\n      \"service_level\": \"standard\",\n      \"shipping_price\": 12.45,\n      \"number_of_parcels\": 2,\n      \"despatched_at\": \"2026-06-30T02:14:00+00:00\",\n      \"delivered_at\": null,\n      \"external_url\": \"https://app.staging.shippit.com/orders/SPT-AU-88213345\",\n      \"sku_sales_order_fulfillment_id\": 256917,\n      \"link_type_label\": \"Sales Order Fulfillment\",\n      \"link_id\": 256917,\n      \"link_reference\": \"F-256917\",\n      \"link_route\": \"/orders/sales-orders/fulfillments/256917\",\n      \"created_at\": \"2026-06-30T02:14:05+00:00\",\n      \"updated_at\": \"2026-06-30T02:14:05+00:00\"\n    },\n    {\n      \"id\": 4799,\n      \"shippit_order_id\": 3288,\n      \"order_tracking_number\": \"SPT-AU-88210012\",\n      \"courier_job_id\": \"JOB-5KM1A\",\n      \"courier_name\": \"Couriers Please\",\n      \"tracking_number\": \"CP99001122334455\",\n      \"tracking_url\": \"https://app.shippit.com/tracking/CP99001122334455\",\n      \"service_level\": \"express\",\n      \"shipping_price\": 18.9,\n      \"number_of_parcels\": 1,\n      \"despatched_at\": \"2026-06-29T23:41:00+00:00\",\n      \"delivered_at\": \"2026-07-01T04:12:00+00:00\",\n      \"external_url\": \"https://app.staging.shippit.com/orders/SPT-AU-88210012\",\n      \"sku_sales_order_fulfillment_id\": null,\n      \"link_type_label\": null,\n      \"link_id\": null,\n      \"link_reference\": null,\n      \"link_route\": null,\n      \"created_at\": \"2026-06-29T23:41:03+00:00\",\n      \"updated_at\": \"2026-07-01T04:12:07+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 10,\n  \"total\": 27,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"Sync Shipments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background (tracked) job that reconciles despatch and delivery timestamps for the instance's undelivered shipments against the provider's current tracking state. Poll the returned tracked_job_log_id for progress.\n\nBody parameters (all optional — send an empty body to sweep every undelivered shipment):\n- since (date) — only reconcile shipments observed on/after this date.\n- date_from (date) — lower bound on the reconcile window.\n- date_to (date) — upper bound on the reconcile window; must be on or after date_from.\n- tracking_number (string, max 255) — restrict the sweep to a single consignment.\n\nAuthenticate with a Bearer token.","body":{"mode":"raw","raw":"{\n  \"since\": \"2026-06-01\",\n  \"date_from\": \"2026-06-01\",\n  \"date_to\": \"2026-06-30\",\n  \"tracking_number\": \"AP4H2388922102000935105\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90211\n  },\n  \"message\": \"Shipment sync started — track progress in the job tray.\"\n}"}]},{"name":"Get Shipment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments",":shipment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"shipment","value":"4821","description":"The shipment id."}]},"description":"Retrieve a single shipment scoped to the instance. Returns 404 if the shipment does not exist or belongs to another instance. Pass include_json=1 to include the stored provider tracking payload.\n\nAuthenticate with a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/shipments/{shipment}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","shipments",":shipment"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"shipment","value":"4821","description":"The shipment id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 4821,\n    \"shippit_order_id\": 3310,\n    \"order_tracking_number\": \"SPT-AU-88213345\",\n    \"courier_job_id\": \"JOB-7GQ2K\",\n    \"courier_name\": \"Australia Post\",\n    \"tracking_number\": \"AP4H2388922102000935105\",\n    \"tracking_url\": \"https://app.shippit.com/tracking/AP4H2388922102000935105\",\n    \"service_level\": \"standard\",\n    \"shipping_price\": 12.45,\n    \"number_of_parcels\": 2,\n    \"despatched_at\": \"2026-06-30T02:14:00+00:00\",\n    \"delivered_at\": null,\n    \"external_url\": \"https://app.staging.shippit.com/orders/SPT-AU-88213345\",\n    \"sku_sales_order_fulfillment_id\": 256917,\n    \"link_type_label\": \"Sales Order Fulfillment\",\n    \"link_id\": 256917,\n    \"link_reference\": \"F-256917\",\n    \"link_route\": \"/orders/sales-orders/fulfillments/256917\",\n    \"json_object\": {\n      \"last_tracking\": {\n        \"status\": \"in_transit\",\n        \"status_owner\": \"AusPost\",\n        \"latest_estimated_delivery_date\": \"2026-07-02\",\n        \"tracking\": [\n          {\n            \"status\": \"order_placed\",\n            \"date\": \"2026-06-30T02:14:00+00:00\"\n          },\n          {\n            \"status\": \"in_transit\",\n            \"date\": \"2026-06-30T09:50:00+00:00\"\n          }\n        ]\n      }\n    },\n    \"created_at\": \"2026-06-30T02:14:05+00:00\",\n    \"updated_at\": \"2026-06-30T02:14:05+00:00\"\n  }\n}"}]},{"name":"List Couriers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"List couriers for the shipping-provider instance, paginated. Each row is one courier type + service-level combination the merchant offers, with its enabled state and an optional mapping to an internal shipping method (sku_shipping_method_id / shipping_method_name). Unmapped couriers have null link fields.\n\nSort field. Prefix with - for descending. Allowed: id, courier_type, service_level, courier_name, enabled, created_at. Default: courier_name (A–Z).\n\nAuthenticate with a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 55,\n      \"integration_instance_id\": 6,\n      \"courier_type\": \"AusPost\",\n      \"service_level\": \"standard\",\n      \"courier_name\": \"Australia Post\",\n      \"enabled\": true,\n      \"sku_shipping_method_id\": 12,\n      \"shipping_method_name\": \"Standard Shipping\",\n      \"link_type_label\": \"Shipping Method\",\n      \"link_id\": 12,\n      \"link_reference\": \"Standard Shipping\",\n      \"created_at\": \"2026-06-10T08:00:00+00:00\",\n      \"updated_at\": \"2026-06-28T15:30:00+00:00\"\n    },\n    {\n      \"id\": 56,\n      \"integration_instance_id\": 6,\n      \"courier_type\": \"CouriersPlease\",\n      \"service_level\": \"express\",\n      \"courier_name\": \"Couriers Please\",\n      \"enabled\": true,\n      \"sku_shipping_method_id\": null,\n      \"shipping_method_name\": null,\n      \"link_type_label\": null,\n      \"link_id\": null,\n      \"link_reference\": null,\n      \"created_at\": \"2026-06-10T08:00:00+00:00\",\n      \"updated_at\": \"2026-06-10T08:00:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 8,\n  \"from\": 1,\n  \"to\": 8\n}"}]},{"name":"Sync Couriers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Queue a background (tracked) job that discovers the couriers and service levels available to the merchant and upserts them for the instance. Takes no request body. Poll the returned tracked_job_log_id for progress.\n\nAuthenticate with a Bearer token.","body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/sync","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers","sync"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 90233\n  },\n  \"message\": \"Courier sync started — track progress in the job tray.\"\n}"}]},{"name":"Get Courier","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/{courier}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers",":courier"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"courier","value":"55","description":"The courier id."}]},"description":"Retrieve a single courier scoped to the instance, including its mapping to an internal shipping method (if any). Returns 404 if the courier does not exist or belongs to another instance.\n\nAuthenticate with a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/{courier}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers",":courier"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"courier","value":"55","description":"The courier id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"integration_instance_id\": 6,\n    \"courier_type\": \"AusPost\",\n    \"service_level\": \"standard\",\n    \"courier_name\": \"Australia Post\",\n    \"enabled\": true,\n    \"sku_shipping_method_id\": 12,\n    \"shipping_method_name\": \"Standard Shipping\",\n    \"link_type_label\": \"Shipping Method\",\n    \"link_id\": 12,\n    \"link_reference\": \"Standard Shipping\",\n    \"created_at\": \"2026-06-10T08:00:00+00:00\",\n    \"updated_at\": \"2026-06-28T15:30:00+00:00\"\n  }\n}"}]},{"name":"Map Courier To Shipping Method","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/{courier}/link","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers",":courier","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"courier","value":"55","description":"The courier id to map."}]},"description":"Map a courier (its courier type / service level) to an internal shipping method so the dispatcher knows which courier to request when submitting an order. Send shipping_method_id as null (or omit it) to remove an existing mapping. Returns the updated courier.\n\nBody parameters:\n- shipping_method_id (integer, nullable) — the internal shipping method id to map to. Must reference an existing shipping method. Null or omitted unlinks the courier.\n\nReturns 404 when the courier cannot be found, and 422 when shipping_method_id does not reference an existing shipping method.\n\nAuthenticate with a Bearer token.","body":{"mode":"raw","raw":"{\n  \"shipping_method_id\": 12\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/couriers/{courier}/link","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","couriers",":courier","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"courier","value":"55","description":"The courier id to map."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"integration_instance_id\": 6,\n    \"courier_type\": \"AusPost\",\n    \"service_level\": \"standard\",\n    \"courier_name\": \"Australia Post\",\n    \"enabled\": true,\n    \"sku_shipping_method_id\": 12,\n    \"shipping_method_name\": \"Standard Shipping\",\n    \"link_type_label\": \"Shipping Method\",\n    \"link_id\": 12,\n    \"link_reference\": \"Standard Shipping\",\n    \"created_at\": \"2026-06-10T08:00:00+00:00\",\n    \"updated_at\": \"2026-06-28T15:30:00+00:00\"\n  }\n}"}]},{"name":"List Warehouse Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a paginated list of warehouse-to-sender mappings for this Shippit instance, newest first. Each mapping links one of your warehouses to the Shippit sender (pickup origin) details used when despatching from it.\n\nSortable columns: `id`, `sku_warehouse_id`, `sender_name`, `enabled`, `created_at` (default `-id`). Default page size is 10.\n\nFiltering uses operator-aware syntax `filter[field.operator]=value`; a bare `filter[field]=value` means equals. `filter[search]` matches the sender name and the linked warehouse name.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 51,\n      \"integration_instance_id\": 2,\n      \"enabled\": true,\n      \"sender_name\": \"Main Distribution Center\",\n      \"sender_address\": {\n        \"line1\": \"12 Warehouse Road\",\n        \"line2\": \"Unit 4\",\n        \"suburb\": \"Botany\",\n        \"state\": \"NSW\",\n        \"postcode\": \"2019\",\n        \"country_code\": \"AU\"\n      },\n      \"sku_warehouse_id\": 42,\n      \"warehouse_name\": \"Sydney Main\",\n      \"link_type_label\": \"Warehouse\",\n      \"link_id\": 42,\n      \"link_reference\": \"Sydney Main\",\n      \"link_route\": \"/crm/warehouses/42\",\n      \"created_at\": \"2026-06-14T09:22:41+00:00\",\n      \"updated_at\": \"2026-07-05T18:03:12+00:00\"\n    },\n    {\n      \"id\": 48,\n      \"integration_instance_id\": 2,\n      \"enabled\": false,\n      \"sender_name\": \"Melbourne Overflow\",\n      \"sender_address\": {\n        \"line1\": \"88 Logistics Way\",\n        \"suburb\": \"Tullamarine\",\n        \"state\": \"VIC\",\n        \"postcode\": \"3043\",\n        \"country_code\": \"AU\"\n      },\n      \"sku_warehouse_id\": 39,\n      \"warehouse_name\": \"Melbourne DC\",\n      \"link_type_label\": \"Warehouse\",\n      \"link_id\": 39,\n      \"link_reference\": \"Melbourne DC\",\n      \"link_route\": \"/crm/warehouses/39\",\n      \"created_at\": \"2026-05-30T11:10:05+00:00\",\n      \"updated_at\": \"2026-06-28T14:41:33+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/shippit/instances/2/warehouses?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://example.sku.io/api/shippit/instances/2/warehouses?page=1\",\n  \"next_page_url\": null,\n  \"path\": \"https://example.sku.io/api/shippit/instances/2/warehouses\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Map Warehouse","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/link","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Links one of your warehouses to Shippit sender (pickup origin) details so despatches from that warehouse originate from the correct address. Idempotent upsert on the (instance, warehouse) pair: calling it again for an already-linked warehouse updates its sender details in place rather than creating a duplicate.\n\nRequest fields:\n- `sku_warehouse_id` (required, integer) — the id of the warehouse to link; must reference an existing warehouse.\n- `enabled` (optional, boolean) — whether the mapping is active; defaults to `true`.\n- `sender_name` (optional, string, max 255) — display name for the sender/pickup origin.\n- `sender_address` (optional, object) — free-form address object stored verbatim as the pickup origin override.\n\nReturns `201 Created` with the resulting mapping. Returns `422` when validation fails (e.g. missing or unknown warehouse).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sku_warehouse_id\": 42,\n  \"enabled\": true,\n  \"sender_name\": \"Main Distribution Center\",\n  \"sender_address\": {\n    \"line1\": \"12 Warehouse Road\",\n    \"line2\": \"Unit 4\",\n    \"suburb\": \"Botany\",\n    \"state\": \"NSW\",\n    \"postcode\": \"2019\",\n    \"country_code\": \"AU\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/link","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses","link"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 51,\n    \"integration_instance_id\": 2,\n    \"enabled\": true,\n    \"sender_name\": \"Main Distribution Center\",\n    \"sender_address\": {\n      \"line1\": \"12 Warehouse Road\",\n      \"line2\": \"Unit 4\",\n      \"suburb\": \"Botany\",\n      \"state\": \"NSW\",\n      \"postcode\": \"2019\",\n      \"country_code\": \"AU\"\n    },\n    \"sku_warehouse_id\": 42,\n    \"warehouse_name\": \"Sydney Main\",\n    \"link_type_label\": \"Warehouse\",\n    \"link_id\": 42,\n    \"link_reference\": \"Sydney Main\",\n    \"link_route\": \"/crm/warehouses/42\",\n    \"created_at\": \"2026-06-14T09:22:41+00:00\",\n    \"updated_at\": \"2026-07-05T18:03:12+00:00\"\n  }\n}"}]},{"name":"Unmap Warehouse","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/{mapping}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses",":mapping"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"mapping","value":"51","description":"The warehouse mapping id to remove."}]},"description":"Removes a warehouse-to-sender mapping. Despatches from that warehouse will no longer use the stored sender override.\n\nReturns `204 No Content` on success. Returns `404` when the mapping does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/{mapping}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses",":mapping"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"mapping","value":"51","description":"The warehouse mapping id to remove."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"Toggle Warehouse Mapping","request":{"method":"PATCH","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/{mapping}/toggle","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses",":mapping","toggle"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"mapping","value":"51","description":"The warehouse mapping id to toggle."}]},"description":"Flips a mapping's enabled flag: an enabled mapping becomes disabled and vice versa. Disabled mappings are retained but no longer supply sender details for despatch.\n\nNo request body is required. Returns `200 OK` with the updated mapping (note the flipped `enabled` value). Returns `404` when the mapping does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/warehouses/{mapping}/toggle","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","warehouses",":mapping","toggle"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"mapping","value":"51","description":"The warehouse mapping id to toggle."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 51,\n    \"integration_instance_id\": 2,\n    \"enabled\": false,\n    \"sender_name\": \"Main Distribution Center\",\n    \"sender_address\": {\n      \"line1\": \"12 Warehouse Road\",\n      \"line2\": \"Unit 4\",\n      \"suburb\": \"Botany\",\n      \"state\": \"NSW\",\n      \"postcode\": \"2019\",\n      \"country_code\": \"AU\"\n    },\n    \"sku_warehouse_id\": 42,\n    \"warehouse_name\": \"Sydney Main\",\n    \"link_type_label\": \"Warehouse\",\n    \"link_id\": 42,\n    \"link_reference\": \"Sydney Main\",\n    \"link_route\": \"/crm/warehouses/42\",\n    \"created_at\": \"2026-06-14T09:22:41+00:00\",\n    \"updated_at\": \"2026-07-05T18:03:12+00:00\"\n  }\n}"}]},{"name":"Subscribe Webhook","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/subscribe","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks","subscribe"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Register this instance's inbound webhook URL with Shippit via the merchant API (PUT /merchant), so despatch and delivery events are delivered without pasting the URL into the Shippit dashboard. Runs automatically on connect; this endpoint re-registers it.\n\nAuthentication: Requires Bearer token. No request body.\n\nReturns 200 with the subscription timestamp, or 422 {code: invalid_key|api_error} if Shippit rejects the call."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/subscribe","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks","subscribe"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook registered with Shippit.\",\n  \"webhook_subscribed_at\": \"2026-07-08T21:31:36+00:00\"\n}"}]},{"name":"Unsubscribe Webhook","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/subscribe","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks","subscribe"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Clear this instance's webhook URL at Shippit (PUT /merchant with null), stopping inbound events.\n\nAuthentication: Requires Bearer token. No request body.\n\nReturns 200, or 422 {code: invalid_key|api_error} on failure."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/subscribe","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks","subscribe"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook cleared at Shippit.\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a paginated list of inbound webhook events received from Shippit for this instance, newest first. Every inbound webhook is persisted so you can audit and inspect deliveries; each row records the event type, tracking number, courier job id, the dedup key, the raw payload, and whether it has been processed yet (`processed` / `processed_at`).\n\nSortable columns: `id`, `event_type`, `tracking_number`, `received_at`, `processed_at`, `created_at` (default `-received_at`). Default page size is 15.\n\nFiltering uses operator-aware syntax `filter[field.operator]=value`; a bare `filter[field]=value` means equals. Available filters: `id`, `event_type`, `tracking_number`, `courier_job_id`, `dedup_key`, `processed` (1 = processed, 0 = pending, all = no filter), `received_at`, `processed_at`, `created_at`. `filter[search]` matches tracking number, event type, courier job id, and dedup key.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9011,\n      \"integration_instance_id\": 2,\n      \"event_type\": \"order.status.updated\",\n      \"tracking_number\": \"AUP0091234567\",\n      \"courier_job_id\": \"JOB-88231\",\n      \"dedup_key\": \"2:order.status.updated:JOB-88231:delivered\",\n      \"payload\": {\n        \"tracking_number\": \"AUP0091234567\",\n        \"courier_job_id\": \"JOB-88231\",\n        \"status\": \"delivered\",\n        \"courier_name\": \"Australia Post\",\n        \"updated_at\": \"2026-07-05T08:00:59+10:00\"\n      },\n      \"processed\": true,\n      \"processed_at\": \"2026-07-05T08:01:11+00:00\",\n      \"received_at\": \"2026-07-05T08:01:09+00:00\",\n      \"created_at\": \"2026-07-05T08:01:09+00:00\"\n    },\n    {\n      \"id\": 9008,\n      \"integration_instance_id\": 2,\n      \"event_type\": \"order.status.updated\",\n      \"tracking_number\": \"AUP0099887766\",\n      \"courier_job_id\": \"JOB-88117\",\n      \"dedup_key\": \"2:order.status.updated:JOB-88117:in_transit\",\n      \"payload\": {\n        \"tracking_number\": \"AUP0099887766\",\n        \"courier_job_id\": \"JOB-88117\",\n        \"status\": \"in_transit\",\n        \"courier_name\": \"Couriers Please\"\n      },\n      \"processed\": false,\n      \"processed_at\": null,\n      \"received_at\": \"2026-07-04T21:14:33+00:00\",\n      \"created_at\": \"2026-07-04T21:14:33+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/shippit/instances/2/webhooks?page=1\",\n  \"from\": 1,\n  \"last_page\": 34,\n  \"last_page_url\": \"https://example.sku.io/api/shippit/instances/2/webhooks?page=34\",\n  \"next_page_url\": \"https://example.sku.io/api/shippit/instances/2/webhooks?page=2\",\n  \"path\": \"https://example.sku.io/api/shippit/instances/2/webhooks\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 502\n}"}]},{"name":"Get Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/{webhookEvent}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks",":webhookEvent"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhookEvent","value":"9011","description":"The webhook event id."}]},"description":"Returns a single webhook event received from Shippit, including its full raw `payload`. `processed_at` (and the `processed` flag) reflect whether the ingest pipeline has already handled the event.\n\nReturns `404` when the event does not exist or belongs to a different integration instance.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/webhooks/{webhookEvent}","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","webhooks",":webhookEvent"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."},{"key":"webhookEvent","value":"9011","description":"The webhook event id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 9011,\n    \"integration_instance_id\": 2,\n    \"event_type\": \"order.status.updated\",\n    \"tracking_number\": \"AUP0091234567\",\n    \"courier_job_id\": \"JOB-88231\",\n    \"dedup_key\": \"2:order.status.updated:JOB-88231:delivered\",\n    \"payload\": {\n      \"tracking_number\": \"AUP0091234567\",\n      \"courier_job_id\": \"JOB-88231\",\n      \"status\": \"delivered\",\n      \"courier_name\": \"Australia Post\",\n      \"updated_at\": \"2026-07-05T08:00:59+10:00\"\n    },\n    \"processed\": true,\n    \"processed_at\": \"2026-07-05T08:01:11+00:00\",\n    \"received_at\": \"2026-07-05T08:01:09+00:00\",\n    \"created_at\": \"2026-07-05T08:01:09+00:00\"\n  }\n}"}]},{"name":"List Activity","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/activity","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","activity"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]},"description":"Returns a paginated activity feed for this Shippit instance, newest first — the audit trail of actions taken across the integration (connect, settings update, disconnect, syncs, order submit/book/cancel, warehouse link/unlink, etc.). Each entry carries the acting user (`causer`, `null` for system-generated entries), a human description, and a `properties` bag of contextual data.\n\nSortable columns: `created_at`, `event`, `id` (default `-created_at`, tie-broken by `-id`). Default page size is 15.\n\nFiltering: `filter[search]` matches the description; `filter[event]` / `filter[description]` are operator-aware text filters; `filter[event_type]` and `filter[causer_id]` accept comma-separated lists; `filter[created_at.*]` supports datetime operators.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/shippit/instances/{integration_instance}/activity","host":["{{baseUrl}}"],"path":["api","shippit","instances",":integration_instance","activity"],"variable":[{"key":"integration_instance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 14032,\n      \"event\": \"warehouse_linked\",\n      \"description\": \"Linked warehouse #42 to Shippit\",\n      \"causer\": {\n        \"id\": 7,\n        \"name\": \"Dana Ops\",\n        \"email\": \"dana@example.com\"\n      },\n      \"properties\": {\n        \"integration_instance_id\": 2,\n        \"shippit_warehouse_mapping_id\": 51,\n        \"sku_warehouse_id\": 42\n      },\n      \"created_at\": \"2026-07-05T18:03:12+00:00\",\n      \"occurred_at_human\": \"2 days ago\"\n    },\n    {\n      \"id\": 14020,\n      \"event\": \"orders_synced\",\n      \"description\": \"Synced 37 orders from Shippit\",\n      \"causer\": null,\n      \"properties\": {\n        \"integration_instance_id\": 2,\n        \"synced_count\": 37\n      },\n      \"created_at\": \"2026-07-05T06:00:04+00:00\",\n      \"occurred_at_human\": \"3 days ago\"\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://example.sku.io/api/shippit/instances/2/activity?page=1\",\n  \"from\": 1,\n  \"last_page\": 9,\n  \"last_page_url\": \"https://example.sku.io/api/shippit/instances/2/activity?page=9\",\n  \"next_page_url\": \"https://example.sku.io/api/shippit/instances/2/activity?page=2\",\n  \"path\": \"https://example.sku.io/api/shippit/instances/2/activity\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 15,\n  \"total\": 128\n}"}]}]},{"name":"QuickBooks Online","item":[{"name":"List Integrations","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/integrations","host":["{{baseUrl}}"],"path":["api","qbo","integrations"]},"description":"Returns all QBO integration instances with connection status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/integrations","host":["{{baseUrl}}"],"path":["api","qbo","integrations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My Company\",\n      \"realm_id\": \"123456789\",\n      \"environment\": \"production\",\n      \"is_authenticated\": true,\n      \"is_auto_sync_enabled\": true,\n      \"sync_due_dates\": true,\n      \"connection_status\": \"connected\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Initialize OAuth","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/integrations/initialize","host":["{{baseUrl}}"],"path":["api","qbo","integrations","initialize"]},"description":"Generates a QBO OAuth authorization URL. Works for both initial setup and reconnection.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nOptional `environment` (`sandbox` | `production`) selects which QuickBooks environment to connect to. It is honoured only on non-production servers (production always connects to production) and defaults to `sandbox` when omitted. For a reconnect the existing connection's environment is reused. The environment is fixed once connected - to switch, disconnect and reconnect.","body":{"mode":"raw","raw":"{\n  \"environment\": \"sandbox\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/integrations/initialize","host":["{{baseUrl}}"],"path":["api","qbo","integrations","initialize"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"state\": \"42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\",\n    \"authorization_url\": \"https://appcenter.intuit.com/connect/oauth2?client_id=...&scope=com.intuit.quickbooks.accounting&redirect_uri=https%3A%2F%2Fapp.sku.io%2Fqbo%2Fcallback&response_type=code&access_type=offline&state=42_4f1a9b2e-37c5-4d8a-9b1f-7c4e9d2a5b18\",\n    \"is_reconnect\": false,\n    \"environment\": \"sandbox\",\n    \"instructions\": [\n      \"1. Visit the authorization_url in your browser\"\n    ]\n  }\n}"}]},{"name":"Complete OAuth Setup","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/integrations/complete","host":["{{baseUrl}}"],"path":["api","qbo","integrations","complete"]},"description":"Completes new QBO integration setup using the OAuth state. Only for new integrations (reconnections are handled automatically via callback).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Deprecation note:** the `is_auto_sync_enabled` field uses legacy naming — it sets the coarse sync-schedule flag, which is slated for rename to `sync_schedule_active`. The field is kept for backward compatibility.","body":{"mode":"raw","raw":"{\n  \"state\": \"abc123\",\n  \"is_auto_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/integrations/complete","host":["{{baseUrl}}"],"path":["api","qbo","integrations","complete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"integration_instance_id\": 1,\n    \"name\": \"My Company\",\n    \"realm_id\": \"123456789\",\n    \"environment\": \"production\",\n    \"is_authenticated\": true,\n    \"is_auto_sync_enabled\": true,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Test Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/integrations/test-connection","host":["{{baseUrl}}"],"path":["api","qbo","integrations","test-connection"]},"description":"Tests the QBO API connection by making a CompanyInfo API call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/integrations/test-connection","host":["{{baseUrl}}"],"path":["api","qbo","integrations","test-connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"company_name\": \"My Company\",\n    \"realm_id\": \"123456789\"\n  }\n}"}]},{"name":"Update Integration Settings","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/integrations/{id}","host":["{{baseUrl}}"],"path":["api","qbo","integrations",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Updates settings for a QBO integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"is_automatic_sync_enabled\": true,\n  \"name\": \"My Company QBO\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/qbo/integrations/{id}","host":["{{baseUrl}}"],"path":["api","qbo","integrations",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Settings updated successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"My Company QBO\",\n    \"realm_id\": \"123456789\",\n    \"environment\": \"production\",\n    \"is_authenticated\": true,\n    \"is_auto_sync_enabled\": true,\n    \"sync_due_dates\": true,\n    \"connection_status\": \"connected\",\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-01T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Integration","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/integrations/{id}","host":["{{baseUrl}}"],"path":["api","qbo","integrations",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Queues deletion of a QBO integration instance and all associated data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/qbo/integrations/{id}","host":["{{baseUrl}}"],"path":["api","qbo","integrations",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO integration instance deletion has been queued\",\n  \"data\": {\n    \"instance_id\": 1,\n    \"status\": \"deletion_queued\"\n  }\n}"}]},{"name":"Get Dashboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/dashboard","host":["{{baseUrl}}"],"path":["api","qbo","dashboard"]},"description":"Returns comprehensive dashboard metrics including entity counts, sync status, and connection health.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/dashboard","host":["{{baseUrl}}"],"path":["api","qbo","dashboard"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"connection\": {\n      \"status\": \"connected\",\n      \"realm_id\": \"123456789\"\n    },\n    \"entity_counts\": {\n      \"accounts\": 150,\n      \"invoices\": 500,\n      \"customers\": 200\n    },\n    \"sync_status\": {\n      \"last_sync_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  }\n}"}]},{"name":"List Accounts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","accounts"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO accounts with filtering and sorting. Defaults to active accounts only.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, name, acct_num, fully_qualified_name, account_sub_type."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/accounts?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","accounts"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"qbo_id\": \"1\",\n      \"name\": \"Checking\",\n      \"account_type\": \"Bank\",\n      \"account_sub_type\": \"Checking\",\n      \"acct_num\": \"1000\",\n      \"classification\": \"Asset\",\n      \"active\": true,\n      \"sync_status\": \"synced\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Delete Accounts","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts","host":["{{baseUrl}}"],"path":["api","qbo","accounts"]},"description":"Delete one or more QBO accounts by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/qbo/accounts","host":["{{baseUrl}}"],"path":["api","qbo","accounts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully deleted 3 QBO accounts(s)\",\n  \"data\": {\n    \"deleted_count\": 3\n  }\n}"}]},{"name":"Get Account","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/{id}","host":["{{baseUrl}}"],"path":["api","qbo","accounts",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO account by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/accounts/{id}","host":["{{baseUrl}}"],"path":["api","qbo","accounts",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1,\n    \"qbo_id\": \"1\",\n    \"name\": \"Checking\",\n    \"account_type\": \"Bank\",\n    \"classification\": \"Asset\",\n    \"active\": true\n  }\n}"}]},{"name":"Refresh Accounts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh"]},"description":"Syncs accounts from QBO API. Omit body for incremental sync, pass full_sync=true for complete resync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"start_date\": \"01/01/2024\",\n  \"end_date\": \"12/31/2024\",\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO accounts refresh completed successfully\",\n  \"data\": {\n    \"created\": 5,\n    \"updated\": 10,\n    \"sync_type\": \"date_range\"\n  }\n}"}]},{"name":"Refresh Accounts in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh-tracked"]},"description":"Starts a background refresh of accounts from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO accounts refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Accounts Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","accounts","sync-info"]},"description":"Returns the latest synced account identifier and timestamp, the total number of accounts already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/accounts/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","accounts","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Accounts in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","accounts","search-qbo"]},"description":"Searches QuickBooks directly for accounts matching a field/value (without importing them). `field` must be one of the values returned by Get Accounts Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","accounts","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Account from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh-single"]},"description":"Fetches a single account from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","accounts","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO account pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Accounts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","accounts","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export accounts to CSV. Supports date range filtering.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Account Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/statistics","host":["{{baseUrl}}"],"path":["api","qbo","accounts","statistics"]},"description":"Get aggregate statistics for QBO accounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/accounts/statistics","host":["{{baseUrl}}"],"path":["api","qbo","accounts","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 150,\n    \"active\": 140,\n    \"archived\": 10,\n    \"by_type\": {\n      \"Bank\": 20,\n      \"Accounts Receivable\": 5\n    }\n  }\n}"}]},{"name":"Archive Accounts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/archive","host":["{{baseUrl}}"],"path":["api","qbo","accounts","archive"]},"description":"Archive one or more QBO accounts by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/archive","host":["{{baseUrl}}"],"path":["api","qbo","accounts","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully archived 3 QBO accounts(s)\",\n  \"data\": {\n    \"archived_count\": 3\n  }\n}"}]},{"name":"Unarchive Accounts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","accounts","unarchive"]},"description":"Unarchive one or more QBO accounts by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","accounts","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO accounts(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"Create Nominal Codes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/nominal-codes","host":["{{baseUrl}}"],"path":["api","qbo","accounts","nominal-codes"]},"description":"Creates SKU nominal codes from selected QBO accounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"account_ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/nominal-codes","host":["{{baseUrl}}"],"path":["api","qbo","accounts","nominal-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Nominal codes created successfully. Created 3, skipped 0 existing.\",\n  \"data\": {\n    \"created\": 3,\n    \"existing\": 0\n  }\n}"}]},{"name":"Adopt QuickBooks Chart of Accounts (hard-replace)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/adopt-chart","host":["{{baseUrl}}"],"path":["api","qbo","accounts","adopt-chart"]},"description":"Onboarding: hard-replace SKU's chart of accounts with QuickBooks's. Imports every mapped QBO account as a nominal code (code = AcctNum or QBO id, type mapped from the QBO account type), re-points every reference (sales order lines, settings roles, product/channel/warehouse overrides, …) onto the replacements, then deletes the old chart. EVERY existing nominal code must appear in `mappings` (a complete old→new map is what makes the delete safe) — otherwise the job fails listing the unmapped ids. Requires a connected QuickBooks accounting integration (404 otherwise). Runs as a tracked job; returns its log id so the UI can follow progress via the tracked job log endpoints. Pass `repost: true` to also repost every current ledger entry after the replace (chained inside the job) so posted GL lines pick up the new accounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:** `mappings[]` (required) — each `{ nominal_code_id, qbo_account_id }`. `repost` (optional bool).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"nominal_code_id\": 12,\n      \"qbo_account_id\": 5\n    },\n    {\n      \"nominal_code_id\": 7,\n      \"qbo_account_id\": 9\n    }\n  ],\n  \"repost\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/accounts/adopt-chart","host":["{{baseUrl}}"],"path":["api","qbo","accounts","adopt-chart"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  },\n  \"message\": \"Adopting the QuickBooks chart of accounts — track progress in the job tray.\"\n}"}]},{"name":"Get Account Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/accounts/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","accounts",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online account. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the account does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/accounts/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","accounts",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboAccount\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"ok\"\n        },\n        \"old\": {\n          \"sync_status\": \"sku_updated_pending_sync\"\n        },\n        \"metadata\": {\n          \"id\": 87,\n          \"name\": \"Inventory Asset\",\n          \"qbo_id\": \"55\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"…?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"…?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"…/api/qbo/accounts/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","bills"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO bills with filtering and sorting.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, vendor_name."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bills?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","bills"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"qbo_id\": \"1\",\n      \"doc_number\": \"BILL-001\",\n      \"total_amount\": \"500.00\",\n      \"sync_status\": \"synced\",\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/bill?txnId=201\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 1\n}"}]},{"name":"Delete Bills","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills","host":["{{baseUrl}}"],"path":["api","qbo","bills"]},"description":"Delete one or more QBO bills.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Bill","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills/{id}","host":["{{baseUrl}}"],"path":["api","qbo","bills",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO bill by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `vendor_link_id` cross-links to the mirrored QuickBooks vendor. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bills/{id}","host":["{{baseUrl}}"],"path":["api","qbo","bills",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 61,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"201\",\n    \"doc_number\": \"BILL-8114\",\n    \"name\": \"BILL-8114\",\n    \"vendor_id\": \"56\",\n    \"vendor_name\": \"Shanghai Supplier Co\",\n    \"total_amount\": \"1250.00\",\n    \"currency\": \"USD\",\n    \"due_date\": \"2026-08-15\",\n    \"txn_date\": \"2026-07-05\",\n    \"status\": \"Open\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/bill?txnId=201\",\n    \"vendor_link_id\": 57,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Cold-chain freight\",\n        \"detail_type\": \"AccountBasedExpenseLineDetail\",\n        \"item\": null,\n        \"item_id\": null,\n        \"item_link_id\": null,\n        \"account\": \"Shipping & Freight\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"amount\": 125,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"201\",\n      \"DocNumber\": \"BILL-8114\",\n      \"TxnDate\": \"2026-07-05\",\n      \"TotalAmt\": 1250,\n      \"VendorRef\": {\n        \"value\": \"56\",\n        \"name\": \"Shanghai Supplier Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"Amount\": 125,\n          \"DetailType\": \"AccountBasedExpenseLineDetail\",\n          \"Description\": \"Cold-chain freight\",\n          \"AccountBasedExpenseLineDetail\": {\n            \"AccountRef\": {\n              \"value\": \"63\",\n              \"name\": \"Shipping & Freight\"\n            }\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Refresh Bills","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/refresh","host":["{{baseUrl}}"],"path":["api","qbo","bills","refresh"]},"description":"Syncs bills from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Bills in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","bills","refresh-tracked"]},"description":"Starts a background refresh of bills from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/bills/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","bills","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO bills refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Bills Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","bills","sync-info"]},"description":"Returns the latest synced bill identifier and timestamp, the total number of bills already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bills/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","bills","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Bills in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","bills","search-qbo"]},"description":"Searches QuickBooks directly for bills matching a field/value (without importing them). `field` must be one of the values returned by Get Bills Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/bills/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","bills","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Bill from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","bills","refresh-single"]},"description":"Fetches a single bill from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/bills/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","bills","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO bill pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Bills","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","bills","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export bills to CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Bill Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills/statistics","host":["{{baseUrl}}"],"path":["api","qbo","bills","statistics"]},"description":"Get aggregate statistics for QBO bills.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Bills","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/archive","host":["{{baseUrl}}"],"path":["api","qbo","bills","archive"]},"description":"Archive one or more QBO bills.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unarchive Bills","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/bills/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","bills","unarchive"]},"description":"Unarchive one or more QBO bills.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Bill Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bills/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","bills",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online bill. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the bill does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bills/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","bills",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboBill\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/bills/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/bills/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/bills/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/bills/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Credit Memos","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO credit memos.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, customer_name."}},{"name":"Delete Credit Memos","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos"]},"description":"Delete one or more QBO credit memos.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Credit Memo","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/{id}","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO credit memo by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `customer_link_id` and `sku_customer_id` cross-link to the mirrored QuickBooks customer and its linked SKU customer. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/{id}","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 44,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"305\",\n    \"doc_number\": \"CN-8231\",\n    \"name\": \"CN-8231\",\n    \"customer_id\": \"12\",\n    \"customer_name\": \"Bar Supply Co\",\n    \"total_amount\": \"99.00\",\n    \"currency\": \"USD\",\n    \"txn_date\": \"2026-07-03\",\n    \"status\": \"Open\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/creditmemo?txnId=305\",\n    \"customer_link_id\": 88,\n    \"sku_customer_id\": 1420,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"305\",\n      \"DocNumber\": \"CN-8231\",\n      \"TxnDate\": \"2026-07-03\",\n      \"TotalAmt\": 99,\n      \"CustomerRef\": {\n        \"value\": \"12\",\n        \"name\": \"Bar Supply Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Refresh Credit Memos","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/refresh","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","refresh"]},"description":"Syncs credit memos from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Credit Memos in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","refresh-tracked"]},"description":"Starts a background refresh of credit memos from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO credit-memos refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Credit Memos Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","sync-info"]},"description":"Returns the latest synced credit memo identifier and timestamp, the total number of credit memos already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Credit Memos in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","search-qbo"]},"description":"Searches QuickBooks directly for credit memos matching a field/value (without importing them). `field` must be one of the values returned by Get Credit Memos Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Credit Memo from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","refresh-single"]},"description":"Fetches a single credit memo from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO credit memo pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Credit Memos","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export credit memos to CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Credit Memo Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/statistics","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","statistics"]},"description":"Get aggregate statistics for QBO credit memos.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Credit Memos","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/archive","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","archive"]},"description":"Archive one or more QBO credit memos.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unarchive Credit Memos","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos","unarchive"]},"description":"Unarchive one or more QBO credit memos.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Credit Memo Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online credit memo. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the credit memo does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/credit-memos/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","credit-memos",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboCreditMemo\",\n      \"subject_id\": 42,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/credit-memos/42/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/credit-memos/42/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/credit-memos/42/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/credit-memos/42/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","customers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO customers. Filter by linked=true/false to see SKU-linked customers.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, display_name, company_name, given_name, family_name, email."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","customers"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"qbo_id\": \"1\",\n      \"display_name\": \"John Doe\",\n      \"company_name\": \"ACME Corp\",\n      \"email\": \"john@acme.com\",\n      \"active\": true,\n      \"sku_customer_id\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 1\n}"}]},{"name":"Delete Customers","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers","host":["{{baseUrl}}"],"path":["api","qbo","customers"]},"description":"Delete one or more QBO customers.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Customer","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/{id}","host":["{{baseUrl}}"],"path":["api","qbo","customers",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO customer by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Unlinked Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/unlinked","host":["{{baseUrl}}"],"path":["api","qbo","customers","unlinked"]},"description":"Returns QBO customers not yet linked to a SKU customer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Linked Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/linked","host":["{{baseUrl}}"],"path":["api","qbo","customers","linked"]},"description":"Returns QBO customers that are linked to a SKU customer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Create SKU Customers from QBO","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/create-sku-customers","host":["{{baseUrl}}"],"path":["api","qbo","customers","create-sku-customers"]},"description":"Bulk creates SKU customers from unlinked QBO customers. Omit ids to process all unlinked.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/create-sku-customers","host":["{{baseUrl}}"],"path":["api","qbo","customers","create-sku-customers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Created 3, linked to existing 0, failed 0.\",\n  \"created\": 3,\n  \"linked\": 0,\n  \"failed\": 0\n}"}]},{"name":"Refresh SKU Customers from QBO","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh-sku-customers","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh-sku-customers"]},"description":"Bulk refreshes linked SKU customers from their QBO counterparts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unlink SKU Customers (Bulk)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/unlink-sku-customers","host":["{{baseUrl}}"],"path":["api","qbo","customers","unlink-sku-customers"]},"description":"Bulk unlinks SKU customers from their QBO customer links.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Link SKU Customer","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/{qboCustomer}/link-sku-customer","host":["{{baseUrl}}"],"path":["api","qbo","customers",":qboCustomer","link-sku-customer"],"variable":[{"key":"qboCustomer","value":"1","description":"The qbo customer ID."}]},"description":"Links an existing SKU customer to a specific QBO customer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"sku_customer_id\": 5\n}","options":{"raw":{"language":"json"}}}}},{"name":"Unlink SKU Customer","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/{qboCustomer}/unlink-sku-customer","host":["{{baseUrl}}"],"path":["api","qbo","customers",":qboCustomer","unlink-sku-customer"],"variable":[{"key":"qboCustomer","value":"1","description":"The qbo customer ID."}]},"description":"Removes the SKU customer link from a QBO customer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Refresh Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh"]},"description":"Syncs customers from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Customers in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh-tracked"]},"description":"Starts a background refresh of customers from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO customers refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Customers Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","customers","sync-info"]},"description":"Returns the latest synced customer identifier and timestamp, the total number of customers already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","customers","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Customers in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","customers","search-qbo"]},"description":"Searches QuickBooks directly for customers matching a field/value (without importing them). `field` must be one of the values returned by Get Customers Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","customers","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Customer from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh-single"]},"description":"Fetches a single customer from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","customers","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO customer pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Customers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","customers","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export customers to CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/archive","host":["{{baseUrl}}"],"path":["api","qbo","customers","archive"]},"description":"Archive one or more QBO customers.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Customer Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/statistics","host":["{{baseUrl}}"],"path":["api","qbo","customers","statistics"]},"description":"Get aggregate counts for the QuickBooks Online customers synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers/statistics","host":["{{baseUrl}}"],"path":["api","qbo","customers","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 412,\n    \"active\": 395,\n    \"archived\": 17\n  }\n}"}]},{"name":"Merge Duplicate Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/merge","host":["{{baseUrl}}"],"path":["api","qbo","customers","merge"]},"description":"Merge one QuickBooks Online customer (the secondary) into another (the primary).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**This endpoint modifies data in QuickBooks itself and is irreversible.** QuickBooks has no native merge or unmerge, so the merge is performed by deactivating (soft-deleting) the secondary customer in QuickBooks Online. The secondary customer cannot be restored through this API afterwards.\n\nWhat happens, in order:\n1. Both customers are re-fetched from QuickBooks to obtain a fresh sync token.\n2. A snapshot of both records is stored in a merge log for auditing.\n3. If the secondary customer was linked to a SKU.io customer and the primary was not, the link is moved to the primary.\n4. The secondary customer is deactivated in QuickBooks and its local synced copy is deleted from SKU.io. (If QuickBooks reports the secondary was already deleted upstream, only the local cleanup is performed.)\n\nBoth customers must belong to the same integration instance. QuickBooks refuses to deactivate a customer with a non-zero balance or open transactions; in that case the API returns a 422 with a `qbo_customer_has_open_balance` error - resolve the balance in QuickBooks and retry.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"primary_qbo_customer_id\": 501,\n  \"secondary_qbo_customer_id\": 512\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/merge","host":["{{baseUrl}}"],"path":["api","qbo","customers","merge"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"merge_log_id\": 7\n  },\n  \"message\": \"QBO customers merged. This action cannot be undone.\"\n}"}]},{"name":"Unarchive Customers","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","customers","unarchive"]},"description":"Restore one or more archived QuickBooks Online customers by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","customers","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO customers(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"Get Customer Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","customers",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online customer. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the customer does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","customers",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboCustomer\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"ok\"\n        },\n        \"old\": {\n          \"sync_status\": \"sku_updated_pending_sync\"\n        },\n        \"metadata\": {\n          \"id\": 87,\n          \"display_name\": \"Bar Supply Co\",\n          \"qbo_id\": \"12\"\n        }\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"…?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"…?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"…/api/qbo/customers/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Invoices","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","invoices"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO invoices. Supports filtering by doc_number, customer_name, status, and sync_status.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, customer_name."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","invoices"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"qbo_id\": \"1\",\n      \"doc_number\": \"INV-001\",\n      \"customer_name\": \"ACME Corp\",\n      \"total_amount\": \"1000.00\",\n      \"status\": \"Paid\",\n      \"sync_status\": \"synced\",\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/invoice?txnId=184\"\n    }\n  ],\n  \"current_page\": 1,\n  \"total\": 1\n}"}]},{"name":"Delete Invoices","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices","host":["{{baseUrl}}"],"path":["api","qbo","invoices"]},"description":"Delete one or more QBO invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/{id}","host":["{{baseUrl}}"],"path":["api","qbo","invoices",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO invoice by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `customer_link_id` and `sku_customer_id` cross-link to the mirrored QuickBooks customer and its linked SKU customer. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices/{id}","host":["{{baseUrl}}"],"path":["api","qbo","invoices",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 87,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"184\",\n    \"doc_number\": \"INV-1042\",\n    \"name\": \"INV-1042\",\n    \"customer_id\": \"12\",\n    \"customer_name\": \"Bar Supply Co\",\n    \"total_amount\": \"842.00\",\n    \"currency\": \"USD\",\n    \"due_date\": \"2026-07-31\",\n    \"txn_date\": \"2026-07-01\",\n    \"status\": \"Open\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/invoice?txnId=184\",\n    \"customer_link_id\": 88,\n    \"sku_customer_id\": 1420,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"184\",\n      \"DocNumber\": \"INV-1042\",\n      \"TxnDate\": \"2026-07-01\",\n      \"TotalAmt\": 842,\n      \"CustomerRef\": {\n        \"value\": \"12\",\n        \"name\": \"Bar Supply Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Sync Invoices to QBO","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync"]},"description":"Syncs accounting transactions to QBO as invoices. Pass specific IDs to force-sync those transactions, or omit for auto-sync of all eligible transactions.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"accounting_transaction_ids\": [\n    101,\n    102\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Synced 2 specific transaction(s) to QuickBooks Online\",\n  \"data\": {\n    \"processed_count\": 2,\n    \"synced\": 2,\n    \"failed\": 0\n  },\n  \"sync_mode\": \"specific_transactions\"\n}"}]},{"name":"Get Invoice Sync Status","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync-status","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync-status"]},"description":"Returns the current sync status and summary for QBO invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync-status","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync-status"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"status\": {\n    \"total_eligible\": 50,\n    \"synced\": 45,\n    \"pending\": 5,\n    \"failed\": 0,\n    \"last_sync_at\": \"2024-01-01T00:00:00.000000Z\"\n  }\n}"}]},{"name":"Refresh Invoices","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/refresh","host":["{{baseUrl}}"],"path":["api","qbo","invoices","refresh"]},"description":"Syncs invoices from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Invoices in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","invoices","refresh-tracked"]},"description":"Starts a background refresh of invoices from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/invoices/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","invoices","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO invoices refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Invoices Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync-info"]},"description":"Returns the latest synced invoice identifier and timestamp, the total number of invoices already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","invoices","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"INV-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Invoices in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","invoices","search-qbo"]},"description":"Searches QuickBooks directly for invoices matching a field/value (without importing them). `field` must be one of the values returned by Get Invoices Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/invoices/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","invoices","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Invoice from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","invoices","refresh-single"]},"description":"Fetches a single invoice from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/invoices/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","invoices","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO invoice pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Invoices","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","invoices","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export invoices to CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Invoices","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/archive","host":["{{baseUrl}}"],"path":["api","qbo","invoices","archive"]},"description":"Archive one or more QBO invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Invoice Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/statistics","host":["{{baseUrl}}"],"path":["api","qbo","invoices","statistics"]},"description":"Get aggregate counts for the QuickBooks Online invoices synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices/statistics","host":["{{baseUrl}}"],"path":["api","qbo","invoices","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1280,\n    \"active\": 1244,\n    \"archived\": 36\n  }\n}"}]},{"name":"Get Invoice Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","invoices",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online invoice. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the invoice does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/invoices/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","invoices",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboInvoice\",\n      \"subject_id\": 314,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/invoices/314/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/invoices/314/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/invoices/314/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/invoices/314/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Unarchive Invoices","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/invoices/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","invoices","unarchive"]},"description":"Restore one or more archived QuickBooks Online invoices by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/invoices/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","invoices","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO invoices(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"List Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","items"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO items/products.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, name, sku, description."}},{"name":"Delete Items","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items","host":["{{baseUrl}}"],"path":["api","qbo","items"]},"description":"Delete one or more QBO items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Item","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items/{id}","host":["{{baseUrl}}"],"path":["api","qbo","items",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO item by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Refresh Items","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/refresh","host":["{{baseUrl}}"],"path":["api","qbo","items","refresh"]},"description":"Syncs items from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Items in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","items","refresh-tracked"]},"description":"Starts a background refresh of items from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/items/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","items","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO items refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Items Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","items","sync-info"]},"description":"Returns the latest synced item identifier and timestamp, the total number of items already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/items/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","items","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Items in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","items","search-qbo"]},"description":"Searches QuickBooks directly for items matching a field/value (without importing them). `field` must be one of the values returned by Get Items Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/items/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","items","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Item from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","items","refresh-single"]},"description":"Fetches a single item from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/items/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","items","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO item pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Export Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items/export?format=csv","host":["{{baseUrl}}"],"path":["api","qbo","items","export"],"query":[{"key":"format","value":"csv","disabled":true}]},"description":"Export items to CSV.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Archive Items","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/archive","host":["{{baseUrl}}"],"path":["api","qbo","items","archive"]},"description":"Archive one or more QBO items.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Item Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items/statistics","host":["{{baseUrl}}"],"path":["api","qbo","items","statistics"]},"description":"Get aggregate counts for the QuickBooks Online items synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/items/statistics","host":["{{baseUrl}}"],"path":["api","qbo","items","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 356,\n    \"active\": 340,\n    \"archived\": 16\n  }\n}"}]},{"name":"Unarchive Items","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/items/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","items","unarchive"]},"description":"Restore one or more archived QuickBooks Online items by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/items/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","items","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO items(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"Get Item Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/items/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","items",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online item. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the item does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/items/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","items",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboItem\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/items/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/items/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/items/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/items/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Journals","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","journals"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO journal entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, description."}},{"name":"Delete Journals","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals","host":["{{baseUrl}}"],"path":["api","qbo","journals"]},"description":"Delete one or more QBO journals.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Journal","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals/{id}","host":["{{baseUrl}}"],"path":["api","qbo","journals",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO journal entry by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/journals/{id}","host":["{{baseUrl}}"],"path":["api","qbo","journals",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 29,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"406\",\n    \"doc_number\": \"JE-9007\",\n    \"name\": \"JE-9007\",\n    \"description\": \"Monthly COGS summary\",\n    \"total_amount\": \"5230.00\",\n    \"adjustment\": false,\n    \"txn_date\": \"2026-06-30\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/journal?txnId=406\",\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Inventory revaluation\",\n        \"detail_type\": \"JournalEntryLineDetail\",\n        \"item\": null,\n        \"item_id\": null,\n        \"item_link_id\": null,\n        \"account\": \"Inventory Asset\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"amount\": 5230,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": \"Debit\"\n      },\n      {\n        \"line_num\": 2,\n        \"description\": \"Inventory revaluation\",\n        \"detail_type\": \"JournalEntryLineDetail\",\n        \"item\": null,\n        \"item_id\": null,\n        \"item_link_id\": null,\n        \"account\": \"Cost of Goods Sold\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"amount\": 5230,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": \"Credit\"\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"406\",\n      \"DocNumber\": \"JE-9007\",\n      \"TxnDate\": \"2026-06-30\",\n      \"TotalAmt\": 5230,\n      \"Line\": [\n        {\n          \"Id\": \"0\",\n          \"Description\": \"Inventory revaluation\",\n          \"Amount\": 5230,\n          \"DetailType\": \"JournalEntryLineDetail\",\n          \"JournalEntryLineDetail\": {\n            \"PostingType\": \"Debit\",\n            \"AccountRef\": {\n              \"value\": \"81\",\n              \"name\": \"Inventory Asset\"\n            }\n          }\n        },\n        {\n          \"Id\": \"1\",\n          \"Description\": \"Inventory revaluation\",\n          \"Amount\": 5230,\n          \"DetailType\": \"JournalEntryLineDetail\",\n          \"JournalEntryLineDetail\": {\n            \"PostingType\": \"Credit\",\n            \"AccountRef\": {\n              \"value\": \"80\",\n              \"name\": \"Cost of Goods Sold\"\n            }\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Refresh Journals","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/refresh","host":["{{baseUrl}}"],"path":["api","qbo","journals","refresh"]},"description":"Syncs journals from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Journals in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","journals","refresh-tracked"]},"description":"Starts a background refresh of journals from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/journals/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","journals","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO journals refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Journals Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","journals","sync-info"]},"description":"Returns the latest synced journal identifier and timestamp, the total number of journals already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/journals/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","journals","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Journals in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","journals","search-qbo"]},"description":"Searches QuickBooks directly for journals matching a field/value (without importing them). `field` must be one of the values returned by Get Journals Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/journals/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","journals","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Journal from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","journals","refresh-single"]},"description":"Fetches a single journal from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/journals/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","journals","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO journal pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Journals","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/archive","host":["{{baseUrl}}"],"path":["api","qbo","journals","archive"]},"description":"Archive one or more QBO journals.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Journals","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals/export","host":["{{baseUrl}}"],"path":["api","qbo","journals","export"]},"description":"Download the QuickBooks Online journals synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Doc Number, Description, Total Amount, Transaction Date, Adjustment, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_journals_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Journal Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals/statistics","host":["{{baseUrl}}"],"path":["api","qbo","journals","statistics"]},"description":"Get aggregate counts for the QuickBooks Online journals synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/journals/statistics","host":["{{baseUrl}}"],"path":["api","qbo","journals","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 94,\n    \"active\": 90,\n    \"archived\": 4\n  }\n}"}]},{"name":"Get Journal Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/journals/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","journals",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online journal. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the journal does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/journals/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","journals",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboJournal\",\n      \"subject_id\": 128,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/journals/128/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/journals/128/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/journals/128/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/journals/128/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Unarchive Journals","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/journals/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","journals","unarchive"]},"description":"Restore one or more archived QuickBooks Online journals by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/journals/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","journals","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO journals(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"List Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","payments"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO payments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, customer_name."}},{"name":"Delete Payments","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments","host":["{{baseUrl}}"],"path":["api","qbo","payments"]},"description":"Delete one or more QBO payments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Payment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments/{id}","host":["{{baseUrl}}"],"path":["api","qbo","payments",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO payment by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `customer_link_id` and `sku_customer_id` cross-link to the mirrored QuickBooks customer and its linked SKU customer. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row.\n\nPayments additionally include the `bank` account name and an `applied` array of the invoices the payment was applied to (`txn_type`, `txn_id`, `amount`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/payments/{id}","host":["{{baseUrl}}"],"path":["api","qbo","payments",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 74,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"509\",\n    \"customer_id\": \"12\",\n    \"customer_name\": \"Bar Supply Co\",\n    \"name\": \"Bar Supply Co\",\n    \"total_amount\": \"842.00\",\n    \"currency\": \"USD\",\n    \"txn_date\": \"2026-07-10\",\n    \"payment_method\": \"Credit Card\",\n    \"reference_number\": \"PMT-509\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/recvpayment?txnId=509\",\n    \"customer_link_id\": 88,\n    \"sku_customer_id\": 1420,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"bank\": \"Checking\",\n    \"applied\": [\n      {\n        \"txn_type\": \"Invoice\",\n        \"txn_id\": \"8061\",\n        \"amount\": 180\n      }\n    ],\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"509\",\n      \"TxnDate\": \"2026-07-10\",\n      \"TotalAmt\": 842,\n      \"CustomerRef\": {\n        \"value\": \"12\",\n        \"name\": \"Bar Supply Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Refresh Payments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/refresh","host":["{{baseUrl}}"],"path":["api","qbo","payments","refresh"]},"description":"Syncs payments from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Payments in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","payments","refresh-tracked"]},"description":"Starts a background refresh of payments from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/payments/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","payments","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO payments refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Payments Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","payments","sync-info"]},"description":"Returns the latest synced payment identifier and timestamp, the total number of payments already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/payments/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","payments","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Payments in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","payments","search-qbo"]},"description":"Searches QuickBooks directly for payments matching a field/value (without importing them). `field` must be one of the values returned by Get Payments Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/payments/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","payments","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Payment from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","payments","refresh-single"]},"description":"Fetches a single payment from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/payments/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","payments","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO payment pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Payments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/archive","host":["{{baseUrl}}"],"path":["api","qbo","payments","archive"]},"description":"Archive one or more QBO payments.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments/export","host":["{{baseUrl}}"],"path":["api","qbo","payments","export"]},"description":"Download the QuickBooks Online payments synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Customer ID, Customer Name, Total Amount, Currency, Transaction Date, Payment Method, Reference Number, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_payments_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Payment Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments/statistics","host":["{{baseUrl}}"],"path":["api","qbo","payments","statistics"]},"description":"Get aggregate counts for the QuickBooks Online payments synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/payments/statistics","host":["{{baseUrl}}"],"path":["api","qbo","payments","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 873,\n    \"active\": 861,\n    \"archived\": 12\n  }\n}"}]},{"name":"Get Payment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payments/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","payments",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online payment. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the payment does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/payments/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","payments",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboPayment\",\n      \"subject_id\": 209,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/payments/209/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/payments/209/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/payments/209/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/payments/209/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Unarchive Payments","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payments/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","payments","unarchive"]},"description":"Restore one or more archived QuickBooks Online payments by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/payments/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","payments","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO payments(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"List Purchase Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO purchase orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, vendor_name."}},{"name":"Delete Purchase Orders","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders"]},"description":"Delete one or more QBO purchase orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Purchase Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/{id}","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO purchase order by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe `linked_sku_purchase_order` field identifies the SKU purchase order this QuickBooks document was pushed from (id, purchase order number, and an app route); it is null when no such origin exists. `qbo_link` deep-links to the purchase order in the QuickBooks web UI.\n\nThe response includes `vendor_link_id`, cross-linking to the mirrored QuickBooks vendor. The reverse ledger cross-link fields `ledger_entry_id`, `ledger_entry_reference`, `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` are also present but are always `null` for purchase orders, which are not pushed by SKU's ledger. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row.\n\nPurchase orders additionally include a `shipping` block (`ship_to_address`, `due_date`, `ship_method`, `memo`, `po_status`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/{id}","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 52,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"612\",\n    \"doc_number\": \"PO-1450\",\n    \"vendor_id\": \"56\",\n    \"vendor_name\": \"Shanghai Supplier Co\",\n    \"total_amount\": \"20000.00\",\n    \"currency\": \"USD\",\n    \"txn_date\": \"2026-06-20\",\n    \"status\": \"Open\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/purchaseorder?txnId=612\",\n    \"vendor_link_id\": 57,\n    \"ledger_entry_id\": null,\n    \"ledger_entry_reference\": null,\n    \"sku_link_type\": null,\n    \"sku_link_id\": null,\n    \"sku_link_label\": null,\n    \"sku_link_route\": null,\n    \"linked_sku_purchase_order\": {\n      \"id\": 1450,\n      \"purchase_order_number\": \"PO-1450\",\n      \"route\": \"/orders/purchase-orders/1450\"\n    },\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"shipping\": {\n      \"ship_to_address\": \"123 Main St, Austin, TX, 78701\",\n      \"due_date\": \"2026-02-11\",\n      \"ship_method\": \"UPS Ground\",\n      \"memo\": \"Deliver to dock B; call warehouse on arrival.\",\n      \"po_status\": \"Open\"\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Cold-chain freight\",\n        \"detail_type\": \"AccountBasedExpenseLineDetail\",\n        \"item\": null,\n        \"item_id\": null,\n        \"item_link_id\": null,\n        \"account\": \"Shipping & Freight\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"amount\": 125,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"612\",\n      \"DocNumber\": \"PO-1450\",\n      \"TxnDate\": \"2026-06-20\",\n      \"TotalAmt\": 20000,\n      \"VendorRef\": {\n        \"value\": \"56\",\n        \"name\": \"Shanghai Supplier Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"Amount\": 125,\n          \"DetailType\": \"AccountBasedExpenseLineDetail\",\n          \"Description\": \"Cold-chain freight\",\n          \"AccountBasedExpenseLineDetail\": {\n            \"AccountRef\": {\n              \"value\": \"63\",\n              \"name\": \"Shipping & Freight\"\n            }\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Refresh Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/refresh","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","refresh"]},"description":"Syncs purchase orders from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Purchase Orders in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","refresh-tracked"]},"description":"Starts a background refresh of purchase orders from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO purchase-orders refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Purchase Orders Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","sync-info"]},"description":"Returns the latest synced purchase order identifier and timestamp, the total number of purchase orders already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Purchase Orders in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","search-qbo"]},"description":"Searches QuickBooks directly for purchase orders matching a field/value (without importing them). `field` must be one of the values returned by Get Purchase Orders Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Purchase Order from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","refresh-single"]},"description":"Fetches a single purchase order from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO purchase order pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/archive","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","archive"]},"description":"Archive one or more QBO purchase orders.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Purchase Orders","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/export","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","export"]},"description":"Download the QuickBooks Online purchase orders synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Doc Number, Vendor ID, Vendor Name, Total Amount, Currency, Transaction Date, Status, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_purchase-orders_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Purchase Order Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/statistics","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","statistics"]},"description":"Get aggregate counts for the QuickBooks Online purchase orders synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/statistics","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 211,\n    \"active\": 198,\n    \"archived\": 13\n  }\n}"}]},{"name":"Unarchive Purchase Orders","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","unarchive"]},"description":"Restore one or more archived QuickBooks Online purchase orders by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO purchase-orders(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"Get Purchase Order Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online purchase order. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the purchase order does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchase-orders/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","purchase-orders",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboPurchaseOrder\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/purchase-orders/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/purchase-orders/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/purchase-orders/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/purchase-orders/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Tax Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO tax codes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, name, description."}},{"name":"Delete Tax Codes","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes"]},"description":"Delete one or more QBO tax codes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Tax Code","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/{id}","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO tax code by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Refresh Tax Codes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/refresh","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","refresh"]},"description":"Syncs tax codes from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Tax Codes in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","refresh-tracked"]},"description":"Starts a background refresh of tax codes from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO tax-codes refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Tax Codes Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","sync-info"]},"description":"Returns the latest synced tax code identifier and timestamp, the total number of tax codes already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Tax Codes in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","search-qbo"]},"description":"Searches QuickBooks directly for tax codes matching a field/value (without importing them). `field` must be one of the values returned by Get Tax Codes Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Tax Code from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","refresh-single"]},"description":"Fetches a single tax code from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO tax code pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Tax Codes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/archive","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","archive"]},"description":"Archive one or more QBO tax codes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Tax Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/export","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","export"]},"description":"Download the QuickBooks Online tax codes synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Name, Description, Taxable, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_tax-codes_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Tax Code Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/statistics","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","statistics"]},"description":"Get aggregate counts for the QuickBooks Online tax codes synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/statistics","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 14,\n    \"active\": 12,\n    \"archived\": 2\n  }\n}"}]},{"name":"Unarchive Tax Codes","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","unarchive"]},"description":"Restore one or more archived QuickBooks Online tax codes by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-codes/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","tax-codes","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO tax-codes(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"List Tax Rates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO tax rates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, name, description."}},{"name":"Delete Tax Rates","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates"]},"description":"Delete one or more QBO tax rates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Tax Rate","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/{id}","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO tax rate by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Refresh Tax Rates","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/refresh","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","refresh"]},"description":"Syncs tax rates from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Tax Rates in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","refresh-tracked"]},"description":"Starts a background refresh of tax rates from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO tax-rates refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Tax Rates Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","sync-info"]},"description":"Returns the latest synced tax rate identifier and timestamp, the total number of tax rates already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Tax Rates in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","search-qbo"]},"description":"Searches QuickBooks directly for tax rates matching a field/value (without importing them). `field` must be one of the values returned by Get Tax Rates Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Tax Rate from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","refresh-single"]},"description":"Fetches a single tax rate from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO tax rate pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Tax Rates","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/archive","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","archive"]},"description":"Archive one or more QBO tax rates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Tax Rates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/export","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","export"]},"description":"Download the QuickBooks Online tax rates synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Name, Description, Rate Value, Agency ID, Agency Name, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_tax-rates_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Tax Rate Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/statistics","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","statistics"]},"description":"Get aggregate counts for the QuickBooks Online tax rates synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/statistics","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 22,\n    \"active\": 20,\n    \"archived\": 2\n  }\n}"}]},{"name":"Unarchive Tax Rates","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","unarchive"]},"description":"Restore one or more archived QuickBooks Online tax rates by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-rates/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","tax-rates","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO tax-rates(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"List Vendors","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","vendors"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}]},"description":"Paginated list of QBO vendors.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nSearchable columns (filter[search]): id, qbo_id, name, display_name, company_name."}},{"name":"Delete Vendors","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors","host":["{{baseUrl}}"],"path":["api","qbo","vendors"]},"description":"Delete one or more QBO vendors.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Vendor","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/{id}","host":["{{baseUrl}}"],"path":["api","qbo","vendors",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]},"description":"Get a single QBO vendor by ID.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendors/{id}","host":["{{baseUrl}}"],"path":["api","qbo","vendors",":id"],"variable":[{"key":"id","value":"1","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 18,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"56\",\n    \"name\": \"Shanghai Supplier Co\",\n    \"display_name\": \"Shanghai Supplier Co\",\n    \"company_name\": \"Shanghai Supplier Co Ltd\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/vendordetail?nameId=56\"\n  }\n}"}]},{"name":"Refresh Vendors","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/refresh","host":["{{baseUrl}}"],"path":["api","qbo","vendors","refresh"]},"description":"Syncs vendors from QBO API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}}},{"name":"Refresh Vendors in Background","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","vendors","refresh-tracked"]},"description":"Starts a background refresh of vendors from QuickBooks and returns a job id you can poll for progress. Send no parameters for an incremental sync (records changed since the last sync), `full_sync: true` to re-pull everything, or `start_date` + `end_date` (MM/DD/YYYY) to pull records updated within a date range.","body":{"mode":"raw","raw":"{\n  \"full_sync\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/vendors/refresh-tracked","host":["{{baseUrl}}"],"path":["api","qbo","vendors","refresh-tracked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO vendors refresh started.\",\n  \"data\": {\n    \"tracked_job_log_id\": 8123,\n    \"sync_type\": \"incremental\",\n    \"sync_description\": \"Incremental sync (changes since last sync)\"\n  }\n}"}]},{"name":"Get Vendors Sync Info","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","vendors","sync-info"]},"description":"Returns the latest synced vendor identifier and timestamp, the total number of vendors already stored, and the fields you can search QuickBooks by for this entity."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendors/sync-info","host":["{{baseUrl}}"],"path":["api","qbo","vendors","sync-info"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"latest_identifier\": \"REF-1042\",\n    \"latest_date\": \"2026-07-16T18:22:05.000000Z\",\n    \"total_count\": 128,\n    \"searchable_fields\": [\n      {\n        \"value\": \"doc_number\",\n        \"label\": \"Doc Number\",\n        \"qbo_field\": \"DocNumber\",\n        \"exact\": false\n      },\n      {\n        \"value\": \"qbo_id\",\n        \"label\": \"QuickBooks ID\",\n        \"qbo_field\": \"Id\",\n        \"exact\": true\n      }\n    ]\n  }\n}"}]},{"name":"Search Vendors in QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","vendors","search-qbo"]},"description":"Searches QuickBooks directly for vendors matching a field/value (without importing them). `field` must be one of the values returned by Get Vendors Sync Info (e.g. `doc_number`, `qbo_id`). Each result flags whether it already exists in your database.","body":{"mode":"raw","raw":"{\n  \"field\": \"doc_number\",\n  \"value\": \"1042\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/vendors/search-qbo","host":["{{baseUrl}}"],"path":["api","qbo","vendors","search-qbo"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"qbo_id\": \"1042\",\n      \"label\": \"INV-1042\",\n      \"sub_label\": \"QuickBooks ID 1042\",\n      \"exists_in_database\": true\n    },\n    {\n      \"qbo_id\": \"1043\",\n      \"label\": \"INV-1043\",\n      \"sub_label\": \"QuickBooks ID 1043\",\n      \"exists_in_database\": false\n    }\n  ]\n}"}]},{"name":"Pull Vendor from QuickBooks","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","vendors","refresh-single"]},"description":"Fetches a single vendor from QuickBooks by its QuickBooks id and imports (or updates) it in your database.","body":{"mode":"raw","raw":"{\n  \"qbo_id\": \"1043\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/vendors/refresh-single","host":["{{baseUrl}}"],"path":["api","qbo","vendors","refresh-single"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"QBO vendor pulled from QuickBooks.\",\n  \"data\": {\n    \"success\": true,\n    \"qbo_id\": \"1043\",\n    \"id\": 991\n  }\n}"}]},{"name":"Archive Vendors","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/archive","host":["{{baseUrl}}"],"path":["api","qbo","vendors","archive"]},"description":"Archive one or more QBO vendors.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1\n  ]\n}","options":{"raw":{"language":"json"}}}}},{"name":"Export Vendors","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/export","host":["{{baseUrl}}"],"path":["api","qbo","vendors","export"]},"description":"Download the QuickBooks Online vendors synced into SKU.io as a CSV file. The export is streamed from the locally synced copies; no request is made to QuickBooks.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCSV columns: QBO ID, Name, Display Name, Company Name, Active, QBO Created At, QBO Updated At, Local Created At, Local Updated At.\n\nThe response is a file download (`Content-Type: text/csv`) with a filename of the form `qbo_vendors_export_2026-07-07_10-30-00.csv`. By default all records (active and archived) are included; use the query parameters to narrow the export.\n\nReturns a 500 error if no QuickBooks Online integration has been set up, and a 422 error if a date parameter is not in MM/DD/YYYY format.\n\nAuthentication: Requires Bearer token."}},{"name":"Get Vendor Statistics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/statistics","host":["{{baseUrl}}"],"path":["api","qbo","vendors","statistics"]},"description":"Get aggregate counts for the QuickBooks Online vendors synced into SKU.io: the total number of records, how many are active, and how many are archived.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCounts are computed from the locally synced copies; no request is made to QuickBooks.\n\nReturns a 500 error if no QuickBooks Online integration has been set up.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendors/statistics","host":["{{baseUrl}}"],"path":["api","qbo","vendors","statistics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"total\": 167,\n    \"active\": 158,\n    \"archived\": 9\n  }\n}"}]},{"name":"Unarchive Vendors","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","vendors","unarchive"]},"description":"Restore one or more archived QuickBooks Online vendors by ID, marking them active again in SKU.io.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only restores the archived local synced copy in SKU.io; it does not modify anything in QuickBooks itself. Archiving and unarchiving control visibility within SKU.io only.\n\nReturns the number of records that were updated.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/vendors/unarchive","host":["{{baseUrl}}"],"path":["api","qbo","vendors","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Successfully unarchived 3 QBO vendors(s)\",\n  \"data\": {\n    \"unarchived_count\": 3\n  }\n}"}]},{"name":"Get Vendor Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendors/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","vendors",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online vendor. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the vendor does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendors/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","vendors",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboVendor\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/vendors/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/vendors/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/vendors/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/vendors/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Conflict Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/summary","host":["{{baseUrl}}"],"path":["api","qbo","conflicts","summary"]},"description":"Returns aggregate conflict statistics across all entity types.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/conflicts/summary","host":["{{baseUrl}}"],"path":["api","qbo","conflicts","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"summary\": {\n    \"total_conflicts\": 5,\n    \"by_type\": {\n      \"invoices\": 3,\n      \"customers\": 2\n    }\n  },\n  \"integration_instance\": {\n    \"id\": 1,\n    \"name\": \"My Company\"\n  }\n}"}]},{"name":"Detect Conflicts","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/detect","host":["{{baseUrl}}"],"path":["api","qbo","conflicts","detect"]},"description":"Runs conflict detection across all entity types and returns newly found conflicts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/conflicts/detect","host":["{{baseUrl}}"],"path":["api","qbo","conflicts","detect"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"conflicts_detected\": 3,\n  \"conflicts_by_type\": {\n    \"invoices\": 3\n  },\n  \"message\": \"Conflict detection completed\"\n}"}]},{"name":"List Conflicts by Entity Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType"],"query":[{"key":"page","value":"1","description":"Page number (default 1).","disabled":true},{"key":"per_page","value":"15","description":"Results per page (default 10).","disabled":true}],"variable":[{"key":"entityType","value":"invoices","description":"One of: invoices, purchase-orders, accounts, customers, items, tax-codes, tax-rates"}]},"description":"Lists conflicted entities of a given type. Valid entity types: invoices, purchase-orders, accounts, customers, items, tax-codes, tax-rates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Get Conflict Details","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}/{entityId}","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType",":entityId"],"variable":[{"key":"entityType","value":"invoices","description":"The entity type ID."},{"key":"entityId","value":"1","description":"The entity ID."}]},"description":"Get detailed conflict information for a specific entity including resolution options.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Resolve Conflict","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}/{entityId}/resolve","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType",":entityId","resolve"],"variable":[{"key":"entityType","value":"invoices","description":"The entity type ID."},{"key":"entityId","value":"1","description":"The entity ID."}]},"description":"Resolves a conflict for a specific entity. Actions: delete_qbo, delete_sku, resync_to_qbo, break_link, mark_do_not_sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"action\": \"resync_to_qbo\",\n  \"reason\": \"Manual review confirmed SKU data is correct\",\n  \"confirm_impacts\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}/{entityId}/resolve","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType",":entityId","resolve"],"variable":[{"key":"entityType","value":"invoices","description":"The entity type ID."},{"key":"entityId","value":"1","description":"The entity ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Conflict resolved successfully\",\n  \"entity_id\": 1,\n  \"action_taken\": \"resync_to_qbo\",\n  \"new_status\": \"synced\"\n}"}]},{"name":"Bulk Resolve Conflicts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}/bulk-resolve","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType","bulk-resolve"],"variable":[{"key":"entityType","value":"invoices","description":"The entity type ID."}]},"description":"Bulk resolves up to 50 conflicts at once for entities of a given type.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"entity_ids\": [\n    1,\n    2,\n    3\n  ],\n  \"action\": \"resync_to_qbo\",\n  \"reason\": \"Bulk resolution\",\n  \"confirm_impacts\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/conflicts/{entityType}/bulk-resolve","host":["{{baseUrl}}"],"path":["api","qbo","conflicts",":entityType","bulk-resolve"],"variable":[{"key":"entityType","value":"invoices","description":"The entity type ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"results\": {\n    \"successful\": [\n      {\n        \"entity_id\": 1,\n        \"new_status\": \"synced\"\n      }\n    ],\n    \"failed\": []\n  },\n  \"message\": \"Bulk resolution completed: 1 successful, 0 failed\"\n}"}]},{"name":"List Payment Type Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings"]},"description":"Lists all payment types with their mapped QBO bank accounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"payment_type_id\": 1,\n      \"payment_type_name\": \"Credit Card\",\n      \"qbo_account\": null,\n      \"is_mapped\": false\n    }\n  ],\n  \"meta\": {\n    \"total_payment_types\": 5,\n    \"mapped_count\": 2,\n    \"unmapped_count\": 3\n  }\n}"}]},{"name":"Get Payment Type Mapping","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings/{paymentTypeId}","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings",":paymentTypeId"],"variable":[{"key":"paymentTypeId","value":"1","description":"The payment type ID."}]},"description":"Get the QBO account mapping for a specific payment type.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Update Payment Type Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings/{paymentTypeId}","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings",":paymentTypeId"],"variable":[{"key":"paymentTypeId","value":"1","description":"The payment type ID."}]},"description":"Maps a payment type to a QBO bank account. Pass null for qbo_account_id to clear the mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"qbo_account_id\": 5\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Available Bank Accounts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings/available-accounts","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings","available-accounts"]},"description":"Returns all active QBO Bank accounts available for payment type mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Update Payment Type Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings","bulk-update"]},"description":"Updates QBO bank account mappings for multiple payment types in one request.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"payment_type_id\": 1,\n      \"qbo_account_id\": 5\n    },\n    {\n      \"payment_type_id\": 2,\n      \"qbo_account_id\": 6\n    },\n    {\n      \"payment_type_id\": 3,\n      \"qbo_account_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/payment-type-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","qbo","payment-type-mappings","bulk-update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Updated 3 mapping(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"payment_type_id\": 1,\n        \"success\": true\n      }\n    ],\n    \"summary\": {\n      \"total\": 3,\n      \"successful\": 3,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"Get Custom Field Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings"]},"description":"Returns the saved QBO invoice custom field mappings (`sales_rep`, `po_number`) and the list of available QBO custom fields fetched from the company's preferences.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"custom_field_mappings\": {\n      \"sales_rep\": {\n        \"enabled\": true,\n        \"definition_id\": \"1\"\n      },\n      \"po_number\": {\n        \"enabled\": true,\n        \"definition_id\": \"3\"\n      }\n    },\n    \"qbo_custom_fields\": [\n      {\n        \"definition_id\": \"1\",\n        \"name\": \"Sales Rep\",\n        \"enabled\": true\n      },\n      {\n        \"definition_id\": \"2\",\n        \"name\": \"UPS/FedEx Tracking\",\n        \"enabled\": true\n      },\n      {\n        \"definition_id\": \"3\",\n        \"name\": \"PO Number\",\n        \"enabled\": true\n      }\n    ]\n  }\n}"}]},{"name":"Update Custom Field Mappings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings"]},"description":"Updates the QBO invoice custom field mapping config. `sales_rep` (required) maps the Sales Order's sales rep, and `po_number` (optional) maps the Sales Order's customer PO number — each to a QBO legacy custom field on invoices. For each mapping, `definition_id` must be \"1\", \"2\", or \"3\" (QBO supports three legacy custom fields) and may be null when `enabled` is false.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires a Bearer token.","body":{"mode":"raw","raw":"{\n  \"custom_field_mappings\": {\n    \"sales_rep\": {\n      \"enabled\": true,\n      \"definition_id\": \"1\"\n    },\n    \"po_number\": {\n      \"enabled\": true,\n      \"definition_id\": \"3\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Custom field mappings updated successfully.\",\n  \"data\": {\n    \"custom_field_mappings\": {\n      \"sales_rep\": {\n        \"enabled\": true,\n        \"definition_id\": \"1\"\n      },\n      \"po_number\": {\n        \"enabled\": true,\n        \"definition_id\": \"3\"\n      }\n    }\n  }\n}"}]},{"name":"Fetch Custom Fields from QBO","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings/fetch-fields","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings","fetch-fields"]},"description":"Fetches available custom fields from QBO Preferences API and stores them locally.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/custom-field-mappings/fetch-fields","host":["{{baseUrl}}"],"path":["api","qbo","custom-field-mappings","fetch-fields"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Custom fields fetched successfully from QuickBooks.\",\n  \"data\": {\n    \"qbo_custom_fields\": [\n      {\n        \"definition_id\": \"1\",\n        \"name\": \"Sales Rep\",\n        \"enabled\": true\n      }\n    ]\n  }\n}"}]},{"name":"List Tax Code Mappings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings"]},"description":"Lists all SKU tax rates with their mapped QBO tax codes.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"tax_rate_id\": 1,\n      \"tax_rate_name\": \"CA Tax\",\n      \"tax_rate_value\": \"0.08\",\n      \"qbo_tax_code\": null,\n      \"is_mapped\": false\n    }\n  ],\n  \"meta\": {\n    \"total_tax_rates\": 3,\n    \"mapped_count\": 1,\n    \"unmapped_count\": 2\n  }\n}"}]},{"name":"Get Tax Code Mapping","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings/{taxRateId}","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings",":taxRateId"],"variable":[{"key":"taxRateId","value":"1","description":"The tax rate ID."}]},"description":"Get the QBO tax code mapping for a specific SKU tax rate.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Update Tax Code Mapping","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings/{taxRateId}","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings",":taxRateId"],"variable":[{"key":"taxRateId","value":"1","description":"The tax rate ID."}]},"description":"Maps a SKU tax rate to a QBO tax code. Pass null for qbo_tax_code_id to clear the mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"qbo_tax_code_id\": 3\n}","options":{"raw":{"language":"json"}}}}},{"name":"Get Available Tax Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings/available-tax-codes","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings","available-tax-codes"]},"description":"Returns all active QBO tax codes available for mapping.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."}},{"name":"Bulk Update Tax Code Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings","bulk-update"]},"description":"Updates QBO tax code mappings for multiple SKU tax rates in one request.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"tax_rate_id\": 1,\n      \"qbo_tax_code_id\": 3\n    },\n    {\n      \"tax_rate_id\": 2,\n      \"qbo_tax_code_id\": null\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/tax-code-mappings/bulk-update","host":["{{baseUrl}}"],"path":["api","qbo","tax-code-mappings","bulk-update"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Updated 2 mapping(s)\",\n  \"data\": {\n    \"results\": [\n      {\n        \"tax_rate_id\": 1,\n        \"success\": true\n      }\n    ],\n    \"summary\": {\n      \"total\": 2,\n      \"successful\": 2,\n      \"failed\": 0\n    }\n  }\n}"}]},{"name":"Get Customer Match Run","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"Get the current state of a customer match run, including its status, the matching configuration snapshot the run was scored with, how many QuickBooks customers were evaluated, proposal counts per confidence bucket, proposal counts per decision status, and the background job log ID for progress tracking.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRun statuses: `running`, `awaiting_review`, `committing`, `completed`, `cancelled`, `failed`.\n\n`pending_bucket_counts` reflects the actionable review queue (pending and approved proposals per bucket); `status_counts` shows all proposals in the run by decision status.\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 3,\n    \"user_id\": 7,\n    \"status\": \"awaiting_review\",\n    \"config_snapshot\": {\n      \"weights\": {\n        \"email\": 50,\n        \"company\": 30,\n        \"name\": 15,\n        \"address\": 3,\n        \"phone\": 2\n      },\n      \"thresholds\": {\n        \"auto\": 90,\n        \"review\": 60\n      },\n      \"generic_email_handling\": \"demote\",\n      \"generic_local_parts\": [\n        \"info\",\n        \"sales\",\n        \"accounts\",\n        \"accounting\",\n        \"orders\",\n        \"billing\",\n        \"admin\",\n        \"contact\",\n        \"hello\",\n        \"office\",\n        \"support\",\n        \"payments\"\n      ],\n      \"fuzzy_company\": true,\n      \"fuzzy_name\": true,\n      \"auto_commit_auto_suggested\": false\n    },\n    \"qbo_customers_evaluated\": 480,\n    \"proposals_auto\": 55,\n    \"proposals_review\": 120,\n    \"proposals_hidden\": 210,\n    \"committed_count\": 0,\n    \"status_counts\": {\n      \"pending\": 385,\n      \"approved\": 0,\n      \"rejected\": 0,\n      \"committed\": 0,\n      \"superseded\": 0\n    },\n    \"pending_bucket_counts\": {\n      \"auto\": 55,\n      \"review\": 120,\n      \"hidden\": 210\n    },\n    \"tracked_job_log_id\": 3411,\n    \"created_at\": \"2026-07-01T09:15:00.000000Z\",\n    \"updated_at\": \"2026-07-01T09:18:42.000000Z\"\n  }\n}"}]},{"name":"Cancel Customer Match Run","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"Cancel a customer match run. All of the run's still-pending proposals are deleted and the run status is set to `cancelled`. If the scoring job is still running in the background, it stops at its next checkpoint.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis only affects SKU.io's local match-run data; it does not modify anything in QuickBooks itself. Links already committed from this run are kept - cancelling does not undo them.\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Run cancelled.\"\n}"}]},{"name":"List Match Run Proposals","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/proposals","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","proposals"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"List the scored match proposals produced by a customer match run, ordered by score (highest first) and paginated (standard pagination metadata is included in the response). Each proposal pairs one QuickBooks Online customer with one SKU.io customer and includes the overall score (0-100), the confidence bucket, and a per-field breakdown of the signals (email, company, name, address, phone) that produced the score.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBuckets: `auto` (score at or above the auto threshold), `review` (between the review and auto thresholds), `hidden` (below the review threshold).\n\nProposal statuses: `pending`, `approved`, `rejected`, `committed`, `superseded`. `rejection_reason` is set when a proposal was auto-rejected because one side was already linked (`qbo_customer_already_linked` or `sku_customer_already_linked`).\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/proposals","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","proposals"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 9101,\n      \"integration_instance_id\": 3,\n      \"qbo_customer_id\": 512,\n      \"sku_customer_id\": 2048,\n      \"run_id\": 12,\n      \"score\": 96,\n      \"bucket\": \"auto\",\n      \"signals\": [\n        {\n          \"field\": \"email\",\n          \"score\": 1,\n          \"weight\": 50,\n          \"contribution\": 50,\n          \"note\": \"exact\"\n        },\n        {\n          \"field\": \"company\",\n          \"score\": 1,\n          \"weight\": 30,\n          \"contribution\": 30,\n          \"note\": \"exact\"\n        },\n        {\n          \"field\": \"name\",\n          \"score\": 0.8,\n          \"weight\": 15,\n          \"contribution\": 12,\n          \"note\": \"fuzzy\"\n        },\n        {\n          \"field\": \"address\",\n          \"score\": 1,\n          \"weight\": 3,\n          \"contribution\": 3,\n          \"note\": null\n        },\n        {\n          \"field\": \"phone\",\n          \"score\": 0.5,\n          \"weight\": 2,\n          \"contribution\": 1,\n          \"note\": null\n        }\n      ],\n      \"status\": \"pending\",\n      \"rejection_reason\": null,\n      \"decided_at\": null,\n      \"qbo_customer\": {\n        \"id\": 512,\n        \"qbo_id\": \"158\",\n        \"display_name\": \"Acme Supplies\",\n        \"company_name\": \"Acme Supplies LLC\",\n        \"given_name\": \"John\",\n        \"family_name\": \"Doe\",\n        \"email\": \"orders@acmesupplies.com\",\n        \"ship_addr\": {\n          \"Line1\": \"12 Main St\",\n          \"City\": \"Austin\",\n          \"PostalCode\": \"78701\"\n        },\n        \"bill_addr\": {\n          \"Line1\": \"12 Main St\",\n          \"City\": \"Austin\",\n          \"PostalCode\": \"78701\"\n        }\n      },\n      \"sku_customer\": {\n        \"id\": 2048,\n        \"name\": \"John Doe\",\n        \"company\": \"Acme Supplies\",\n        \"email\": \"orders@acmesupplies.com\",\n        \"address1\": \"12 Main St\",\n        \"zip\": \"78701\",\n        \"phone\": \"+1 512 555 0193\"\n      }\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/customers/match-runs/12/proposals?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/customers/match-runs/12/proposals?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/customers/match-runs/12/proposals?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/customers/match-runs/12/proposals\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 385\n}"}]},{"name":"Get Customer Matching Configuration","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Get the customer matching configuration for a QuickBooks Online integration instance. If no configuration has been saved yet, the defaults are returned.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- `weights` - relative importance (0-100) of each signal: email, company, name, address, phone.\n- `thresholds` - score cutoffs (0-100): proposals scoring at or above `auto` are auto-suggested; at or above `review` they land in the review queue; below `review` they are hidden.\n- `generic_email_handling` - how shared mailbox addresses (info@, sales@, ...) are scored: `demote` (half credit), `ignore` (no credit), or `accept` (full credit).\n- `generic_local_parts` - the list of email local parts treated as generic.\n- `fuzzy_company` / `fuzzy_name` - whether near-matches count for the company and name signals.\n- `auto_commit_auto_suggested` - whether proposals in the auto bucket should be committed without manual review.\n\nReturns 404 if the integration instance does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"weights\": {\n      \"email\": 50,\n      \"company\": 30,\n      \"name\": 15,\n      \"address\": 3,\n      \"phone\": 2\n    },\n    \"thresholds\": {\n      \"auto\": 90,\n      \"review\": 60\n    },\n    \"generic_email_handling\": \"demote\",\n    \"generic_local_parts\": [\n      \"info\",\n      \"sales\",\n      \"accounts\",\n      \"accounting\",\n      \"orders\",\n      \"billing\",\n      \"admin\",\n      \"contact\",\n      \"hello\",\n      \"office\",\n      \"support\",\n      \"payments\"\n    ],\n    \"fuzzy_company\": true,\n    \"fuzzy_name\": true,\n    \"auto_commit_auto_suggested\": false\n  }\n}"}]},{"name":"Update Customer Matching Configuration","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Save the customer matching configuration for a QuickBooks Online integration instance. The full configuration must be sent - all fields except `generic_local_parts` are required.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nValidation rules beyond per-field types:\n- The five weights must sum to more than 0.\n- `thresholds.review` must be less than or equal to `thresholds.auto`.\n- `generic_email_handling` must be one of `demote`, `ignore`, `accept`.\n\nThe saved configuration is used by subsequent match runs and previews (each run also stores a snapshot of the configuration it was scored with). Saving the configuration does not modify anything in QuickBooks.\n\nReturns the normalized configuration that was saved. Returns 404 if the integration instance does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"weights\": {\n    \"email\": 50,\n    \"company\": 30,\n    \"name\": 15,\n    \"address\": 3,\n    \"phone\": 2\n  },\n  \"thresholds\": {\n    \"auto\": 90,\n    \"review\": 60\n  },\n  \"generic_email_handling\": \"demote\",\n  \"generic_local_parts\": [\n    \"info\",\n    \"sales\",\n    \"accounts\",\n    \"billing\",\n    \"support\"\n  ],\n  \"fuzzy_company\": true,\n  \"fuzzy_name\": true,\n  \"auto_commit_auto_suggested\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"weights\": {\n      \"email\": 50,\n      \"company\": 30,\n      \"name\": 15,\n      \"address\": 3,\n      \"phone\": 2\n    },\n    \"thresholds\": {\n      \"auto\": 90,\n      \"review\": 60\n    },\n    \"generic_email_handling\": \"demote\",\n    \"generic_local_parts\": [\n      \"info\",\n      \"sales\",\n      \"accounts\",\n      \"billing\",\n      \"support\"\n    ],\n    \"fuzzy_company\": true,\n    \"fuzzy_name\": true,\n    \"auto_commit_auto_suggested\": false\n  },\n  \"message\": \"Matching configuration saved.\"\n}"}]},{"name":"Start Customer Match Run","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs"]},"description":"Start a new customer match run. The run scores every active, unlinked QuickBooks Online customer (or only the customers listed in `qbo_customer_ids`) against the SKU.io customer pool using the current matching configuration, and stores up to five scored proposals per QuickBooks customer.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis endpoint queues a background job to do the scoring and returns immediately. The response contains the new run ID and a background job log ID that can be used to track progress. Poll `GET /api/qbo/customers/match-runs/{id}` until the run status changes from `running` to `awaiting_review` before fetching proposals.\n\nScoring reads only locally synced data and creates proposal records in SKU.io; it does not modify anything in QuickBooks. Any pending proposals from earlier runs for the same QuickBooks customers are marked `superseded`.\n\nRun statuses: `running`, `awaiting_review`, `committing`, `completed`, `cancelled`, `failed`.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 3,\n  \"qbo_customer_ids\": [\n    512,\n    513,\n    514\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"run_id\": 12,\n    \"tracked_job_log_id\": 3411\n  },\n  \"message\": \"Match run started.\"\n}"}]},{"name":"Approve All Match Proposals","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/approve-all","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","approve-all"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"Approve every pending proposal in a match run, optionally narrowed to one confidence bucket and/or a search term. This is a bulk shortcut with the same behavior as submitting decisions: each approved proposal is linked immediately (the SKU.io customer ID is written onto the locally synced QuickBooks customer record and the proposal moves to `committed`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBody fields (both optional): `bucket` limits the approval to one confidence bucket (`auto`, `review`, or `hidden`); `search` limits it to proposals whose QuickBooks or SKU.io customer matches the term (name, company, or email, max 255 characters). Omit both to approve every pending proposal in the run.\n\nLinking modifies only the local synced copy in SKU.io; it does not modify anything in QuickBooks itself.\n\nProposals whose QuickBooks customer or SKU.io customer is already linked elsewhere are skipped and marked rejected with a `rejection_reason`. The response reports how many proposals were committed, rejected, and skipped.\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"bucket\": \"auto\",\n  \"search\": \"acme\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/approve-all","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","approve-all"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"committed\": 54,\n    \"rejected\": 0,\n    \"skipped\": 1,\n    \"errors\": []\n  },\n  \"message\": \"Approved 54 match(es).\"\n}"}]},{"name":"Commit Approved Match Proposals","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/commit","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","commit"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"Apply every proposal in the run that is still in `approved` status: each one writes the SKU.io customer ID onto the locally synced QuickBooks customer record and moves the proposal to `committed`. The run transitions through `committing` and finishes as `completed`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThis commits only the local synced copies in SKU.io; it does not modify anything in QuickBooks itself.\n\nNote that the decisions and approve-all endpoints already link approved proposals immediately, so this endpoint typically finds nothing left to commit unless proposals were approved through another flow. Proposals whose QuickBooks customer or SKU.io customer is already linked elsewhere are marked rejected with a `rejection_reason` instead of being committed; per-proposal failures are reported in `errors`.\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/commit","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","commit"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"committed\": 5,\n    \"errors\": []\n  },\n  \"message\": \"Committed 5 match(es).\"\n}"}]},{"name":"Submit Match Proposal Decisions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/decisions","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","decisions"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]},"description":"Approve and/or reject match proposals in bulk. Pass proposal IDs in `approve` and/or `reject`; IDs that do not belong to this run are silently ignored.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nApproving a proposal applies the link immediately: the SKU.io customer ID is written onto the locally synced QuickBooks customer record and the proposal moves to `committed` status. Rejecting simply marks the proposal `rejected`.\n\nLinking modifies only the local synced copy in SKU.io; it does not modify anything in QuickBooks itself.\n\nA proposal is skipped (counted in `skipped` and marked rejected with a `rejection_reason`) when the QuickBooks customer is already linked to a SKU.io customer, or when the SKU.io customer is already linked to a different QuickBooks customer. Per-proposal failures are reported in `errors` without failing the whole request.\n\nReturns 404 if the run does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"approve\": [\n    9101,\n    9102\n  ],\n  \"reject\": [\n    9103\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/customers/match-runs/{matchRun}/decisions","host":["{{baseUrl}}"],"path":["api","qbo","customers","match-runs",":matchRun","decisions"],"variable":[{"key":"matchRun","value":"","description":"The match run ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"committed\": 2,\n    \"rejected\": 1,\n    \"skipped\": 0,\n    \"errors\": []\n  },\n  \"message\": \"Decisions saved.\"\n}"}]},{"name":"Preview Customer Matching Results","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config/dry-run","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config","dry-run"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]},"description":"Preview how the currently saved matching configuration would classify a sample of unlinked QuickBooks Online customers, without creating a match run or persisting any proposals. Up to `sample_size` active, unlinked QuickBooks customers are scored against the SKU.io customer pool and the response reports how many would land in each bucket.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nBuckets: `auto` (score at or above the auto threshold), `review` (between the review and auto thresholds), `hidden` (below the review threshold), plus `unmatched` for customers with no scoring candidate at all.\n\nThis is a read-only preview computed synchronously from locally synced data - nothing is written in SKU.io and nothing is modified in QuickBooks. Save configuration changes first: the preview always uses the saved configuration, not values sent in this request.\n\nReturns 404 if the integration instance does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"sample_size\": 100\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/qbo/integration-instances/{integrationInstance}/matching-config/dry-run","host":["{{baseUrl}}"],"path":["api","qbo","integration-instances",":integrationInstance","matching-config","dry-run"],"variable":[{"key":"integrationInstance","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"sample_size\": 100,\n    \"auto\": 12,\n    \"review\": 30,\n    \"hidden\": 40,\n    \"unmatched\": 18\n  }\n}"}]},{"name":"List Vendor Credits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits"]},"description":"List mirrored QuickBooks vendor credits, paginated.\n\nAllowed sorts: id, doc_number, vendor_name, txn_date, total_amount, status, sync_status, last_synced_at, qbo_created_at, qbo_updated_at, created_at, updated_at. Prefix with - for descending. Default sort: -created_at.\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, vendor_name.\n\nThese documents are written to QuickBooks by SKU's ledger sync (or mirrored from QuickBooks), so the API surface is read-only — list and get only.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 12,\n      \"integration_instance_id\": 3,\n      \"qbo_id\": \"184\",\n      \"doc_number\": \"VC-1042\",\n      \"vendor_id\": \"56\",\n      \"vendor_name\": \"Shanghai Supplier Co\",\n      \"total_amount\": \"1250.00\",\n      \"currency\": \"USD\",\n      \"txn_date\": \"2026-07-01\",\n      \"status\": \"Open\",\n      \"active\": true,\n      \"sync_status\": \"ok\",\n      \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"sync_error_message\": null,\n      \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n      \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n      \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n      \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"QuickBooks Online\"\n      },\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/vendorcredit?txnId=184\"\n    }\n  ],\n  \"meta\": {\n    \"total\": 1,\n    \"per_page\": 15,\n    \"current_page\": 1,\n    \"last_page\": 1,\n    \"from\": 1,\n    \"to\": 1\n  },\n  \"links\": {\n    \"first\": \"…?page=1\",\n    \"last\": \"…?page=1\",\n    \"prev\": null,\n    \"next\": null\n  }\n}"}]},{"name":"Get Vendor Credit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits/{id}","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get one mirrored QuickBooks vendor credit.\n\nThe `linked_ledger_entry` field identifies the SKU ledger entry this QuickBooks document was created from (id, document number, and an app route). It is `null` when the document originated in QuickBooks rather than being pushed by SKU. This field is only present on the detail response, not on list rows.\n\n`qbo_link` deep-links to the vendor credit in the QuickBooks web UI.\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `vendor_link_id` cross-links to the mirrored QuickBooks vendor.\n\nAuthentication: Requires Bearer token. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits/{id}","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"184\",\n    \"doc_number\": \"VC-1042\",\n    \"vendor_id\": \"56\",\n    \"vendor_name\": \"Shanghai Supplier Co\",\n    \"total_amount\": \"1250.00\",\n    \"currency\": \"USD\",\n    \"txn_date\": \"2026-07-01\",\n    \"status\": \"Open\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/vendorcredit?txnId=184\",\n    \"vendor_link_id\": 57,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"linked_ledger_entry\": {\n      \"id\": 9021,\n      \"document_number\": \"VC-9021\",\n      \"route\": \"/ledger/entries/9021\"\n    },\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"184\",\n      \"DocNumber\": \"VC-1042\",\n      \"TxnDate\": \"2026-07-01\",\n      \"TotalAmt\": 1250,\n      \"VendorRef\": {\n        \"value\": \"56\",\n        \"name\": \"Shanghai Supplier Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Get Vendor Credit Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online vendor credit. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the vendor credit does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/vendor-credits/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","vendor-credits",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboVendorCredit\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/vendor-credits/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/vendor-credits/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/vendor-credits/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/vendor-credits/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Deposits","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/deposits","host":["{{baseUrl}}"],"path":["api","qbo","deposits"]},"description":"List mirrored QuickBooks bank deposits, paginated.\n\nAllowed sorts: id, txn_date, total_amount, sync_status, last_synced_at, qbo_created_at, qbo_updated_at, created_at, updated_at. Prefix with - for descending. Default sort: -created_at.\n\nSearchable columns (filter[search]): id, qbo_id.\n\nThese documents are written to QuickBooks by SKU's ledger sync (or mirrored from QuickBooks), so the API surface is read-only — list and get only.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/deposits","host":["{{baseUrl}}"],"path":["api","qbo","deposits"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 7,\n      \"integration_instance_id\": 3,\n      \"qbo_id\": \"441\",\n      \"total_amount\": \"10000.00\",\n      \"txn_date\": \"2026-07-01\",\n      \"active\": true,\n      \"sync_status\": \"ok\",\n      \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"sync_error_message\": null,\n      \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n      \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n      \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n      \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"QuickBooks Online\"\n      },\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/deposit?txnId=441\"\n    }\n  ],\n  \"meta\": {\n    \"total\": 1,\n    \"per_page\": 15,\n    \"current_page\": 1,\n    \"last_page\": 1,\n    \"from\": 1,\n    \"to\": 1\n  },\n  \"links\": {\n    \"first\": \"…?page=1\",\n    \"last\": \"…?page=1\",\n    \"prev\": null,\n    \"next\": null\n  }\n}"}]},{"name":"Get Deposit","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/deposits/{id}","host":["{{baseUrl}}"],"path":["api","qbo","deposits",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get one mirrored QuickBooks bank deposit.\n\nThe `linked_ledger_entry` field identifies the SKU ledger entry this QuickBooks document was created from (id, document number, and an app route). It is `null` when the document originated in QuickBooks rather than being pushed by SKU. This field is only present on the detail response, not on list rows.\n\n`qbo_link` deep-links to the deposit in the QuickBooks web UI.\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU.\n\nAuthentication: Requires Bearer token. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/deposits/{id}","host":["{{baseUrl}}"],"path":["api","qbo","deposits",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 7,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"441\",\n    \"total_amount\": \"10000.00\",\n    \"txn_date\": \"2026-07-01\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/deposit?txnId=441\",\n    \"linked_ledger_entry\": {\n      \"id\": 9105,\n      \"document_number\": \"PPR-9105\",\n      \"route\": \"/ledger/entries/9105\"\n    },\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"441\",\n      \"TxnDate\": \"2026-07-01\",\n      \"TotalAmt\": 10000,\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Get Deposit Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/deposits/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","deposits",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online deposit. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the deposit does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/deposits/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","deposits",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboDeposit\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/deposits/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/deposits/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/deposits/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/deposits/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Purchases","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchases","host":["{{baseUrl}}"],"path":["api","qbo","purchases"]},"description":"List mirrored QuickBooks purchases (expenses), paginated.\n\nAllowed sorts: id, doc_number, payment_type, txn_date, total_amount, sync_status, last_synced_at, qbo_created_at, qbo_updated_at, created_at, updated_at. Prefix with - for descending. Default sort: -created_at.\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, payment_type.\n\nThese documents are written to QuickBooks by SKU's ledger sync (or mirrored from QuickBooks), so the API surface is read-only — list and get only.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchases","host":["{{baseUrl}}"],"path":["api","qbo","purchases"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 21,\n      \"integration_instance_id\": 3,\n      \"qbo_id\": \"512\",\n      \"doc_number\": \"PP-10285\",\n      \"payment_type\": \"Check\",\n      \"total_amount\": \"10000.00\",\n      \"txn_date\": \"2026-06-28\",\n      \"active\": true,\n      \"sync_status\": \"ok\",\n      \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"sync_error_message\": null,\n      \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n      \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n      \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n      \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"QuickBooks Online\"\n      },\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/expense?txnId=512\"\n    }\n  ],\n  \"meta\": {\n    \"total\": 1,\n    \"per_page\": 15,\n    \"current_page\": 1,\n    \"last_page\": 1,\n    \"from\": 1,\n    \"to\": 1\n  },\n  \"links\": {\n    \"first\": \"…?page=1\",\n    \"last\": \"…?page=1\",\n    \"prev\": null,\n    \"next\": null\n  }\n}"}]},{"name":"Get Purchase","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchases/{id}","host":["{{baseUrl}}"],"path":["api","qbo","purchases",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get one mirrored QuickBooks purchase (expense).\n\nThe `linked_ledger_entry` field identifies the SKU ledger entry this QuickBooks document was created from (id, document number, and an app route). It is `null` when the document originated in QuickBooks rather than being pushed by SKU. This field is only present on the detail response, not on list rows.\n\n`qbo_link` deep-links to the expense in the QuickBooks web UI.\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU.\n\nAuthentication: Requires Bearer token. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchases/{id}","host":["{{baseUrl}}"],"path":["api","qbo","purchases",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 21,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"512\",\n    \"doc_number\": \"PP-10285\",\n    \"payment_type\": \"Check\",\n    \"total_amount\": \"10000.00\",\n    \"txn_date\": \"2026-06-28\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/expense?txnId=512\",\n    \"linked_ledger_entry\": {\n      \"id\": 10285,\n      \"document_number\": \"PP-10285\",\n      \"route\": \"/ledger/entries/10285\"\n    },\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Cold-chain freight\",\n        \"detail_type\": \"AccountBasedExpenseLineDetail\",\n        \"item\": null,\n        \"item_id\": null,\n        \"item_link_id\": null,\n        \"account\": \"Shipping & Freight\",\n        \"quantity\": null,\n        \"unit_price\": null,\n        \"amount\": 125,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"512\",\n      \"DocNumber\": \"PP-10285\",\n      \"TxnDate\": \"2026-06-28\",\n      \"TotalAmt\": 10000,\n      \"PaymentType\": \"Check\",\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"Amount\": 125,\n          \"DetailType\": \"AccountBasedExpenseLineDetail\",\n          \"Description\": \"Cold-chain freight\",\n          \"AccountBasedExpenseLineDetail\": {\n            \"AccountRef\": {\n              \"value\": \"63\",\n              \"name\": \"Shipping & Freight\"\n            }\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Get Purchase Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/purchases/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","purchases",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online purchase. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the purchase does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/purchases/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","purchases",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboPurchase\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/purchases/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/purchases/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/purchases/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/purchases/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Bill Payments","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bill-payments","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments"]},"description":"List mirrored QuickBooks bill payments, paginated. Each row includes its allocations — the bills / vendor credits the payment was applied to, with per-line amounts.\n\nAllowed sorts: id, doc_number, vendor_name, txn_date, total_amount, pay_type, sync_status, last_synced_at, qbo_created_at, qbo_updated_at, created_at, updated_at. Prefix with - for descending. Default sort: -created_at.\n\nSearchable columns (filter[search]): id, qbo_id, doc_number, vendor_name, private_note.\n\nThese documents are written to QuickBooks by SKU's ledger sync (or mirrored from QuickBooks), so the API surface is read-only — list and get only.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bill-payments","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 33,\n      \"integration_instance_id\": 3,\n      \"qbo_id\": \"901\",\n      \"vendor_id\": \"56\",\n      \"vendor_name\": \"Shanghai Supplier Co\",\n      \"total_amount\": \"0.00\",\n      \"currency\": \"USD\",\n      \"txn_date\": \"2026-07-02\",\n      \"pay_type\": \"Check\",\n      \"doc_number\": \"PPA-10290\",\n      \"private_note\": \"Vendor credit applied to bill\",\n      \"active\": true,\n      \"sync_status\": \"ok\",\n      \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n      \"sync_error_message\": null,\n      \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n      \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n      \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n      \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n      \"integration_instance\": {\n        \"id\": 3,\n        \"name\": \"QuickBooks Online\"\n      },\n      \"allocations\": [\n        {\n          \"id\": 61,\n          \"txn_type\": \"Bill\",\n          \"linked_txn_id\": \"777\",\n          \"amount\": \"125.50\"\n        },\n        {\n          \"id\": 62,\n          \"txn_type\": \"VendorCredit\",\n          \"linked_txn_id\": \"184\",\n          \"amount\": \"-125.50\"\n        }\n      ],\n      \"qbo_link\": \"https://app.qbo.intuit.com/app/billpayment?txnId=901\"\n    }\n  ],\n  \"meta\": {\n    \"total\": 1,\n    \"per_page\": 15,\n    \"current_page\": 1,\n    \"last_page\": 1,\n    \"from\": 1,\n    \"to\": 1\n  },\n  \"links\": {\n    \"first\": \"…?page=1\",\n    \"last\": \"…?page=1\",\n    \"prev\": null,\n    \"next\": null\n  }\n}"}]},{"name":"Get Bill Payment","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bill-payments/{id}","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Get one mirrored QuickBooks bill payment, including its allocations (which bills / vendor credits it settled and for how much).\n\nThe `linked_ledger_entry` field identifies the SKU ledger entry this QuickBooks document was created from (id, document number, and an app route). It is `null` when the document originated in QuickBooks rather than being pushed by SKU. This field is only present on the detail response, not on list rows.\n\n`qbo_link` deep-links to the bill payment in the QuickBooks web UI.\n\nThis document is pushed to QuickBooks by SKU's ledger, so the response includes reverse cross-link fields: `ledger_entry_id` and `ledger_entry_reference` identify the SKU ledger entry that pushed it, while `sku_link_type`, `sku_link_id`, `sku_link_label`, and `sku_link_route` point back to the originating SKU document. These are `null` when the document originated in QuickBooks rather than being pushed by SKU. `vendor_link_id` cross-links to the mirrored QuickBooks vendor.\n\nAuthentication: Requires Bearer token. Returns `line_items` (normalized line rows parsed from the stored QuickBooks payload) and `detail_payload` (the full raw QuickBooks payload); both are null until the document is re-synced from QuickBooks.\n\nAlso returns an `amounts` summary (`subtotal`, `tax`, `total`, `balance`, `paid`) and a `tax_code` on each `line_items` row."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bill-payments/{id}","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 33,\n    \"integration_instance_id\": 3,\n    \"qbo_id\": \"901\",\n    \"vendor_id\": \"56\",\n    \"vendor_name\": \"Shanghai Supplier Co\",\n    \"total_amount\": \"0.00\",\n    \"currency\": \"USD\",\n    \"txn_date\": \"2026-07-02\",\n    \"pay_type\": \"Check\",\n    \"doc_number\": \"PPA-10290\",\n    \"private_note\": \"Vendor credit applied to bill\",\n    \"active\": true,\n    \"sync_status\": \"ok\",\n    \"last_synced_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"last_qbo_check_at\": \"2026-07-15T10:00:00.000000Z\",\n    \"sync_error_message\": null,\n    \"qbo_created_at\": \"2026-07-01T09:00:00.000000Z\",\n    \"qbo_updated_at\": \"2026-07-14T18:30:00.000000Z\",\n    \"created_at\": \"2026-07-01T09:05:00.000000Z\",\n    \"updated_at\": \"2026-07-14T18:35:00.000000Z\",\n    \"integration_instance\": {\n      \"id\": 3,\n      \"name\": \"QuickBooks Online\"\n    },\n    \"allocations\": [\n      {\n        \"id\": 61,\n        \"txn_type\": \"Bill\",\n        \"linked_txn_id\": \"777\",\n        \"amount\": \"125.50\"\n      },\n      {\n        \"id\": 62,\n        \"txn_type\": \"VendorCredit\",\n        \"linked_txn_id\": \"184\",\n        \"amount\": \"-125.50\"\n      }\n    ],\n    \"qbo_link\": \"https://app.qbo.intuit.com/app/billpayment?txnId=901\",\n    \"vendor_link_id\": 57,\n    \"ledger_entry_id\": 12506,\n    \"ledger_entry_reference\": \"O260724VOY4F6/R1\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 4242,\n    \"sku_link_label\": \"Sales Order\",\n    \"sku_link_route\": \"/orders/sales-orders/4242\",\n    \"linked_ledger_entry\": {\n      \"id\": 10290,\n      \"document_number\": \"PPA-10290\",\n      \"route\": \"/ledger/entries/10290\"\n    },\n    \"amounts\": {\n      \"subtotal\": 550,\n      \"tax\": 40,\n      \"total\": 590,\n      \"balance\": 90,\n      \"paid\": 500\n    },\n    \"line_items\": [\n      {\n        \"line_num\": 1,\n        \"description\": \"Osetra Caviar 4.4 oz\",\n        \"detail_type\": \"SalesItemLineDetail\",\n        \"item\": \"RO125G\",\n        \"item_id\": \"70\",\n        \"item_link_id\": 42,\n        \"account\": null,\n        \"quantity\": 4,\n        \"unit_price\": 147.5,\n        \"amount\": 590,\n        \"tax_code\": \"TAX\",\n        \"posting_type\": null\n      }\n    ],\n    \"detail_payload\": {\n      \"Id\": \"901\",\n      \"DocNumber\": \"PPA-10290\",\n      \"TxnDate\": \"2026-07-02\",\n      \"TotalAmt\": 0,\n      \"VendorRef\": {\n        \"value\": \"56\",\n        \"name\": \"Shanghai Supplier Co\"\n      },\n      \"CurrencyRef\": {\n        \"value\": \"USD\"\n      },\n      \"Line\": [\n        {\n          \"Id\": \"1\",\n          \"LineNum\": 1,\n          \"Amount\": 590,\n          \"DetailType\": \"SalesItemLineDetail\",\n          \"Description\": \"Osetra Caviar 4.4 oz\",\n          \"SalesItemLineDetail\": {\n            \"ItemRef\": {\n              \"value\": \"21\",\n              \"name\": \"RO125G\"\n            },\n            \"Qty\": 4,\n            \"UnitPrice\": 147.5\n          }\n        }\n      ],\n      \"sparse\": false\n    }\n  }\n}"}]},{"name":"Get Bill Payment Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/bill-payments/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Retrieve the audit trail for a synced QuickBooks Online bill payment. Each entry records a create, update, or delete event on the local copy of the record, including the changed attributes, their previous values, and the user or process that made the change.\n\nResults are ordered newest first and paginated (standard pagination metadata is included in the response).\n\nReturns 404 if the bill payment does not exist.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/bill-payments/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","qbo","bill-payments",":id","activity-log"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 5821,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"QboBillPayment\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"attributes\": {\n          \"sync_status\": \"synced\"\n        },\n        \"old\": {\n          \"sync_status\": \"pending\"\n        },\n        \"source\": \"qbo_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-18T14:22:31.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"{{protocol}}://{{domain}}/api/qbo/bill-payments/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"{{protocol}}://{{domain}}/api/qbo/bill-payments/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"{{protocol}}://{{domain}}/api/qbo/bill-payments/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"{{protocol}}://{{domain}}/api/qbo/bill-payments/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"List Sync Activity","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/qbo/sync-activity","host":["{{baseUrl}}"],"path":["api","qbo","sync-activity"]},"description":"List QuickBooks sync-status transitions, newest first.\n\nDefault window: when no created_at filter is supplied, results cover the LAST 7 DAYS only. Supply any filter[created_at...] parameter to query older history.\n\nEach row records one status transition on a mirrored QuickBooks record: the record type and id, the old and new status, a human-readable reason, structured metadata, the acting user (null for system/polling changes), and the timestamp. The `entity` object resolves the mirrored record's QuickBooks id and its document identifier (document number or name) when the record still exists.\n\nSearchable columns (filter[search]): id, reason, entity_type.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/qbo/sync-activity","host":["{{baseUrl}}"],"path":["api","qbo","sync-activity"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 311,\n      \"entity_type\": \"Modules\\\\Qbo\\\\Entities\\\\QboInvoice\",\n      \"entity_type_label\": \"QboInvoice\",\n      \"entity_id\": 87,\n      \"entity\": {\n        \"qbo_id\": \"184\",\n        \"doc_identifier\": \"INV-1042\"\n      },\n      \"old_status\": \"ok\",\n      \"new_status\": \"qbo_updated\",\n      \"reason\": \"Status updated from QuickBooks data ingestion (refresh/CDC pull)\",\n      \"metadata\": {\n        \"qbo_id\": \"184\",\n        \"source\": \"qbo_data_ingestion\"\n      },\n      \"user\": null,\n      \"created_at\": \"2026-07-15T10:00:00.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"…?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"…?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"…/api/qbo/sync-activity\",\n  \"per_page\": 25,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]}]},{"name":"Xero","item":[{"name":"List Bank Transactions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/bank-transactions","host":["{{baseUrl}}"],"path":["api","xero","v2","bank-transactions"]},"description":"Paginated, filterable, sortable list of locally-cached Xero bank transactions (synced from Xero's BankTransactions API).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nFiltering goes through XeroEntityListing + AdvancedFilterBuilder, so every column accepts the full operator set both as `filter[column.operator]=value` AND inside the base64 `filter_groups` tree (the advanced-filter modal and the ever-present Type/Status/Reconciled/Date dropdowns).\n\nEach column also supports the `is_not` operator (e.g. `filter[status.is_not]=DELETED` to exclude voided transactions), plus the full operator set inside `filter_groups`.\n\nAllowed sorts: id, date, total, type, status, is_reconciled, contact_name, bank_account_name, reference, updated_at, created_at (default -date)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/bank-transactions","host":["{{baseUrl}}"],"path":["api","xero","v2","bank-transactions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 11501,\n      \"xero_uuid\": \"a5343cfe-f398-4c61-a550-6888c1e26e73\",\n      \"bank_transaction_id\": \"a5343cfe-f398-4c61-a550-6888c1e26e73\",\n      \"type\": \"SPEND\",\n      \"status\": \"AUTHORISED\",\n      \"is_reconciled\": false,\n      \"reference\": \"BELL SPORTS 866-5252357\",\n      \"contact_id\": \"c-1\",\n      \"contact_name\": \"Bell Sports\",\n      \"bank_account_id\": \"ba-1\",\n      \"bank_account_code\": \"202\",\n      \"bank_account_name\": \"AMEX xx-2001\",\n      \"currency_code\": \"USD\",\n      \"sub_total\": \"157.4700\",\n      \"total_tax\": \"0.0000\",\n      \"total\": \"157.4700\",\n      \"date\": \"2025-08-31T00:00:00+00:00\",\n      \"updated_date_utc\": \"2016-07-30T12:23:00+00:00\",\n      \"url\": \"https://go.xero.com/Bank/ViewTransaction.aspx?bankTransactionID=a5343cfe-f398-4c61-a550-6888c1e26e73\",\n      \"sync_status\": null,\n      \"last_error\": null,\n      \"created_at\": \"2026-06-26T22:50:00+00:00\",\n      \"updated_at\": \"2026-06-26T22:50:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"last_page\": 700,\n  \"total\": 17500,\n  \"from\": 1,\n  \"to\": 15\n}"}]},{"name":"Get Bank Transaction Detail","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/bank-transactions/{bankTransaction}","host":["{{baseUrl}}"],"path":["api","xero","v2","bank-transactions",":bankTransaction"],"variable":[{"key":"bankTransaction","value":"11501","description":"Local XeroBankTransaction id."}]},"description":"Full detail view for a single cached Xero bank transaction — header, contact, bank account, amounts, every line item, and the raw Xero `json_object` payload.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\nReturns 404 if the id does not exist."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/bank-transactions/{bankTransaction}","host":["{{baseUrl}}"],"path":["api","xero","v2","bank-transactions",":bankTransaction"],"variable":[{"key":"bankTransaction","value":"11501","description":"Local XeroBankTransaction id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11501,\n    \"xero_uuid\": \"a5343cfe-f398-4c61-a550-6888c1e26e73\",\n    \"bank_transaction_id\": \"a5343cfe-f398-4c61-a550-6888c1e26e73\",\n    \"type\": \"SPEND\",\n    \"status\": \"AUTHORISED\",\n    \"is_reconciled\": false,\n    \"reference\": \"BELL SPORTS 866-5252357\",\n    \"line_amount_types\": \"NoTax\",\n    \"contact_id\": \"c-1\",\n    \"contact_name\": \"Bell Sports\",\n    \"bank_account_id\": \"ba-1\",\n    \"bank_account_code\": \"202\",\n    \"bank_account_name\": \"AMEX xx-2001\",\n    \"currency_code\": \"USD\",\n    \"currency_rate\": \"1.000000\",\n    \"sub_total\": \"157.4700\",\n    \"total_tax\": \"0.0000\",\n    \"total\": \"157.4700\",\n    \"date\": \"2025-08-31T00:00:00+00:00\",\n    \"updated_date_utc\": \"2016-07-30T12:23:00+00:00\",\n    \"line_items\": [\n      {\n        \"line_item_id\": \"li-1\",\n        \"description\": null,\n        \"account_code\": \"500\",\n        \"quantity\": 1,\n        \"unit_amount\": 157.47,\n        \"tax_type\": \"NONE\",\n        \"tax_amount\": 0,\n        \"line_amount\": 157.47,\n        \"item_code\": null\n      }\n    ],\n    \"url\": \"https://go.xero.com/Bank/ViewTransaction.aspx?bankTransactionID=a5343cfe-f398-4c61-a550-6888c1e26e73\",\n    \"sync_status\": null,\n    \"last_error\": null,\n    \"created_at\": \"2026-06-26T22:50:00+00:00\",\n    \"updated_at\": \"2026-06-26T22:50:00+00:00\",\n    \"json_object\": {\n      \"BankTransactionID\": \"a5343cfe-f398-4c61-a550-6888c1e26e73\",\n      \"Type\": \"SPEND\",\n      \"Status\": \"AUTHORISED\",\n      \"IsReconciled\": false,\n      \"Total\": \"157.47\",\n      \"Contact\": {\n        \"ContactID\": \"c-1\",\n        \"Name\": \"Bell Sports\"\n      },\n      \"BankAccount\": {\n        \"AccountID\": \"ba-1\",\n        \"Code\": \"202\",\n        \"Name\": \"AMEX xx-2001\"\n      },\n      \"LineItems\": [\n        {\n          \"LineItemID\": \"li-1\",\n          \"AccountCode\": \"500\",\n          \"LineAmount\": 157.47\n        }\n      ]\n    }\n  }\n}"}]},{"name":"Sync Bank Transactions from Xero","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/bank-transactions/download","host":["{{baseUrl}}"],"path":["api","xero","bank-transactions","download"]},"description":"Dispatch a tracked background sync that pulls bank transactions from Xero's BankTransactions API into the local cache (paged 100/request, upserted by BankTransactionID).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Body (all optional, nullable dates Y-m-d):**\n- `date_from` — only transactions dated on/after (builds the Xero OData `Date >= DateTime(...)` filter)\n- `date_to` — only transactions dated on/before\n- `modified_after` — incremental: only records changed since (If-Modified-Since)\n\nAll null = full pull. Returns the tracked-job id so the UI can follow progress via the tracked job log endpoints.","body":{"mode":"raw","raw":"{\n  \"date_from\": \"2024-01-01\",\n  \"date_to\": \"2026-06-27\",\n  \"modified_after\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/bank-transactions/download","host":["{{baseUrl}}"],"path":["api","xero","bank-transactions","download"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 12345\n  }\n}"}]},{"name":"Generate OAuth URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/authorize","host":["{{baseUrl}}"],"path":["api","xero","authorize"]},"description":"Generate a Xero OAuth 2.0 authorization URL to initiate the connection flow. Redirect the user to the returned URL to authenticate with Xero.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/authorize","host":["{{baseUrl}}"],"path":["api","xero","authorize"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"url\": \"https://login.xero.com/identity/connect/authorize?response_type=code&client_id=...&redirect_uri=...&scope=openid+profile+email+accounting.transactions+offline_access&state=...\"\n  }\n}"}]},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/integrations","host":["{{baseUrl}}"],"path":["api","xero","integrations"]},"description":"List all Xero integration instances. Used by the application UI to determine whether to show the empty state (Connect to Xero) or the dashboard.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/integrations","host":["{{baseUrl}}"],"path":["api","xero","integrations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Xero Production\",\n      \"tenant_id\": \"abc123-tenant-uuid\",\n      \"sync_status\": \"active\",\n      \"is_automatic_sync_enabled\": true,\n      \"xero_webhook_enabled\": false,\n      \"integration_settings\": {\n        \"settings\": {\n          \"sync_start_date\": \"2024-01-01\"\n        }\n      }\n    }\n  ]\n}"}]},{"name":"Update Integration Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/integrations/{id}","host":["{{baseUrl}}"],"path":["api","xero","integrations",":id"],"variable":[{"key":"id","value":"1","description":"Xero integration instance ID"}]},"description":"Update Xero integration settings. All fields are optional.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- is_automatic_sync_enabled (optional, boolean): Enable/disable automatic sync\n- name (optional, string, max 255): Display name\n- sync_start_date (optional, date Y-m-d | null): Only sync transactions on or after this date","body":{"mode":"raw","raw":"{\n  \"is_automatic_sync_enabled\": true,\n  \"name\": \"Xero Production\",\n  \"sync_start_date\": \"2024-01-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/xero/integrations/{id}","host":["{{baseUrl}}"],"path":["api","xero","integrations",":id"],"variable":[{"key":"id","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Settings saved.\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Xero Production\",\n    \"is_automatic_sync_enabled\": true\n  }\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/xero/integrations/{id}","host":["{{baseUrl}}"],"path":["api","xero","integrations",":id"],"variable":[{"key":"id","value":"1","description":"Xero integration instance ID"}]},"description":"Delete a Xero integration instance and all associated data.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/xero/integrations/{id}","host":["{{baseUrl}}"],"path":["api","xero","integrations",":id"],"variable":[{"key":"id","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Xero integration deleted.\"\n}"}]},{"name":"Show Dashboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/dashboard","host":["{{baseUrl}}"],"path":["api","xero","dashboard"]},"description":"Get the Xero integration dashboard data including integration status, connection health, entity counts, and webhook summary.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns null data if no integration instance is configured."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/dashboard","host":["{{baseUrl}}"],"path":["api","xero","dashboard"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"integration_status\": {\n      \"id\": 1,\n      \"name\": \"Xero Production\",\n      \"tenant_id\": \"abc123-tenant-uuid\",\n      \"is_authenticated\": true,\n      \"is_automatic_sync_enabled\": true,\n      \"sync_status\": \"active\",\n      \"sync_start_date\": \"2024-01-01\"\n    },\n    \"connection_health\": {\n      \"daily_api_limit\": 5000,\n      \"daily_api_remaining\": 9850,\n      \"daily_api_reset_at\": \"2024-05-02T00:00:00Z\",\n      \"webhook_enabled\": false\n    },\n    \"entity_counts\": {\n      \"accounts\": 142,\n      \"tax_rates\": 8,\n      \"contacts\": 356,\n      \"invoices\": 1204,\n      \"bills\": 892,\n      \"credit_notes\": 47,\n      \"purchase_orders\": 211,\n      \"payments\": 2103,\n      \"manual_journals\": 15\n    },\n    \"webhook_summary\": {\n      \"enabled\": false,\n      \"events_last_24h\": 0,\n      \"failed_last_24h\": 0\n    }\n  }\n}"}]},{"name":"Download Accounts from Xero","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/xero/accounts/download","host":["{{baseUrl}}"],"path":["api","xero","accounts","download"]},"description":"Fetch and sync all accounts from the Xero API into the local database.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/accounts/download","host":["{{baseUrl}}"],"path":["api","xero","accounts","download"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Xero Accounts downloaded successfully.\"\n}"}]},{"name":"Create Nominal Codes from Accounts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/accounts/create-nominal-codes","host":["{{baseUrl}}"],"path":["api","xero","accounts","create-nominal-codes"]},"description":"Create SKU.io nominal codes from selected Xero account records. Requires an active Xero accounting integration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nBody:\n- ids (required, array of integers, min 1): Xero account IDs to create nominal codes from","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/accounts/create-nominal-codes","host":["{{baseUrl}}"],"path":["api","xero","accounts","create-nominal-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true\n}"}]},{"name":"Create Account in Xero (asset)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/accounts/create","host":["{{baseUrl}}"],"path":["api","xero","accounts","create"]},"description":"Create a GL account in the connected Xero tenant and mirror it locally. Type is restricted to Xero ASSET types (CURRENT/FIXED/NONCURRENT) — used by the onboarding flow to provision a missing inventory ASSET account (Xero won't let you post inventory journal movements to an INVENTORY-type account). Requires a connected Xero accounting integration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthenticate with a PAT.","body":{"mode":"raw","raw":"{\n  \"code\": \"1000\",\n  \"name\": \"Inventory Asset\",\n  \"type\": \"CURRENT\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/accounts/create","host":["{{baseUrl}}"],"path":["api","xero","accounts","create"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"code\": \"1000\",\n    \"name\": \"Inventory Asset\",\n    \"type\": \"CURRENT\",\n    \"class\": \"ASSET\"\n  },\n  \"message\": \"Account created in Xero.\"\n}"}]},{"name":"Nominal Code → Xero Account Suggestions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/accounts/nominal-code-suggestions","host":["{{baseUrl}}"],"path":["api","xero","accounts","nominal-code-suggestions"]},"description":"Smart-default suggestions for the onboarding mapping step: for each SKU nominal code, the Xero account it most likely maps to (matched by exact code → type → name). Read-only.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/accounts/nominal-code-suggestions","host":["{{baseUrl}}"],"path":["api","xero","accounts","nominal-code-suggestions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"nominal_code_id\": 12,\n      \"nominal_code\": \"4000\",\n      \"nominal_name\": \"Sales\",\n      \"nominal_type\": \"Revenue\",\n      \"xero_account_id\": 5,\n      \"xero_code\": \"4000\",\n      \"xero_name\": \"Sales\",\n      \"xero_type\": \"REVENUE\",\n      \"xero_class\": \"REVENUE\",\n      \"reason\": \"code\"\n    }\n  ]\n}"}]},{"name":"Map Nominal Codes → Xero Accounts","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/accounts/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","xero","accounts","nominal-code-mappings"]},"description":"Persist SKU nominal code → Xero account mappings (polymorphic integration_account link). Enforces the inventory→ASSET guard: rejects mapping any code to a Xero INVENTORY-type account, and requires the inventory-control role's code to map to an ASSET-class account (422 otherwise).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"nominal_code_id\": 12,\n      \"xero_account_id\": 5\n    },\n    {\n      \"nominal_code_id\": 7,\n      \"xero_account_id\": 9\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/accounts/nominal-code-mappings","host":["{{baseUrl}}"],"path":["api","xero","accounts","nominal-code-mappings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Nominal code mappings saved.\"\n}"}]},{"name":"Adopt Xero Chart of Accounts (hard-replace)","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/accounts/adopt-chart","host":["{{baseUrl}}"],"path":["api","xero","accounts","adopt-chart"]},"description":"Onboarding: hard-replace SKU's chart of accounts with Xero's. Imports every mapped Xero account as a nominal code, re-points every reference (sales order lines, settings roles, product/channel/warehouse overrides, …) onto the replacements, then deletes the old chart. EVERY existing nominal code must appear in `mappings` (a complete old→new map is what makes the delete safe) — otherwise 422-equivalent failure listing the unmapped ids. Runs as a tracked job; returns its log id so the UI can follow progress via the tracked job log endpoints. Pass `repost: true` to also repost every current ledger entry after the replace (chained inside the job) so posted GL lines pick up the new accounts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).","body":{"mode":"raw","raw":"{\n  \"mappings\": [\n    {\n      \"nominal_code_id\": 12,\n      \"xero_account_id\": 5\n    },\n    {\n      \"nominal_code_id\": 7,\n      \"xero_account_id\": 9\n    }\n  ],\n  \"repost\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/accounts/adopt-chart","host":["{{baseUrl}}"],"path":["api","xero","accounts","adopt-chart"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"tracked_job_log_id\": 4821\n  }\n}"}]},{"name":"Download Tax Rates from Xero","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/xero/tax-rates/download","host":["{{baseUrl}}"],"path":["api","xero","tax-rates","download"]},"description":"Fetch and sync tax rates from the Xero API.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/tax-rates/download","host":["{{baseUrl}}"],"path":["api","xero","tax-rates","download"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Tax rates downloaded successfully.\"\n}"}]},{"name":"Sync Contacts","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/xero/contacts/sync","host":["{{baseUrl}}"],"path":["api","xero","contacts","sync"]},"description":"Push your suppliers to Xero as contacts — creates or updates the matching Xero contact for each supplier. Requires a connected Xero integration with syncing active.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 422 with an `XeroNotConnected` error when the Xero connection is disconnected or its authorization has expired; reauthorize Xero before retrying."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/contacts/sync","host":["{{baseUrl}}"],"path":["api","xero","contacts","sync"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Contacts synced successfully.\"\n}"}]},{"name":"Link Contact to SKU Entity","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/link-sku-entity","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","link-sku-entity"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]},"description":"Link this Xero contact to a SKU.io customer or supplier via its polymorphic reverse link. Provide `link_type` (the SKU.io model class — `App\\\\Models\\\\Customer` or `App\\\\Models\\\\Supplier`) and `link_id` (that record's ID). Returns the updated contact with its resolved `sku_link_type`, `sku_link_id`, and `sku_link_reference`.\n\nReturns 422 when the referenced customer or supplier does not exist.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"link_type\": \"App\\\\Models\\\\Customer\",\n  \"link_id\": 1420\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/link-sku-entity","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","link-sku-entity"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"SKU Customer linked successfully.\",\n  \"data\": {\n    \"id\": 87,\n    \"contact_id\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"name\": \"Acme Retail Group\",\n    \"email\": \"accounts@acmeretail.com\",\n    \"phone\": \"1 415 5550172\",\n    \"is_customer\": true,\n    \"is_supplier\": false,\n    \"status\": \"ACTIVE\",\n    \"addresses\": [\n      {\n        \"type\": \"STREET\",\n        \"line1\": \"2251 Harrison St\",\n        \"line2\": \"Suite 400\",\n        \"line3\": null,\n        \"city\": \"San Francisco\",\n        \"postal_code\": \"94110\",\n        \"country\": \"United States\"\n      }\n    ],\n    \"sku_link_type\": \"App\\\\Models\\\\Customer\",\n    \"sku_link_id\": 1420,\n    \"sku_link_reference\": \"Acme Corp\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/Contacts/View/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"created_at\": \"2026-02-03T11:18:52+00:00\",\n    \"updated_at\": \"2026-06-28T04:02:19+00:00\"\n  }\n}"}]},{"name":"Unlink Contact from SKU Entity","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/unlink-sku-entity","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","unlink-sku-entity"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]},"description":"Clear this Xero contact's link to a SKU.io customer or supplier (nulls the polymorphic reverse link). Read-safe — leaves the contact record otherwise untouched.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/unlink-sku-entity","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","unlink-sku-entity"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"SKU entity unlinked successfully.\"\n}"}]},{"name":"List Accounts (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/accounts?page=1&per_page=15&sort=Name&filter[search]=revenue","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Sort column. Allowed: id, Name, Code, Type, Status, Class, created_at. Prefix with - for descending (e.g. -Name)","disabled":true},{"key":"filter[search]","value":"revenue","description":"Search by id, Name, or Code","disabled":true}]},"description":"Paginated list of Xero accounts with advanced filtering via Spatie QueryBuilder + GroupedFilterSupport.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nQuery Parameters:\n- page (optional, integer, default 1): Page number\n- per_page (optional, integer, default 15): Records per page\n- sort (optional, string): Allowed sorts: id, Name, Code, Type, Status, Class, created_at. Default: Name\n- filter[search] (optional, string): Search across id, Name, Code\n\nAdvanced Filters (filter_groups):\nSupports all operators: is, is_not, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty, is_one_of (text fields); greater_than, less_than, between (numeric).\nFilterable columns: id (numeric), Name (text), Code (text), Type (text), Class (text), Status (text)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/accounts?page=1&per_page=15&sort=Name&filter[search]=revenue","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Sort column. Allowed: id, Name, Code, Type, Status, Class, created_at. Prefix with - for descending (e.g. -Name)","disabled":true},{"key":"filter[search]","value":"revenue","description":"Search by id, Name, or Code","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"xero_integration_instance_id\": 1,\n      \"Code\": \"200\",\n      \"Name\": \"Sales\",\n      \"Type\": \"REVENUE\",\n      \"Status\": \"ACTIVE\",\n      \"Class\": \"REVENUE\",\n      \"Description\": \"Revenue from product sales\",\n      \"nominalCode\": {\n        \"id\": 3,\n        \"code\": \"200\",\n        \"name\": \"Sales\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 10,\n  \"per_page\": 15,\n  \"total\": 142\n}"}]},{"name":"List Tax Rates (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates?page=1&per_page=15&sort=Name&filter[search]=GST","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Allowed: id, Name, TaxType, EffectiveRate, created_at. Prefix - for descending","disabled":true},{"key":"filter[search]","value":"GST","description":"Search by id, Name, TaxType","disabled":true}]},"description":"Paginated list of Xero tax rates.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort options: id, Name, TaxType, EffectiveRate, created_at\n\nFilterable columns: id (numeric), Name (text), TaxType (text), EffectiveRate (numeric)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates?page=1&per_page=15&sort=Name&filter[search]=GST","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Allowed: id, Name, TaxType, EffectiveRate, created_at. Prefix - for descending","disabled":true},{"key":"filter[search]","value":"GST","description":"Search by id, Name, TaxType","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"Name\": \"GST on Income\",\n      \"TaxType\": \"OUTPUT\",\n      \"EffectiveRate\": 10,\n      \"Status\": \"ACTIVE\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 8\n}"}]},{"name":"List Contacts (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/contacts?page=1&per_page=15&sort=Name&filter[search]=acme","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Allowed: id, Name, ContactID, created_at. Prefix - for descending","disabled":true},{"key":"filter[search]","value":"acme","description":"Search by id, Name, ContactID","disabled":true}]},"description":"Paginated list of Xero contacts with advanced filtering.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort options: id, Name, ContactID, created_at\n\nFilterable columns: id (numeric), Name (text), ContactID (text), link_type (text — polymorphic FQN e.g. App\\Models\\Supplier)\n\nAlso includes computed fields: IsCustomer, IsSupplier (extracted from JSON object)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/contacts?page=1&per_page=15&sort=Name&filter[search]=acme","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"Name","description":"Allowed: id, Name, ContactID, created_at. Prefix - for descending","disabled":true},{"key":"filter[search]","value":"acme","description":"Search by id, Name, ContactID","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"xero_integration_instance_id\": 1,\n      \"ContactID\": \"xero-contact-uuid\",\n      \"Name\": \"Acme Corp\",\n      \"link_type\": \"App\\\\Models\\\\Supplier\",\n      \"link_id\": 5,\n      \"IsCustomer\": \"false\",\n      \"IsSupplier\": \"true\",\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 24,\n  \"per_page\": 15,\n  \"total\": 356\n}"}]},{"name":"List Invoices (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/invoices?page=1&per_page=15&sort=-updated_at&filter[search]=INV-001","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Allowed: id, xero_uuid, InvoiceNumber, Status, Date, DueDate, Total, AmountDue, AmountPaid, ContactName, CurrencyCode, updated_at, created_at","disabled":true},{"key":"filter[search]","value":"INV-001","description":"Search by id, xero_uuid, InvoiceNumber, Reference, ContactName, last_error","disabled":true}]},"description":"Paginated list of Xero invoices (ACCREC type) with advanced filtering via Spatie QueryBuilder + GroupedFilterSupport.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSort options: id, xero_uuid, InvoiceNumber, Status, Date, DueDate, Total, AmountDue, AmountPaid, ContactName, CurrencyCode, updated_at, created_at. Default: -updated_at\n\nFilterable columns:\n- Text: xero_uuid, InvoiceNumber, Reference, Status, sync_status, CurrencyCode, ContactID, ContactName, last_error, has_error (boolean-like), has_sku_link (boolean-like), sku_reference\n- Numeric: id, Total, SubTotal, TotalTax, AmountDue, AmountPaid, AmountCredited\n- Date (millis): Date, DueDate, FullyPaidOnDate, UpdatedDateUTC\n\nEach row includes: at_id, at_reference, at_type, sku_link_type, sku_link_id (flattened from accountingTransaction relation)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/invoices?page=1&per_page=15&sort=-updated_at&filter[search]=INV-001","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Allowed: id, xero_uuid, InvoiceNumber, Status, Date, DueDate, Total, AmountDue, AmountPaid, ContactName, CurrencyCode, updated_at, created_at","disabled":true},{"key":"filter[search]","value":"INV-001","description":"Search by id, xero_uuid, InvoiceNumber, Reference, ContactName, last_error","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 100,\n      \"xero_uuid\": \"xero-invoice-uuid-001\",\n      \"InvoiceNumber\": \"INV-001\",\n      \"Status\": \"AUTHORISED\",\n      \"sync_status\": \"synced\",\n      \"ContactID\": \"contact-uuid\",\n      \"ContactName\": \"Acme Corp\",\n      \"Date\": 1714521600000,\n      \"DueDate\": 1717113600000,\n      \"Total\": 1250,\n      \"SubTotal\": 1136.36,\n      \"TotalTax\": 113.64,\n      \"AmountDue\": 0,\n      \"AmountPaid\": 1250,\n      \"AmountCredited\": 0,\n      \"CurrencyCode\": \"AUD\",\n      \"last_error\": null,\n      \"at_id\": 55,\n      \"at_reference\": \"C-1001\",\n      \"at_type\": \"sales_order\",\n      \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"sku_link_id\": 1001,\n      \"created_at\": \"2024-05-01T10:00:00.000000Z\",\n      \"updated_at\": \"2024-05-01T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 81,\n  \"per_page\": 15,\n  \"total\": 1204\n}"}]},{"name":"List Bills (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/bills?page=1&per_page=15&sort=-updated_at&filter[search]=BILL-001","host":["{{baseUrl}}"],"path":["api","xero","v2","bills"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Allowed: id, xero_uuid, InvoiceNumber, Status, Date, DueDate, Total, AmountDue, AmountPaid, ContactName, CurrencyCode, updated_at, created_at","disabled":true},{"key":"filter[search]","value":"BILL-001","description":"Search by id, xero_uuid, InvoiceNumber, Reference, ContactName, last_error","disabled":true}]},"description":"Paginated list of Xero bills (ACCPAY type). Same filter and sort options as invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFilterable columns (identical to invoices): id, xero_uuid, InvoiceNumber, Reference, Status, sync_status, CurrencyCode, ContactID, ContactName, Total, SubTotal, TotalTax, AmountDue, AmountPaid, AmountCredited, Date (millis), DueDate (millis), FullyPaidOnDate (millis), UpdatedDateUTC (millis), last_error, has_error, has_sku_link, sku_reference"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/bills?page=1&per_page=15&sort=-updated_at&filter[search]=BILL-001","host":["{{baseUrl}}"],"path":["api","xero","v2","bills"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Allowed: id, xero_uuid, InvoiceNumber, Status, Date, DueDate, Total, AmountDue, AmountPaid, ContactName, CurrencyCode, updated_at, created_at","disabled":true},{"key":"filter[search]","value":"BILL-001","description":"Search by id, xero_uuid, InvoiceNumber, Reference, ContactName, last_error","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 200,\n      \"xero_uuid\": \"xero-bill-uuid-001\",\n      \"InvoiceNumber\": \"BILL-001\",\n      \"Status\": \"AUTHORISED\",\n      \"ContactName\": \"Global Supplies\",\n      \"Total\": 890,\n      \"AmountDue\": 890,\n      \"AmountPaid\": 0,\n      \"Date\": 1714521600000,\n      \"DueDate\": 1717113600000,\n      \"CurrencyCode\": \"USD\",\n      \"at_id\": null,\n      \"at_reference\": null,\n      \"at_type\": null,\n      \"sku_link_type\": null,\n      \"sku_link_id\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 60,\n  \"per_page\": 15,\n  \"total\": 892\n}"}]},{"name":"List Credit Notes (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column (same options as invoices endpoint)","disabled":true}]},"description":"Paginated list of Xero credit notes. Same filter and sort options as invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column (same options as invoices endpoint)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 300,\n      \"xero_uuid\": \"xero-cn-uuid-001\",\n      \"InvoiceNumber\": \"CN-001\",\n      \"Status\": \"AUTHORISED\",\n      \"ContactName\": \"Acme Corp\",\n      \"Total\": 250,\n      \"CurrencyCode\": \"AUD\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 4,\n  \"per_page\": 15,\n  \"total\": 47\n}"}]},{"name":"List Purchase Orders (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]},"description":"Paginated list of Xero purchase orders. Same filter and sort options as invoices.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 400,\n      \"xero_uuid\": \"xero-po-uuid-001\",\n      \"InvoiceNumber\": \"PO-001\",\n      \"Status\": \"AUTHORISED\",\n      \"ContactName\": \"Global Supplies\",\n      \"Total\": 5000,\n      \"CurrencyCode\": \"USD\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 15,\n  \"per_page\": 15,\n  \"total\": 211\n}"}]},{"name":"List Manual Journals (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]},"description":"Paginated list of Xero manual journal entries.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 500,\n      \"xero_uuid\": \"xero-mj-uuid-001\",\n      \"Status\": \"POSTED\",\n      \"created_at\": \"2024-04-01T10:00:00.000000Z\",\n      \"updated_at\": \"2024-04-01T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 15\n}"}]},{"name":"List Journals (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/journals","host":["{{baseUrl}}"],"path":["api","xero","v2","journals"]},"description":"Paginated list of Xero general-ledger journal lines.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach row is one flattened GL journal line pulled from Xero's immutable Journals feed (GET /Journals) — the provider side of the daily inventory reconciliation. Distinct from Manual Journals (/api/xero/v2/manual-journals), which are user-authored journals.\n\nAuthentication: Requires Bearer token.\n\nPagination: page (default 1), per_page (default 15).\n\nSorting (sort, prefix with - for DESC). Default: -journal_number (newest journals first, lines of the same journal kept adjacent). Allowed: id, journal_number, journal_date, account_code, account_name, source_type, net_amount, gross_amount, tax_amount, created_at, updated_at.\n\nSearch (filter[search]): partial match across account_code, account_name, source_type, source_id, journal_id (and exact id / journal_number when numeric).\n\nAdvanced filters (base64 filter_groups tree OR flat filter[&lt;col>][&lt;op>]=v). Numeric: id, journal_number, net_amount, gross_amount, tax_amount. Text: journal_id, account_code, account_name, source_type, source_id. Date: journal_date.\n\nnet_amount is signed: positive = debit, negative = credit.\n\naccount_local_id: the local XeroAccount id this line's account resolves to (account_id GUID first, account_code second). Use it to deep-link the account columns to /v2/integrations/xero/accounts/{id}. null when the account is not synced locally."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/journals","host":["{{baseUrl}}"],"path":["api","xero","v2","journals"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"integration_instance_id\": 12,\n      \"journal_id\": \"b1d2c3e4-0000-4a1b-9c2d-3e4f5a6b7c8d\",\n      \"journal_number\": 4821,\n      \"journal_date\": \"2024-04-30\",\n      \"source_id\": \"f7e6d5c4-1111-4b2c-8d3e-4f5a6b7c8d9e\",\n      \"source_type\": \"ACCREC\",\n      \"journal_line_id\": \"a9b8c7d6-2222-4c3d-9e4f-5a6b7c8d9e0f\",\n      \"account_id\": \"c3d4e5f6-3333-4d4e-af5a-6b7c8d9e0f1a\",\n      \"account_code\": \"200\",\n      \"account_name\": \"Sales\",\n      \"account_local_id\": 3,\n      \"net_amount\": \"-1250.00\",\n      \"gross_amount\": \"-1375.00\",\n      \"tax_amount\": \"-125.00\",\n      \"created_at\": \"2024-05-01T03:15:22.000000Z\",\n      \"updated_at\": \"2024-05-01T03:15:22.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 8\n}"}]},{"name":"Get Journal Detail (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/journals/{id}","host":["{{baseUrl}}"],"path":["api","xero","v2","journals",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Detail view of a single Xero general-ledger journal, grouped by journal_number.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns the journal header (number, Xero journal_id, date, source type/id, integration instance), every flattened GL line of that journal (including account_local_id for deep-linking each line's account), and computed totals (line_count, total_debit, total_credit, net, tax, gross, is_balanced).\n\nPath param: journalNumber (integer) — the Xero journal number.\n\nQuery param: integration_instance_id (integer, optional) — scope to a single connection. journal_number is only unique per connection, so pass this when more than one Xero connection exists.\n\nAuthentication: Requires Bearer token.\n\nnet_amount is signed: positive = debit, negative = credit. total_debit / total_credit are the absolute sums of the positive / negative net_amounts; is_balanced is true when they're equal.\n\n404 'Journal not found.' when no lines match the journal number (and instance, if supplied)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/journals/{id}","host":["{{baseUrl}}"],"path":["api","xero","v2","journals",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"journal_number\": 4821,\n    \"journal_id\": \"b1d2c3e4-0000-4a1b-9c2d-3e4f5a6b7c8d\",\n    \"journal_date\": \"2024-04-30\",\n    \"integration_instance_id\": 12,\n    \"source_type\": \"ACCREC\",\n    \"source_id\": \"f7e6d5c4-1111-4b2c-8d3e-4f5a6b7c8d9e\",\n    \"lines\": [\n      {\n        \"id\": 9001,\n        \"integration_instance_id\": 12,\n        \"journal_id\": \"b1d2c3e4-0000-4a1b-9c2d-3e4f5a6b7c8d\",\n        \"journal_number\": 4821,\n        \"journal_date\": \"2024-04-30\",\n        \"source_id\": \"f7e6d5c4-1111-4b2c-8d3e-4f5a6b7c8d9e\",\n        \"source_type\": \"ACCREC\",\n        \"journal_line_id\": \"a9b8c7d6-2222-4c3d-9e4f-5a6b7c8d9e0f\",\n        \"account_id\": \"c3d4e5f6-3333-4d4e-af5a-6b7c8d9e0f1a\",\n        \"account_code\": \"200\",\n        \"account_name\": \"Sales\",\n        \"account_local_id\": 3,\n        \"net_amount\": \"-1250.00\",\n        \"gross_amount\": \"-1375.00\",\n        \"tax_amount\": \"-125.00\",\n        \"created_at\": \"2024-05-01T03:15:22.000000Z\",\n        \"updated_at\": \"2024-05-01T03:15:22.000000Z\"\n      },\n      {\n        \"id\": 9002,\n        \"integration_instance_id\": 12,\n        \"journal_id\": \"b1d2c3e4-0000-4a1b-9c2d-3e4f5a6b7c8d\",\n        \"journal_number\": 4821,\n        \"journal_date\": \"2024-04-30\",\n        \"source_id\": \"f7e6d5c4-1111-4b2c-8d3e-4f5a6b7c8d9e\",\n        \"source_type\": \"ACCREC\",\n        \"journal_line_id\": \"b8c7d6e5-3333-4d4e-af5a-6b7c8d9e0f1b\",\n        \"account_id\": \"d4e5f6a7-4444-4e5f-b06b-7c8d9e0f1a2b\",\n        \"account_code\": \"610\",\n        \"account_name\": \"Accounts Receivable\",\n        \"account_local_id\": 7,\n        \"net_amount\": \"1375.00\",\n        \"gross_amount\": \"1375.00\",\n        \"tax_amount\": \"0.00\",\n        \"created_at\": \"2024-05-01T03:15:22.000000Z\",\n        \"updated_at\": \"2024-05-01T03:15:22.000000Z\"\n      }\n    ],\n    \"totals\": {\n      \"line_count\": 2,\n      \"total_debit\": \"1375.00\",\n      \"total_credit\": \"1250.00\",\n      \"net\": \"125.00\",\n      \"tax\": \"-125.00\",\n      \"gross\": \"0.00\",\n      \"is_balanced\": false\n    }\n  }\n}"}]},{"name":"List Payments (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/payments?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","payments"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]},"description":"Paginated list of Xero payments. Payments use a payment relation (not accountingTransaction) to link to SKU.io Payment entities.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/payments?page=1&per_page=15&sort=-updated_at","host":["{{baseUrl}}"],"path":["api","xero","v2","payments"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"per_page","value":"15","description":"Records per page (default: 15)","disabled":true},{"key":"sort","value":"-updated_at","description":"Sort column","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 600,\n      \"xero_uuid\": \"xero-payment-uuid-001\",\n      \"Amount\": 1250,\n      \"Date\": 1714521600000,\n      \"at_id\": null,\n      \"at_reference\": null,\n      \"at_type\": \"payment\",\n      \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"sku_link_id\": 1001,\n      \"created_at\": \"2024-05-01T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 141,\n  \"per_page\": 15,\n  \"total\": 2103\n}"}]},{"name":"Get Account (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/{account}","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts",":account"],"variable":[{"key":"account","value":"61","description":"xero_accounts.id"}]},"description":"Detail view-model for a single Xero account (chart of accounts) — backs the /v2/integrations/xero/accounts/{id} detail page. Returns the stored generated columns, descriptive fields that only live in the raw Xero json_object payload, the linked SKU nominal code, and local sync metadata.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Requires Bearer token.\n\n**Path parameters:**\n- account (required, integer): xero_accounts.id\n\n**nominal_code** is the SKU nominal code this account links to (null when unlinked). `link_basis` records how the link was resolved: `mapping` = an explicit polymorphic mapping (set by the onboarding wizard / QBO), `code` = inferred by matching xero_accounts.Code ⇄ nominal_codes.code (the fallback Xero's sync uses when a tenant adopted its chart). The frontend deep-links from here to /v2/ledger/accounts/{nominal_code.id}.\n\nXero accounts are config records: there is no remote deep-link, no line items and no per-record sync status, so those are intentionally omitted."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/{account}","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts",":account"],"variable":[{"key":"account","value":"61","description":"xero_accounts.id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 61,\n  \"account_id\": \"2c8b3e10-7f4a-4d2e-9b1c-5a6f8e0d1234\",\n  \"code\": \"510\",\n  \"name\": \"Shipping\",\n  \"type\": \"EXPENSE\",\n  \"class\": \"EXPENSE\",\n  \"status\": \"ACTIVE\",\n  \"description\": \"Shipping and freight costs\",\n  \"tax_type\": \"NONE\",\n  \"enable_payments_to_account\": false,\n  \"show_in_expense_claims\": false,\n  \"bank_account_number\": null,\n  \"bank_account_type\": null,\n  \"currency_code\": null,\n  \"reporting_code\": \"EXP\",\n  \"reporting_code_name\": \"Expense\",\n  \"system_account\": null,\n  \"updated_date_utc\": \"/Date(1718200000000+0000)/\",\n  \"nominal_code\": {\n    \"id\": 20,\n    \"code\": \"510\",\n    \"name\": \"Shipping\",\n    \"type\": \"Expense\",\n    \"link_basis\": \"code\"\n  },\n  \"created_at\": \"2026-05-20T08:14:32+00:00\",\n  \"updated_at\": \"2026-06-10T11:02:51+00:00\"\n}"}]},{"name":"Get Bill (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/bills/{bill}","host":["{{baseUrl}}"],"path":["api","xero","v2","bills",":bill"],"variable":[{"key":"bill","value":"128","description":"Internal bill record ID"}]},"description":"Get a single synced Xero bill (an ACCPAY invoice in Xero) — header fields, line items, the reverse link to the SKU.io record it was generated from, and sync metadata (`sync_status`, `last_error`, and `url`, a deep link to the bill in Xero). Monetary amounts are in the bill's currency; datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `bill` (integer, required): internal bill record ID — the `id` returned by List Bills (V2).\n\n**Reverse link fields:** `at_id`/`at_reference` identify the SKU.io accounting transaction the record was generated from (null when the record was synced via the ledger pipeline instead — then `ledger_entry_id`/`ledger_entry_reference` are set). `sku_link_type`/`sku_link_id` identify the underlying SKU.io source record (e.g. a sales order or purchase order); `sku_link_label` and `sku_link_route` are only populated when the link was resolved through the ledger.\n\nReturns 404 when no bill with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/bills/{bill}","host":["{{baseUrl}}"],"path":["api","xero","v2","bills",":bill"],"variable":[{"key":"bill","value":"128","description":"Internal bill record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 128,\n    \"xero_uuid\": \"3f1c9a2e-8b4d-4e7f-9a2c-6d5e4f3a2b1c\",\n    \"invoice_number\": \"BILL-0042\",\n    \"type\": \"ACCPAY\",\n    \"reference\": \"PO-812254\",\n    \"status\": \"AUTHORISED\",\n    \"contact_name\": \"Pacific Packaging Supplies\",\n    \"contact_id\": \"9c2d5e8f-1a4b-47c6-8d9e-3b2a1c4d5e6f\",\n    \"currency_code\": \"USD\",\n    \"sub_total\": 1250,\n    \"total_tax\": 125,\n    \"total\": 1375,\n    \"amount_due\": 1375,\n    \"amount_paid\": 0,\n    \"amount_credited\": 0,\n    \"date\": \"2026-05-14T00:00:00+00:00\",\n    \"due_date\": \"2026-06-13T00:00:00+00:00\",\n    \"fully_paid_on_date\": null,\n    \"updated_date_utc\": \"2026-05-15T08:21:44+00:00\",\n    \"line_items\": [\n      {\n        \"description\": \"Corrugated shipping boxes 12x9x4 (case of 250)\",\n        \"account_code\": \"310\",\n        \"item_code\": \"BOX-1294\",\n        \"quantity\": 4,\n        \"unit_amount\": 262.5,\n        \"tax_type\": \"INPUT\",\n        \"tax_amount\": 105,\n        \"line_amount\": 1050\n      },\n      {\n        \"description\": \"Packing tape 48mm (36 rolls)\",\n        \"account_code\": \"310\",\n        \"item_code\": \"TAPE-48\",\n        \"quantity\": 2,\n        \"unit_amount\": 100,\n        \"tax_type\": \"INPUT\",\n        \"tax_amount\": 20,\n        \"line_amount\": 200\n      }\n    ],\n    \"at_id\": 5121,\n    \"at_reference\": \"PO-812254\",\n    \"ledger_entry_id\": null,\n    \"ledger_entry_reference\": null,\n    \"sku_link_type\": \"App\\\\Models\\\\PurchaseInvoice\",\n    \"sku_link_id\": 344,\n    \"sku_link_label\": null,\n    \"sku_link_route\": null,\n    \"sync_status\": \"OK\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/AccountsPayable/View.aspx?InvoiceID=3f1c9a2e-8b4d-4e7f-9a2c-6d5e4f3a2b1c\",\n    \"created_at\": \"2026-05-14T18:03:29+00:00\",\n    \"updated_at\": \"2026-06-01T02:15:07+00:00\",\n    \"raw_payload\": {\n      \"InvoiceID\": \"3f1c9a2e-8b4d-4e7f-9a2c-6d5e4f3a2b1c\",\n      \"Type\": \"ACCPAY\",\n      \"InvoiceNumber\": \"BILL-0042\",\n      \"Reference\": \"PO-812254\",\n      \"Status\": \"AUTHORISED\",\n      \"LineAmountTypes\": \"Exclusive\",\n      \"Contact\": {\n        \"ContactID\": \"9c2d5e8f-1a4b-47c6-8d9e-3b2a1c4d5e6f\",\n        \"Name\": \"Pacific Packaging Supplies\"\n      },\n      \"CurrencyCode\": \"USD\",\n      \"SubTotal\": 1250,\n      \"TotalTax\": 125,\n      \"Total\": 1375,\n      \"AmountDue\": 1375,\n      \"AmountPaid\": 0,\n      \"Date\": \"2026-05-14\",\n      \"DueDate\": \"2026-06-13\",\n      \"LineItems\": [\n        {\n          \"LineItemID\": \"1d2c3b4a-5e6f-4a7b-8c9d-0e1f2a3b4c5d\",\n          \"Description\": \"Corrugated shipping boxes 12x9x4 (case of 250)\",\n          \"Quantity\": 4,\n          \"UnitAmount\": 262.5,\n          \"AccountCode\": \"310\",\n          \"TaxType\": \"INPUT\",\n          \"TaxAmount\": 105,\n          \"LineAmount\": 1050\n        }\n      ],\n      \"UpdatedDateUTC\": \"2026-05-15T08:21:44+00:00\"\n    }\n  }\n}"}]},{"name":"Get Contact (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]},"description":"Get a single synced Xero contact — name, primary email/phone, customer/supplier flags, status, addresses, the reverse link to the SKU.io customer or supplier it maps to (`sku_link_type`/`sku_link_id`), and sync metadata (`last_error`, plus `url`, a deep link to the contact in Xero).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nContacts are not a ledger sync target, so there is no accounting-transaction link — the SKU.io side is the contact's own link to a customer or supplier record.\n\n**Path parameters:**\n- `contact` (integer, required): internal contact record ID — the `id` returned by List Contacts (V2).\n\nReturns 404 when no contact with that ID exists.\n\n**Authentication:** Bearer token.\n\nAlso returns `sku_link_reference` — a human-readable label for the linked SKU.io customer or supplier."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 87,\n    \"contact_id\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"name\": \"Acme Retail Group\",\n    \"email\": \"accounts@acmeretail.com\",\n    \"phone\": \"1 415 5550172\",\n    \"is_customer\": true,\n    \"is_supplier\": false,\n    \"status\": \"ACTIVE\",\n    \"addresses\": [\n      {\n        \"type\": \"STREET\",\n        \"line1\": \"2251 Harrison St\",\n        \"line2\": \"Suite 400\",\n        \"line3\": null,\n        \"city\": \"San Francisco\",\n        \"postal_code\": \"94110\",\n        \"country\": \"United States\"\n      },\n      {\n        \"type\": \"POBOX\",\n        \"line1\": \"PO Box 7712\",\n        \"line2\": null,\n        \"line3\": null,\n        \"city\": \"San Francisco\",\n        \"postal_code\": \"94120\",\n        \"country\": \"United States\"\n      }\n    ],\n    \"sku_link_type\": \"App\\\\Models\\\\Customer\",\n    \"sku_link_id\": 412,\n    \"sku_link_reference\": \"Acme Corp\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/Contacts/View/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"created_at\": \"2026-02-03T11:18:52+00:00\",\n    \"updated_at\": \"2026-06-28T04:02:19+00:00\"\n  }\n}"}]},{"name":"Get Credit Note (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes/{creditNote}","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes",":creditNote"],"variable":[{"key":"creditNote","value":"56","description":"Internal credit note record ID"}]},"description":"Get a single synced Xero credit note (ACCRECCREDIT) — header fields including `remaining_credit`, line items, the reverse link to the SKU.io record it was generated from, and sync metadata (`sync_status`, `last_error`, and `url`, a deep link to the credit note in Xero). Monetary amounts are in the credit note's currency; datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `creditNote` (integer, required): internal credit note record ID — the `id` returned by List Credit Notes (V2).\n\n**Reverse link fields:** `at_id`/`at_reference` identify the SKU.io accounting transaction the record was generated from (null when the record was synced via the ledger pipeline instead — then `ledger_entry_id`/`ledger_entry_reference` are set). `sku_link_type`/`sku_link_id` identify the underlying SKU.io source record (e.g. a sales order or purchase order); `sku_link_label` and `sku_link_route` are only populated when the link was resolved through the ledger.\n\nReturns 404 when no credit note with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes/{creditNote}","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes",":creditNote"],"variable":[{"key":"creditNote","value":"56","description":"Internal credit note record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 56,\n    \"xero_uuid\": \"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d\",\n    \"credit_note_number\": \"CN-0218\",\n    \"type\": \"ACCRECCREDIT\",\n    \"reference\": \"C-100308254\",\n    \"status\": \"PAID\",\n    \"contact_name\": \"Acme Retail Group\",\n    \"contact_id\": \"7b1e4f3a-2c8d-49e5-b6a7-1f2e3d4c5b6a\",\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"sub_total\": 45.45,\n    \"total_tax\": 4.55,\n    \"total\": 50,\n    \"remaining_credit\": 0,\n    \"date\": \"2026-06-10T00:00:00+00:00\",\n    \"fully_paid_on_date\": \"2026-06-12T00:00:00+00:00\",\n    \"updated_date_utc\": \"2026-06-12T09:33:07+00:00\",\n    \"line_items\": [\n      {\n        \"description\": \"Return — LED strip light kit 5m (damaged in transit)\",\n        \"account_code\": \"200\",\n        \"item_code\": \"LED-5M-WW\",\n        \"quantity\": 1,\n        \"unit_amount\": 45.45,\n        \"tax_type\": \"OUTPUT\",\n        \"tax_amount\": 4.55,\n        \"line_amount\": 45.45\n      }\n    ],\n    \"at_id\": 5236,\n    \"at_reference\": \"C-100308254\",\n    \"ledger_entry_id\": null,\n    \"ledger_entry_reference\": null,\n    \"sku_link_type\": \"App\\\\Models\\\\SalesCredit\",\n    \"sku_link_id\": 1187,\n    \"sku_link_label\": null,\n    \"sku_link_route\": null,\n    \"sync_status\": \"OK\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/AccountsReceivable/ViewCreditNote.aspx?creditNoteID=a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d\",\n    \"created_at\": \"2026-06-10T14:47:33+00:00\",\n    \"updated_at\": \"2026-06-12T09:33:18+00:00\",\n    \"raw_payload\": {\n      \"CreditNoteID\": \"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d\",\n      \"Type\": \"ACCRECCREDIT\",\n      \"CreditNoteNumber\": \"CN-0031\",\n      \"Reference\": \"C-100308254\",\n      \"Status\": \"PAID\",\n      \"LineAmountTypes\": \"Exclusive\",\n      \"Contact\": {\n        \"ContactID\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n        \"Name\": \"Acme Retail Group\"\n      },\n      \"CurrencyCode\": \"USD\",\n      \"CurrencyRate\": 1,\n      \"SubTotal\": 45.45,\n      \"TotalTax\": 4.55,\n      \"Total\": 50,\n      \"RemainingCredit\": 0,\n      \"Date\": \"2026-05-20\",\n      \"LineItems\": [\n        {\n          \"LineItemID\": \"7f6e5d4c-3b2a-4190-8f7e-6d5c4b3a2190\",\n          \"Description\": \"Return credit — Widget Pro\",\n          \"Quantity\": 1,\n          \"UnitAmount\": 45.45,\n          \"AccountCode\": \"200\",\n          \"TaxType\": \"OUTPUT\",\n          \"TaxAmount\": 4.55,\n          \"LineAmount\": 45.45\n        }\n      ],\n      \"UpdatedDateUTC\": \"2026-05-21T10:05:00+00:00\"\n    }\n  }\n}"}]},{"name":"Get Invoice (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/invoices/{invoice}","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices",":invoice"],"variable":[{"key":"invoice","value":"342","description":"Internal invoice record ID"}]},"description":"Get a single synced Xero sales invoice (ACCREC) — header fields, line items, the reverse link to the SKU.io record it was generated from, and sync metadata (`sync_status`, `last_error`, and `url`, a deep link to the invoice in Xero). Monetary amounts are in the invoice's currency; datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `invoice` (integer, required): internal invoice record ID — the `id` returned by List Invoices (V2).\n\n**Reverse link fields:** `at_id`/`at_reference` identify the SKU.io accounting transaction the record was generated from (null when the record was synced via the ledger pipeline instead — then `ledger_entry_id`/`ledger_entry_reference` are set). `sku_link_type`/`sku_link_id` identify the underlying SKU.io source record (e.g. a sales order or purchase order); `sku_link_label` and `sku_link_route` are only populated when the link was resolved through the ledger.\n\nReturns 404 when no invoice with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/invoices/{invoice}","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices",":invoice"],"variable":[{"key":"invoice","value":"342","description":"Internal invoice record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 342,\n    \"xero_uuid\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n    \"invoice_number\": \"INV-10427\",\n    \"type\": \"ACCREC\",\n    \"reference\": \"SO-100482\",\n    \"status\": \"PAID\",\n    \"contact_name\": \"Acme Retail Group\",\n    \"contact_id\": \"7b1e4f3a-2c8d-49e5-b6a7-1f2e3d4c5b6a\",\n    \"currency_code\": \"USD\",\n    \"sub_total\": 206.82,\n    \"total_tax\": 20.68,\n    \"total\": 227.5,\n    \"amount_due\": 0,\n    \"amount_paid\": 227.5,\n    \"amount_credited\": 0,\n    \"date\": \"2026-06-02T00:00:00+00:00\",\n    \"due_date\": \"2026-07-02T00:00:00+00:00\",\n    \"fully_paid_on_date\": \"2026-06-19T00:00:00+00:00\",\n    \"updated_date_utc\": \"2026-06-19T10:41:03+00:00\",\n    \"line_items\": [\n      {\n        \"description\": \"LED strip light kit 5m — warm white\",\n        \"account_code\": \"200\",\n        \"item_code\": \"LED-5M-WW\",\n        \"quantity\": 5,\n        \"unit_amount\": 32.5,\n        \"tax_type\": \"OUTPUT\",\n        \"tax_amount\": 16.25,\n        \"line_amount\": 162.5\n      },\n      {\n        \"description\": \"Aluminium mounting channel 1m\",\n        \"account_code\": \"200\",\n        \"item_code\": \"ALU-CH-1M\",\n        \"quantity\": 8,\n        \"unit_amount\": 5.54,\n        \"tax_type\": \"OUTPUT\",\n        \"tax_amount\": 4.43,\n        \"line_amount\": 44.32\n      }\n    ],\n    \"at_id\": 4890,\n    \"at_reference\": \"SO-100482\",\n    \"ledger_entry_id\": null,\n    \"ledger_entry_reference\": null,\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 100482,\n    \"sku_link_label\": null,\n    \"sku_link_route\": null,\n    \"sync_status\": \"OK\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/AccountsReceivable/View.aspx?InvoiceID=b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n    \"created_at\": \"2026-06-02T15:22:40+00:00\",\n    \"updated_at\": \"2026-06-19T10:41:12+00:00\",\n    \"raw_payload\": {\n      \"InvoiceID\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n      \"Type\": \"ACCREC\",\n      \"InvoiceNumber\": \"INV-10427\",\n      \"Reference\": \"SO-100482\",\n      \"Status\": \"PAID\",\n      \"LineAmountTypes\": \"Exclusive\",\n      \"Contact\": {\n        \"ContactID\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n        \"Name\": \"Acme Retail Group\"\n      },\n      \"CurrencyCode\": \"USD\",\n      \"SubTotal\": 206.82,\n      \"TotalTax\": 20.68,\n      \"Total\": 227.5,\n      \"AmountDue\": 0,\n      \"AmountPaid\": 227.5,\n      \"Date\": \"2026-05-14\",\n      \"DueDate\": \"2026-06-13\",\n      \"LineItems\": [\n        {\n          \"LineItemID\": \"5b1e0c8a-7d2f-4e3a-9b6c-1a2b3c4d5e6f\",\n          \"Description\": \"Widget Pro (case of 12)\",\n          \"Quantity\": 1,\n          \"UnitAmount\": 206.82,\n          \"AccountCode\": \"200\",\n          \"TaxType\": \"OUTPUT\",\n          \"TaxAmount\": 20.68,\n          \"LineAmount\": 206.82\n        }\n      ],\n      \"UpdatedDateUTC\": \"2026-05-15T08:21:44+00:00\"\n    }\n  }\n}"}]},{"name":"Get Manual Journal (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals/{manualJournal}","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals",":manualJournal"],"variable":[{"key":"manualJournal","value":"44","description":"Internal manual journal record ID"}]},"description":"Get a single synced Xero manual journal — status, narration, journal lines (positive amounts are debits, negative are credits), the reverse link to the SKU.io record it was generated from, and sync metadata (`sync_status`, `last_error`, and `url`, a deep link to the journal in Xero). Datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `manualJournal` (integer, required): internal manual journal record ID — the `id` returned by List Manual Journals (V2).\n\n**Reverse link fields:** `at_id`/`at_reference` identify the SKU.io accounting transaction the record was generated from (null when the record was synced via the ledger pipeline instead — then `ledger_entry_id`/`ledger_entry_reference` are set). `sku_link_type`/`sku_link_id` identify the underlying SKU.io source record (e.g. a sales order or purchase order); `sku_link_label` and `sku_link_route` are only populated when the link was resolved through the ledger.\n\nReturns 404 when no manual journal with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals/{manualJournal}","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals",":manualJournal"],"variable":[{"key":"manualJournal","value":"44","description":"Internal manual journal record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 44,\n    \"xero_uuid\": \"c9d8e7f6-a5b4-43c2-9d1e-8f7a6b5c4d3e\",\n    \"manual_journal_id\": \"c9d8e7f6-a5b4-43c2-9d1e-8f7a6b5c4d3e\",\n    \"status\": \"POSTED\",\n    \"narration\": \"COGS accrual — June 2026 shipped orders\",\n    \"line_amount_types\": \"NoTax\",\n    \"show_on_cash_basis_reports\": true,\n    \"date\": \"2026-06-30T00:00:00+00:00\",\n    \"updated_date_utc\": \"2026-07-01T01:12:56+00:00\",\n    \"line_items\": [\n      {\n        \"description\": \"Cost of goods sold — June 2026\",\n        \"account_code\": \"500\",\n        \"tax_type\": \"NONE\",\n        \"tax_amount\": 0,\n        \"line_amount\": 18302.45\n      },\n      {\n        \"description\": \"Inventory asset relief — June 2026\",\n        \"account_code\": \"630\",\n        \"tax_type\": \"NONE\",\n        \"tax_amount\": 0,\n        \"line_amount\": -18302.45\n      }\n    ],\n    \"at_id\": null,\n    \"at_reference\": null,\n    \"ledger_entry_id\": 771,\n    \"ledger_entry_reference\": \"JE-2026-06-COGS\",\n    \"sku_link_type\": null,\n    \"sku_link_id\": null,\n    \"sku_link_label\": null,\n    \"sku_link_route\": null,\n    \"sync_status\": \"OK\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/Journal/View.aspx?invoiceID=c9d8e7f6-a5b4-43c2-9d1e-8f7a6b5c4d3e\",\n    \"created_at\": \"2026-07-01T01:12:40+00:00\",\n    \"updated_at\": \"2026-07-01T01:13:02+00:00\",\n    \"raw_payload\": {\n      \"ManualJournalID\": \"c9d8e7f6-a5b4-43c2-9d1e-8f7a6b5c4d3e\",\n      \"Status\": \"POSTED\",\n      \"Narration\": \"Month-end accrual — freight in transit\",\n      \"LineAmountTypes\": \"NoTax\",\n      \"ShowOnCashBasisReports\": true,\n      \"Date\": \"2026-05-31\",\n      \"JournalLines\": [\n        {\n          \"LineID\": \"0a1b2c3d-4e5f-4061-8a7b-2c3d4e5f6071\",\n          \"AccountCode\": \"310\",\n          \"Description\": \"Freight accrual\",\n          \"TaxType\": \"NONE\",\n          \"LineAmount\": 320\n        },\n        {\n          \"LineID\": \"1b2c3d4e-5f60-4172-9b8c-3d4e5f607182\",\n          \"AccountCode\": \"800\",\n          \"Description\": \"Accrued liabilities\",\n          \"TaxType\": \"NONE\",\n          \"LineAmount\": -320\n        }\n      ],\n      \"UpdatedDateUTC\": \"2026-06-01T02:15:07+00:00\"\n    }\n  }\n}"}]},{"name":"Get Payment (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/payments/{payment}","host":["{{baseUrl}}"],"path":["api","xero","v2","payments",":payment"],"variable":[{"key":"payment","value":"519","description":"Internal payment record ID"}]},"description":"Get a single synced Xero payment — amount, bank account, reconciliation state, the Xero invoice it was applied to (`invoice_id`/`invoice_number`), the reverse link to the SKU.io payment's source record (`sku_link_type`/`sku_link_id`/`sku_link_reference`), and sync metadata. Payments have no line items and no accounting-transaction link; sync health is derived from `last_error` (null = OK). Datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `payment` (integer, required): internal payment record ID — the `id` returned by List Payments (V2).\n\nReturns 404 when no payment with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/payments/{payment}","host":["{{baseUrl}}"],"path":["api","xero","v2","payments",":payment"],"variable":[{"key":"payment","value":"519","description":"Internal payment record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 519,\n    \"payment_id\": \"e2f3a4b5-c6d7-48e9-8f0a-1b2c3d4e5f6a\",\n    \"reference\": \"PAY-4471\",\n    \"status\": \"AUTHORISED\",\n    \"payment_type\": \"ACCRECPAYMENT\",\n    \"amount\": 227.5,\n    \"bank_amount\": 227.5,\n    \"currency_rate\": 1,\n    \"is_reconciled\": true,\n    \"bank_account_id\": \"f1e2d3c4-b5a6-4798-8c9d-0a1b2c3d4e5f\",\n    \"bank_account_code\": 90,\n    \"bank_account_name\": \"Business Checking\",\n    \"invoice_id\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n    \"invoice_number\": \"INV-10427\",\n    \"date\": \"2026-06-19T00:00:00+00:00\",\n    \"updated_date_utc\": \"2026-06-19T10:40:58+00:00\",\n    \"sku_link_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"sku_link_id\": 100482,\n    \"sku_link_reference\": \"114-4382991-7620254\",\n    \"last_error\": null,\n    \"url\": null,\n    \"created_at\": \"2026-06-19T10:41:20+00:00\",\n    \"updated_at\": \"2026-06-19T10:41:20+00:00\",\n    \"raw_payload\": {\n      \"PaymentID\": \"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b\",\n      \"Reference\": \"PAY-4471\",\n      \"Status\": \"AUTHORISED\",\n      \"PaymentType\": \"ACCRECPAYMENT\",\n      \"Amount\": 227.5,\n      \"BankAmount\": 227.5,\n      \"CurrencyRate\": 1,\n      \"IsReconciled\": true,\n      \"Date\": \"2026-06-02\",\n      \"Account\": {\n        \"AccountID\": \"6a5b4c3d-2e1f-4093-8a7b-6c5d4e3f2091\",\n        \"Code\": 90,\n        \"Name\": \"Business Checking\"\n      },\n      \"Invoice\": {\n        \"InvoiceID\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n        \"InvoiceNumber\": \"INV-10427\"\n      },\n      \"UpdatedDateUTC\": \"2026-06-02T09:30:11+00:00\"\n    }\n  }\n}"}]},{"name":"Get Purchase Order (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders",":purchaseOrder"],"variable":[{"key":"purchaseOrder","value":"73","description":"Internal purchase order record ID"}]},"description":"Get a single synced Xero purchase order — header and delivery fields, line items, the reverse link to the SKU.io accounting transaction and purchase order it was generated from (`at_id`/`at_reference`, `sku_link_type`/`sku_link_id`), and sync metadata (`sync_status`, `last_error`, and `url`, a deep link to the purchase order in Xero). Monetary amounts are in the order's currency; datetimes are UTC ISO-8601.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `purchaseOrder` (integer, required): internal purchase order record ID — the `id` returned by List Purchase Orders (V2).\n\nReturns 404 when no purchase order with that ID exists.\n\n**Authentication:** Bearer token.\n\nReturns `raw_payload` (the full raw Xero payload); present only on the detail/show endpoint."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders/{purchaseOrder}","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders",":purchaseOrder"],"variable":[{"key":"purchaseOrder","value":"73","description":"Internal purchase order record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 73,\n    \"xero_uuid\": \"d7c6b5a4-e3f2-41a0-9b8c-7d6e5f4a3b2c\",\n    \"purchase_order_number\": \"PO-812254\",\n    \"reference\": \"Restock — Q3 packaging\",\n    \"status\": \"BILLED\",\n    \"contact_name\": \"Pacific Packaging Supplies\",\n    \"contact_id\": \"9c2d5e8f-1a4b-47c6-8d9e-3b2a1c4d5e6f\",\n    \"attention_to\": \"Receiving Dept\",\n    \"telephone\": \"1 628 5550194\",\n    \"delivery_address\": \"48 Industrial Way, Oakland, CA 94607, United States\",\n    \"delivery_instructions\": \"Dock 3 — deliveries 8am-2pm only\",\n    \"currency_code\": \"USD\",\n    \"currency_rate\": 1,\n    \"sub_total\": 1250,\n    \"total_tax\": 125,\n    \"total\": 1375,\n    \"date\": \"2026-05-08T00:00:00+00:00\",\n    \"delivery_date\": \"2026-05-20T00:00:00+00:00\",\n    \"expected_arrival_date\": \"2026-05-22T00:00:00+00:00\",\n    \"updated_date_utc\": \"2026-05-15T08:20:31+00:00\",\n    \"line_items\": [\n      {\n        \"description\": \"Corrugated shipping boxes 12x9x4 (case of 250)\",\n        \"account_code\": \"310\",\n        \"item_code\": \"BOX-1294\",\n        \"quantity\": 4,\n        \"unit_amount\": 262.5,\n        \"tax_type\": \"INPUT\",\n        \"tax_amount\": 105,\n        \"line_amount\": 1050\n      },\n      {\n        \"description\": \"Packing tape 48mm (36 rolls)\",\n        \"account_code\": \"310\",\n        \"item_code\": \"TAPE-48\",\n        \"quantity\": 2,\n        \"unit_amount\": 100,\n        \"tax_type\": \"INPUT\",\n        \"tax_amount\": 20,\n        \"line_amount\": 200\n      }\n    ],\n    \"at_id\": 5098,\n    \"at_reference\": \"PO-812254\",\n    \"sku_link_type\": \"App\\\\Models\\\\PurchaseOrder\",\n    \"sku_link_id\": 2254,\n    \"sync_status\": \"OK\",\n    \"last_error\": null,\n    \"url\": \"https://go.xero.com/Accounts/Payable/PurchaseOrders/View/d7c6b5a4-e3f2-41a0-9b8c-7d6e5f4a3b2c\",\n    \"created_at\": \"2026-05-08T16:55:12+00:00\",\n    \"updated_at\": \"2026-06-01T02:15:07+00:00\",\n    \"raw_payload\": {\n      \"PurchaseOrderID\": \"d7c6b5a4-e3f2-41a0-9b8c-7d6e5f4a3b2c\",\n      \"PurchaseOrderNumber\": \"PO-812254\",\n      \"Reference\": \"Restock — Q3 packaging\",\n      \"Status\": \"BILLED\",\n      \"LineAmountTypes\": \"Exclusive\",\n      \"Contact\": {\n        \"ContactID\": \"9c2d5e8f-1a4b-47c6-8d9e-3b2a1c4d5e6f\",\n        \"Name\": \"Pacific Packaging Supplies\"\n      },\n      \"CurrencyCode\": \"USD\",\n      \"CurrencyRate\": 1,\n      \"SubTotal\": 1250,\n      \"TotalTax\": 125,\n      \"Total\": 1375,\n      \"Date\": \"2026-05-10\",\n      \"DeliveryDate\": \"2026-05-24\",\n      \"LineItems\": [\n        {\n          \"LineItemID\": \"2c3d4e5f-6071-4283-9c8d-4e5f60718293\",\n          \"Description\": \"Corrugated shipping boxes 12x9x4 (case of 250)\",\n          \"Quantity\": 4,\n          \"UnitAmount\": 262.5,\n          \"AccountCode\": \"310\",\n          \"TaxType\": \"INPUT\",\n          \"TaxAmount\": 105,\n          \"LineAmount\": 1050\n        }\n      ],\n      \"UpdatedDateUTC\": \"2026-05-15T08:21:44+00:00\"\n    }\n  }\n}"}]},{"name":"Get Tax Rate (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates/{taxRate}","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates",":taxRate"],"variable":[{"key":"taxRate","value":"5","description":"Internal tax rate record ID"}]},"description":"Get a single synced Xero tax rate — name, tax type, effective rate, status, applicability flags (`can_apply_to_*`), and the individual tax components that make up the rate. Tax rates are configuration records: they carry no line items and no reverse SKU.io link.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `taxRate` (integer, required): internal tax rate record ID — the `id` returned by List Tax Rates (V2).\n\nReturns 404 when no tax rate with that ID exists.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates/{taxRate}","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates",":taxRate"],"variable":[{"key":"taxRate","value":"5","description":"Internal tax rate record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Tax on Sales (8.875%)\",\n    \"tax_type\": \"OUTPUT\",\n    \"effective_rate\": 8.875,\n    \"status\": \"ACTIVE\",\n    \"report_tax_type\": \"OUTPUT\",\n    \"display_tax_rate\": 8.875,\n    \"can_apply_to_assets\": true,\n    \"can_apply_to_equity\": true,\n    \"can_apply_to_expenses\": true,\n    \"can_apply_to_liabilities\": true,\n    \"can_apply_to_revenue\": true,\n    \"tax_components\": [\n      {\n        \"name\": \"NY State Tax\",\n        \"rate\": 4,\n        \"is_compound\": false,\n        \"is_non_recoverable\": false\n      },\n      {\n        \"name\": \"NYC Local Tax\",\n        \"rate\": 4.875,\n        \"is_compound\": false,\n        \"is_non_recoverable\": false\n      }\n    ],\n    \"created_at\": \"2026-01-12T08:30:00+00:00\",\n    \"updated_at\": \"2026-06-20T02:15:07+00:00\"\n  }\n}"}]},{"name":"Get Account Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/{account}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts",":account","activity-log"],"variable":[{"key":"account","value":"61","description":"Internal account record ID"}]},"description":"Paginated change history for a single synced Xero account — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Accounts (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/{account}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts",":account","activity-log"],"variable":[{"key":"account","value":"61","description":"Internal account record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroAccount\",\n      \"subject_id\": 61,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Name\": \"Shipping & Freight\",\n          \"Status\": \"ACTIVE\"\n        },\n        \"old\": {\n          \"Name\": \"Shipping\",\n          \"Status\": \"ACTIVE\"\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroAccount\",\n      \"subject_id\": 61,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/accounts/61/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/accounts/61/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/accounts/61/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/accounts/61/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Bill Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/bills/{bill}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","bills",":bill","activity-log"],"variable":[{"key":"bill","value":"128","description":"Internal bill record ID"}]},"description":"Paginated change history for a single synced Xero bill — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Bills (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/bills/{bill}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","bills",":bill","activity-log"],"variable":[{"key":"bill","value":"128","description":"Internal bill record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroBill\",\n      \"subject_id\": 128,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Status\": \"PAID\",\n          \"AmountDue\": 0,\n          \"AmountPaid\": 1375\n        },\n        \"old\": {\n          \"Status\": \"AUTHORISED\",\n          \"AmountDue\": 1375,\n          \"AmountPaid\": 0\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroBill\",\n      \"subject_id\": 128,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/bills/128/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/bills/128/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/bills/128/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/bills/128/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Contact Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","activity-log"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]},"description":"Paginated change history for a single synced Xero contact — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Contacts (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/contacts/{contact}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","contacts",":contact","activity-log"],"variable":[{"key":"contact","value":"87","description":"Internal contact record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroContact\",\n      \"subject_id\": 87,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Name\": \"Acme Retail Group\",\n          \"link_id\": 412,\n          \"link_type\": \"App\\\\Models\\\\Customer\"\n        },\n        \"old\": {\n          \"Name\": \"Acme Retail\",\n          \"link_id\": null,\n          \"link_type\": null\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroContact\",\n      \"subject_id\": 87,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/contacts/87/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/contacts/87/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/contacts/87/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/contacts/87/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Credit Note Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes/{creditNote}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes",":creditNote","activity-log"],"variable":[{"key":"creditNote","value":"56","description":"Internal credit note record ID"}]},"description":"Paginated change history for a single synced Xero credit note — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Credit Notes (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/credit-notes/{creditNote}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","credit-notes",":creditNote","activity-log"],"variable":[{"key":"creditNote","value":"56","description":"Internal credit note record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroCreditNote\",\n      \"subject_id\": 56,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Status\": \"PAID\",\n          \"RemainingCredit\": 0\n        },\n        \"old\": {\n          \"Status\": \"AUTHORISED\",\n          \"RemainingCredit\": 50\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroCreditNote\",\n      \"subject_id\": 56,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/credit-notes/56/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/credit-notes/56/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/credit-notes/56/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/credit-notes/56/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Invoice Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/invoices/{invoice}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices",":invoice","activity-log"],"variable":[{"key":"invoice","value":"342","description":"Internal invoice record ID"}]},"description":"Paginated change history for a single synced Xero invoice — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Invoices (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/invoices/{invoice}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","invoices",":invoice","activity-log"],"variable":[{"key":"invoice","value":"342","description":"Internal invoice record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroInvoice\",\n      \"subject_id\": 342,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Status\": \"PAID\",\n          \"AmountDue\": 0,\n          \"AmountPaid\": 227.5\n        },\n        \"old\": {\n          \"Status\": \"AUTHORISED\",\n          \"AmountDue\": 227.5,\n          \"AmountPaid\": 0\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroInvoice\",\n      \"subject_id\": 342,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/invoices/342/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/invoices/342/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/invoices/342/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/invoices/342/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Manual Journal Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals/{manualJournal}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals",":manualJournal","activity-log"],"variable":[{"key":"manualJournal","value":"44","description":"Internal manual journal record ID"}]},"description":"Paginated change history for a single synced Xero manual journal — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Manual Journals (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/manual-journals/{manualJournal}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","manual-journals",":manualJournal","activity-log"],"variable":[{"key":"manualJournal","value":"44","description":"Internal manual journal record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroManualJournal\",\n      \"subject_id\": 44,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Status\": \"POSTED\",\n          \"sync_status\": \"OK\"\n        },\n        \"old\": {\n          \"Status\": \"DRAFT\",\n          \"sync_status\": null\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroManualJournal\",\n      \"subject_id\": 44,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/manual-journals/44/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/manual-journals/44/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/manual-journals/44/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/manual-journals/44/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Payment Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/payments/{payment}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","payments",":payment","activity-log"],"variable":[{"key":"payment","value":"519","description":"Internal payment record ID"}]},"description":"Paginated change history for a single synced Xero payment — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Payments (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/payments/{payment}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","payments",":payment","activity-log"],"variable":[{"key":"payment","value":"519","description":"Internal payment record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroPayment\",\n      \"subject_id\": 519,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"PaymentStatus\": \"AUTHORISED\",\n          \"IsReconciled\": true\n        },\n        \"old\": {\n          \"PaymentStatus\": \"AUTHORISED\",\n          \"IsReconciled\": false\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroPayment\",\n      \"subject_id\": 519,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/payments/519/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/payments/519/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/payments/519/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/payments/519/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Purchase Order Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders/{purchaseOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders",":purchaseOrder","activity-log"],"variable":[{"key":"purchaseOrder","value":"73","description":"Internal purchase order record ID"}]},"description":"Paginated change history for a single synced Xero purchase order — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Purchase Orders (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/purchase-orders/{purchaseOrder}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","purchase-orders",":purchaseOrder","activity-log"],"variable":[{"key":"purchaseOrder","value":"73","description":"Internal purchase order record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroPurchaseOrder\",\n      \"subject_id\": 73,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Status\": \"BILLED\",\n          \"Total\": 1375\n        },\n        \"old\": {\n          \"Status\": \"AUTHORISED\",\n          \"Total\": 1375\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroPurchaseOrder\",\n      \"subject_id\": 73,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/purchase-orders/73/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/purchase-orders/73/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/purchase-orders/73/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/purchase-orders/73/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Get Tax Rate Activity Log (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates/{taxRate}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates",":taxRate","activity-log"],"variable":[{"key":"taxRate","value":"5","description":"Internal tax rate record ID"}]},"description":"Paginated change history for a single synced Xero tax rate — one entry per recorded change, newest first. Each entry includes the change type (`event`: created / updated / deleted / bulk_upsert), the changed field values (`properties.attributes` = new values, `properties.old` = previous values), the source tag of whatever made the change (`properties.source`), an optional `batch_uuid` grouping changes made by one bulk operation, and `causer_name` (the user who triggered it; null for system/sync changes).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Query parameters:** `page`, `per_page` (default 15), `filter[event]`, `filter[source]`, `filter[batch_uuid]`, `filter[search]` — all optional.\n\n**Path parameters:** the record ID is the `id` returned by List Tax Rates (V2).\n\nReturns 404 when the record does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/tax-rates/{taxRate}/activity-log","host":["{{baseUrl}}"],"path":["api","xero","v2","tax-rates",":taxRate","activity-log"],"variable":[{"key":"taxRate","value":"5","description":"Internal tax rate record ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 98211,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"XeroTaxRate\",\n      \"subject_id\": 5,\n      \"batch_uuid\": null,\n      \"properties\": {\n        \"source\": \"xero_sync\",\n        \"attributes\": {\n          \"Name\": \"Tax on Sales (8.875%)\",\n          \"EffectiveRate\": 8.875\n        },\n        \"old\": {\n          \"Name\": \"Tax on Sales (8.5%)\",\n          \"EffectiveRate\": 8.5\n        }\n      },\n      \"causer_name\": null,\n      \"created_at\": \"2026-06-18T14:32:11.000000Z\"\n    },\n    {\n      \"id\": 97104,\n      \"description\": \"created\",\n      \"event\": \"created\",\n      \"subject_type\": \"XeroTaxRate\",\n      \"subject_id\": 5,\n      \"batch_uuid\": \"9d3f2a68-1c2b-4e0f-8a4d-6b1e2f3a4c5d\",\n      \"properties\": {\n        \"source\": \"xero_sync\"\n      },\n      \"causer_name\": \"Jane Smith\",\n      \"created_at\": \"2026-06-15T09:12:45.000000Z\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/v2/tax-rates/5/activity-log?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/v2/tax-rates/5/activity-log?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/v2/tax-rates/5/activity-log?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/v2/tax-rates/5/activity-log\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 2\n}"}]},{"name":"Export Accounts (V2)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/export?format=csv","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts","export"],"query":[{"key":"format","value":"csv","description":"File format: csv (default) or xlsx","disabled":true}]},"description":"Download the synced Xero chart of accounts as a CSV or XLSX file. Exports every account matching the given filters (no pagination) using the same filter parameters as List Accounts (V2). The response is a file attachment named `xero-accounts-<timestamp>.<format>`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Columns:** ID, AccountID, Name, Code, Type, Status, Class, SKU Account (the linked SKU.io ledger account name, blank when unlinked), Created At, Updated At.\n\n**Query parameters:** `format` (csv, default, or xlsx) plus optional filters — `filter[search]`, exact-match filters on Name/Code/Type/Class/Status/id (each also supports operator variants such as `filter[Name.contains]` and `filter[Status.is_not]`), and `filter_groups` (base64-encoded JSON tree for and/or combinations).\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/v2/accounts/export?format=csv","host":["{{baseUrl}}"],"path":["api","xero","v2","accounts","export"],"query":[{"key":"format","value":"csv","description":"File format: csv (default) or xlsx","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"ID,AccountID,Name,Code,Type,Status,Class,SKU Account,Created At,Updated At\n61,2c8b3e10-7f4a-4d2e-9b1c-5a6f8e0d1234,Shipping,510,EXPENSE,ACTIVE,EXPENSE,Shipping,2026-01-12 08:30:00,2026-06-20 02:15:07\n62,9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d,Sales,200,REVENUE,ACTIVE,REVENUE,Sales,2026-01-12 08:30:00,2026-06-20 02:15:07\n63,5f4e3d2c-1b0a-49f8-8e7d-6c5b4a3f2e1d,Business Checking,090,BANK,ACTIVE,ASSET,,2026-01-12 08:30:00,2026-06-20 02:15:07\n"}]},{"name":"Show Webhook Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Get the webhook settings for a Xero integration instance. Lazily generates a webhook UUID if one doesn't exist. Returns a masked signing key preview (first 4 + last 4 chars) and the 20 most recent webhook events.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"webhook_enabled\": false,\n    \"webhook_url\": \"https://app.sku.io/api/webhooks/xero/some-uuid-here\",\n    \"has_signing_key\": true,\n    \"signing_key_preview\": \"abcd...wxyz\",\n    \"recent_events\": [\n      {\n        \"id\": 1,\n        \"event_category\": \"INVOICE\",\n        \"event_type\": \"CREATE\",\n        \"resource_id\": \"xero-resource-uuid\",\n        \"status\": \"processed\",\n        \"error_message\": null,\n        \"created_at\": \"2024-05-01T09:00:00.000000Z\",\n        \"processed_at\": \"2024-05-01T09:00:05.000000Z\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Webhook Settings","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Enable or disable Xero webhooks and update the signing key. Key rotation is supported with a 1-hour grace period for the previous key.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- webhook_enabled (required, boolean): Enable or disable webhook processing\n- signing_key (optional, string, min 32 max 256): HMAC-SHA256 signing key from Xero\n\nErrors:\n- 422: Cannot enable webhooks without a signing key","body":{"mode":"raw","raw":"{\n  \"webhook_enabled\": true,\n  \"signing_key\": \"your-xero-webhook-signing-key-here-min-32-chars\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook settings saved.\",\n  \"data\": {\n    \"webhook_enabled\": true,\n    \"webhook_url\": \"https://app.sku.io/api/webhooks/xero/some-uuid-here\",\n    \"has_signing_key\": true\n  }\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Paginated feed of the webhook events Xero has delivered for this connection, newest first (by `event_date_utc`). Each event records what changed in Xero (`event_category` CONTACT / INVOICE / CREDITNOTE, `event_type` CREATE / UPDATE, `resource_id` — the Xero GUID), how it was handled (`status`: received, processing, processed, failed, duplicate, ignored; `processing_attempts`; `error_message`), the raw event payload as delivered by Xero, and `app_link`/`app_link_label` — a path to the synced record inside SKU.io (null until the referenced record has been synced in).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Sorting:** id, event_category, event_type, status, processing_attempts, event_date_utc, created_at, processed_at (prefix with - for descending; default -event_date_utc).\n\n**Filters:** filter[search] plus per-column filters on status, event_category, event_type, resource_id, error_message, id, processing_attempts, event_date_utc, created_at, processed_at. Text/numeric/date columns also accept operator variants (`filter[column.operator]`, e.g. `filter[status.is_not]=processed`, `filter[event_date_utc.between]=2026-07-01,2026-07-07`).\n\nReturns 404 when the integration instance does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1543,\n      \"event_category\": \"INVOICE\",\n      \"event_type\": \"UPDATE\",\n      \"resource_id\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n      \"resource_url\": \"https://api.xero.com/api.xro/2.0/Invoices/b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n      \"status\": \"processed\",\n      \"processing_attempts\": 1,\n      \"error_message\": null,\n      \"payload\": {\n        \"resourceUrl\": \"https://api.xero.com/api.xro/2.0/Invoices/b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n        \"resourceId\": \"b3a8c7d2-4e1f-4a9b-8c6d-2f5e7a9b1c3d\",\n        \"dataTypeName\": \"Invoice\",\n        \"eventDateUtc\": \"2026-07-01T14:05:22+00:00\",\n        \"eventType\": \"UPDATE\",\n        \"eventCategory\": \"INVOICE\",\n        \"tenantId\": \"8f7a6b5c-4d3e-42f1-9b8c-7d6e5f4a3b2c\",\n        \"tenantType\": \"ORGANISATION\",\n        \"eventSequence\": 1\n      },\n      \"app_link\": \"/integrations/xero/invoices/342\",\n      \"app_link_label\": \"Xero Invoice\",\n      \"event_date_utc\": \"2026-07-01T14:05:22+00:00\",\n      \"processed_at\": \"2026-07-01T14:05:31+00:00\",\n      \"created_at\": \"2026-07-01T14:05:24+00:00\"\n    },\n    {\n      \"id\": 1544,\n      \"event_category\": \"CONTACT\",\n      \"event_type\": \"CREATE\",\n      \"resource_id\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n      \"resource_url\": \"https://api.xero.com/api.xro/2.0/Contacts/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n      \"status\": \"failed\",\n      \"processing_attempts\": 3,\n      \"error_message\": \"Xero API rate limit exceeded while fetching contact d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n      \"payload\": {\n        \"resourceUrl\": \"https://api.xero.com/api.xro/2.0/Contacts/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n        \"resourceId\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n        \"dataTypeName\": \"Contact\",\n        \"eventDateUtc\": \"2026-07-01T14:09:47+00:00\",\n        \"eventType\": \"CREATE\",\n        \"eventCategory\": \"CONTACT\",\n        \"tenantId\": \"8f7a6b5c-4d3e-42f1-9b8c-7d6e5f4a3b2c\",\n        \"tenantType\": \"ORGANISATION\",\n        \"eventSequence\": 2\n      },\n      \"app_link\": null,\n      \"app_link_label\": null,\n      \"event_date_utc\": \"2026-07-01T14:09:47+00:00\",\n      \"processed_at\": null,\n      \"created_at\": \"2026-07-01T14:09:49+00:00\"\n    }\n  ],\n  \"first_page_url\": \"https://app.sku.io/api/xero/webhook-settings/1/events?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://app.sku.io/api/xero/webhook-settings/1/events?page=1\",\n  \"links\": [\n    {\n      \"url\": null,\n      \"label\": \"&laquo; Previous\",\n      \"active\": false\n    },\n    {\n      \"url\": \"https://app.sku.io/api/xero/webhook-settings/1/events?page=1\",\n      \"label\": \"1\",\n      \"active\": true\n    },\n    {\n      \"url\": null,\n      \"label\": \"Next &raquo;\",\n      \"active\": false\n    }\n  ],\n  \"next_page_url\": null,\n  \"path\": \"https://app.sku.io/api/xero/webhook-settings/1/events\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 2,\n  \"total\": 362\n}"}]},{"name":"Bulk Delete Webhook Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Permanently delete webhook events in bulk. This only removes the stored event records (the audit feed); it does not undo any data changes the events triggered. Requires an explicit `confirmation` value of `YES`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (one of two selection modes):**\n- `event_ids` (array of integers, required unless `apply_to_all` is true): explicit event IDs to delete. Each ID must exist.\n- `apply_to_all` (boolean, optional): when true, delete every event matching `filters` instead of an explicit ID list.\n- `filters` (object, optional, used with `apply_to_all`): flat filter map using the same keys as List Webhook Events' `filter[...]` parameters, e.g. `{\"status\": \"duplicate\"}`.\n- `confirmation` (string, required): must be exactly `YES`.\n\nReturns the number of rows removed.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 webhook event(s) deleted.\",\n  \"data\": {\n    \"deleted_count\": 2\n  }\n}"}]},{"name":"Get Webhook Events Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/summary","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","summary"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Per-status counts of every webhook event received for this connection, plus a `total`. Every known status is always present (zero-filled): received, processing, processed, failed, duplicate, ignored. Useful for monitoring webhook processing health — a growing `failed` count indicates events that need to be retried (see Retry Failed Webhook Events).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/summary","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","summary"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"received\": 2,\n    \"processing\": 0,\n    \"processed\": 341,\n    \"failed\": 4,\n    \"duplicate\": 12,\n    \"ignored\": 3,\n    \"total\": 362\n  }\n}"}]},{"name":"Reprocess Webhook Events","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/reprocess","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","reprocess"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Reprocess webhook events in bulk: each targeted event is reset to `received` status and a background job is queued per event to re-fetch the referenced record's current state from Xero. Returns immediately with the number of events queued; processing happens asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body (one of two selection modes):**\n- `event_ids` (array of integers, required unless `apply_to_all` is true): explicit event IDs to reprocess. Each ID must exist.\n- `apply_to_all` (boolean, optional): when true, reprocess every event matching `filters` instead of an explicit ID list.\n- `filters` (object, optional, used with `apply_to_all`): flat filter map using the same keys as List Webhook Events' `filter[...]` parameters, e.g. `{\"status\": \"failed\", \"event_category\": \"INVOICE\"}`.\n\n**Authentication:** Bearer token.","body":{"mode":"raw","raw":"{\n  \"event_ids\": [\n    1543,\n    1544\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/reprocess","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","reprocess"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook events queued for reprocessing.\",\n  \"data\": {\n    \"reprocessed_count\": 2\n  }\n}"}]},{"name":"Retry Failed Webhook Events","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/retry-failed","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","retry-failed"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Reprocess every currently-failed webhook event for this connection in one call — equivalent to Reprocess Webhook Events with all failed event IDs. Each failed event is reset to `received` and a background job is queued per event; the call returns immediately with the number of events queued, and processing happens asynchronously. No request body is required.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/retry-failed","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","retry-failed"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Failed webhook events queued for reprocessing.\",\n  \"data\": {\n    \"reprocessed_count\": 4\n  }\n}"}]},{"name":"Reprocess Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/{event}/reprocess","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events",":event","reprocess"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"},{"key":"event","value":"1544","description":"Webhook event ID"}]},"description":"Reprocess a single webhook event: resets it to `received` status and queues a background job that re-fetches the referenced record's current state from Xero. Returns the refreshed event immediately (status `received`, pending the queued job); processing happens asynchronously.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Path parameters:**\n- `integrationInstanceId` (integer, required): Xero integration instance ID.\n- `event` (integer, required): webhook event ID (the `id` from List Webhook Events).\n\nReturns 404 when the event does not exist.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/{event}/reprocess","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events",":event","reprocess"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"},{"key":"event","value":"1544","description":"Webhook event ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook event queued for reprocessing.\",\n  \"data\": {\n    \"id\": 1544,\n    \"event_category\": \"CONTACT\",\n    \"event_type\": \"CREATE\",\n    \"resource_id\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"resource_url\": \"https://api.xero.com/api.xro/2.0/Contacts/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"status\": \"received\",\n    \"processing_attempts\": 3,\n    \"error_message\": \"Xero API rate limit exceeded while fetching contact d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n    \"payload\": {\n      \"resourceUrl\": \"https://api.xero.com/api.xro/2.0/Contacts/d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n      \"resourceId\": \"d4e5f6a7-b8c9-40d1-a2b3-c4d5e6f7a8b9\",\n      \"dataTypeName\": \"Contact\",\n      \"eventDateUtc\": \"2026-07-01T14:09:47+00:00\",\n      \"eventType\": \"CREATE\",\n      \"eventCategory\": \"CONTACT\",\n      \"tenantId\": \"8f7a6b5c-4d3e-42f1-9b8c-7d6e5f4a3b2c\",\n      \"tenantType\": \"ORGANISATION\",\n      \"eventSequence\": 2\n    },\n    \"app_link\": null,\n    \"app_link_label\": null,\n    \"event_date_utc\": \"2026-07-01T14:09:47+00:00\",\n    \"processed_at\": null,\n    \"created_at\": \"2026-07-01T14:09:49+00:00\"\n  }\n}"}]},{"name":"Delete All Webhook Events","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/all","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","all"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]},"description":"Permanently delete every stored webhook event for this connection. This only clears the event history; it does not undo any data changes the events triggered, and it does not disable webhooks. Requires an explicit `confirmation` value of `YES`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body:**\n- `confirmation` (string, required): must be exactly `YES`.\n\nReturns the number of rows removed.\n\n**Authentication:** Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/xero/webhook-settings/{integrationInstanceId}/events/all","host":["{{baseUrl}}"],"path":["api","xero","webhook-settings",":integrationInstanceId","events","all"],"variable":[{"key":"integrationInstanceId","value":"1","description":"Xero integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"362 webhook event(s) deleted.\",\n  \"data\": {\n    \"deleted_count\": 362\n  }\n}"}]}]},{"name":"Stripe","item":[{"name":"Create Stripe Integration","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stripe/integrations","host":["{{baseUrl}}"],"path":["api","stripe","integrations"]},"description":"Creates a new Stripe integration instance (a placeholder before OAuth).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires admin or power-user permissions. The newly created instance is returned with `connected: false` until the OAuth flow has been completed via Start Authorization.","body":{"mode":"raw","raw":"{\n  \"name\": \"Main Store\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/integrations","host":["{{baseUrl}}"],"path":["api","stripe","integrations"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Main Store\",\n    \"sync_status\": \"active\",\n    \"connected\": false,\n    \"charges_enabled\": false,\n    \"payouts_enabled\": false,\n    \"details_submitted\": false,\n    \"default_currency\": \"USD\",\n    \"country\": \"US\",\n    \"email\": \"owner@example.com\",\n    \"display_name\": \"Acme Inc\",\n    \"business_name\": \"Acme Inc\",\n    \"business_url\": \"https://acme.example.com\",\n    \"capabilities\": {\n      \"card_payments\": \"active\",\n      \"transfers\": \"active\"\n    },\n    \"stripe_account_id\": null,\n    \"livemode\": false,\n    \"webhook_registered\": true,\n    \"last_reconciled_at\": \"2026-05-01T07:00:00.000000Z\",\n    \"disconnected_at\": null,\n    \"created_at\": \"2026-05-01T06:00:00.000000Z\",\n    \"updated_at\": \"2026-05-01T07:00:00.000000Z\"\n  },\n  \"message\": \"Stripe integration created.\"\n}"}]},{"name":"Show Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Returns a single Stripe integration instance with connection status, capabilities and account snapshot.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Main Store\",\n    \"sync_status\": \"active\",\n    \"connected\": true,\n    \"charges_enabled\": true,\n    \"payouts_enabled\": true,\n    \"details_submitted\": true,\n    \"default_currency\": \"USD\",\n    \"country\": \"US\",\n    \"email\": \"owner@example.com\",\n    \"display_name\": \"Acme Inc\",\n    \"business_name\": \"Acme Inc\",\n    \"business_url\": \"https://acme.example.com\",\n    \"capabilities\": {\n      \"card_payments\": \"active\",\n      \"transfers\": \"active\"\n    },\n    \"stripe_account_id\": \"acct_1Oxxxxxxx\",\n    \"livemode\": false,\n    \"webhook_registered\": true,\n    \"last_reconciled_at\": \"2026-05-01T07:00:00.000000Z\",\n    \"disconnected_at\": null,\n    \"created_at\": \"2026-05-01T06:00:00.000000Z\",\n    \"updated_at\": \"2026-05-01T07:00:00.000000Z\"\n  }\n}"}]},{"name":"Start Authorization (OAuth)","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/authorize","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","authorize"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Begins the Stripe Connect OAuth flow. Returns an `authorize_url` that the merchant should be redirected to in order to grant access. Stripe will redirect back to `/api/stripe/oauth/callback`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires admin or power-user permissions."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/authorize","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","authorize"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"authorize_url\": \"https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_test&scope=read_write&state=stripe_state_token\"\n  }\n}"}]},{"name":"Disconnect Integration","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/disconnect","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","disconnect"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Disconnects the Stripe integration — revokes the OAuth token at Stripe and clears the local access token. Past pay links continue to function, but new ones cannot be created until reconnected.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires admin or power-user permissions."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/disconnect","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","disconnect"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 7,\n    \"name\": \"Main Store\",\n    \"sync_status\": \"active\",\n    \"connected\": false,\n    \"charges_enabled\": true,\n    \"payouts_enabled\": true,\n    \"details_submitted\": true,\n    \"default_currency\": \"USD\",\n    \"country\": \"US\",\n    \"email\": \"owner@example.com\",\n    \"display_name\": \"Acme Inc\",\n    \"business_name\": \"Acme Inc\",\n    \"business_url\": \"https://acme.example.com\",\n    \"capabilities\": {\n      \"card_payments\": \"active\",\n      \"transfers\": \"active\"\n    },\n    \"stripe_account_id\": null,\n    \"livemode\": false,\n    \"webhook_registered\": true,\n    \"last_reconciled_at\": \"2026-05-01T07:00:00.000000Z\",\n    \"disconnected_at\": \"2026-05-01T07:00:00.000000Z\",\n    \"created_at\": \"2026-05-01T06:00:00.000000Z\",\n    \"updated_at\": \"2026-05-01T07:00:00.000000Z\"\n  },\n  \"message\": \"Stripe integration disconnected.\"\n}"}]},{"name":"Send Invoice","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stripe/invoices","host":["{{baseUrl}}"],"path":["api","stripe","invoices"]},"description":"Creates, finalizes, and sends a Stripe Invoice for a sales order. Stripe emails the customer the hosted invoice link automatically. If a payable open invoice already exists for the sales order it is returned instead of creating a new one (idempotent).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- `integration_instance_id` (required, integer) — the Stripe integration to charge through\n- `sales_order_id` (required, integer) — the sales order being invoiced\n- `amount_in_cents` (optional, integer, min 1) — override the order outstanding balance; if omitted the full outstanding balance is invoiced\n- `customer_email` (optional, email) — override the customer email on file (defaults to the sales order's customer email)\n\nRate limited: 30 requests/minute.","body":{"mode":"raw","raw":"{\n  \"integration_instance_id\": 7,\n  \"sales_order_id\": 1234,\n  \"amount_in_cents\": 19999,\n  \"customer_email\": \"buyer@example.com\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/invoices","host":["{{baseUrl}}"],"path":["api","stripe","invoices"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\"data\": {\"id\": 42, \"integration_instance_id\": 7, \"sales_order_id\": 1234, \"sales_order_number\": \"SO-2026-00100\"\u0002 \"user_id\": 8, \"stripe_invoice_id\": \"in_1Oabc123\", \"stripe_customer_id\": \"cus_OabcDEF\", \"stripe_payment_intent_id\": null, \"stripe_charge_id\": null, \"amount\": 19999, \"amount_paid\": 0, \"amount_refunded\": 0, \"currency\": \"USD\", \"status\": \"open\", \"customer_email\": \"buyer@example.com\", \"hosted_invoice_url\": \"https://invoice.stripe.com/i/acct_1Oabc/test_YWNjdF8x\", \"invoice_pdf\": \"https://pay.stripe.com/invoice/acct_1Oabc/invst_xxx/pdf\", \"days_until_due\": 30, \"due_date\": \"2026-06-01T00:00:00.000000Z\", \"finalized_at\": \"2026-05-01T07:30:00.000000Z\", \"paid_at\": null, \"voided_at\": null, \"last_refunded_at\": null, \"metadata\": {\"sku9_sales_order_id\": 1234, \"sku9_user_id\": 8}, \"created_at\": \"2026-05-01T07:30:00.000000Z\", \"updated_at\": \"2026-05-01T07:30:00.000000Z\"}, \"message\": \"Invoice sent to customer.\"}"}]},{"name":"Show Invoice","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id"],"variable":[{"key":"id","value":"42","description":"Local SKU.io Stripe invoice ID"}]},"description":"Returns a single Stripe Invoice with its linked Sales Order number (when set) and integration instance.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe `sales_order_number` field on the response is loaded via `whenLoaded('salesOrder')` and reflects the SKU.io sales order's human-readable number (e.g. `SO-2026-00100`). The `sales_order_id` may be null for orphaned invoices.\n\nUsed by the Stripe Invoice detail page (`/v2/integrations/stripe/:id/invoices/:invoiceId`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id"],"variable":[{"key":"id","value":"42","description":"Local SKU.io Stripe invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_instance_id\": 7,\n    \"sales_order_id\": 1234,\n    \"sales_order_number\": \"SO-2026-00100\",\n    \"user_id\": 8,\n    \"stripe_invoice_id\": \"in_1Oabc123\",\n    \"stripe_customer_id\": \"cus_OabcDEF\",\n    \"stripe_payment_intent_id\": \"pi_3Oabc456\",\n    \"stripe_charge_id\": \"ch_3Oabc789\",\n    \"amount\": 19999,\n    \"amount_paid\": 19999,\n    \"amount_refunded\": 0,\n    \"currency\": \"USD\",\n    \"status\": \"paid\",\n    \"customer_email\": \"customer@example.com\",\n    \"hosted_invoice_url\": \"https://invoice.stripe.com/i/acct_xxx/test_yyy\",\n    \"invoice_pdf\": \"https://invoice.stripe.com/i/acct_xxx/test_yyy/pdf\",\n    \"days_until_due\": 15,\n    \"due_date\": \"2026-06-22T00:00:00.000000Z\",\n    \"finalized_at\": \"2026-06-04T05:09:00.000000Z\",\n    \"paid_at\": \"2026-06-05T05:09:00.000000Z\",\n    \"voided_at\": null,\n    \"last_refunded_at\": null,\n    \"metadata\": {\n      \"sales_order_id\": 1234,\n      \"order_number\": \"SO-2026-00100\"\n    },\n    \"created_at\": \"2026-06-02T05:09:00.000000Z\",\n    \"updated_at\": \"2026-06-05T05:09:00.000000Z\"\n  }\n}"}]},{"name":"Get Invoice Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","activity-log"],"variable":[{"key":"id","value":"42","description":"Local SKU.io Stripe invoice ID"}]},"description":"Returns the chronological list of Stripe webhook events linked to this invoice via `related_object_id` matching the invoice's `stripe_invoice_id`, `stripe_payment_intent_id`, or `stripe_charge_id`.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nActs as the audit / activity log for the invoice lifecycle (created → finalized → paid → refunded / voided). Events are sorted by `event_created_at` descending (newest first).\n\nThe response is a flat collection — not paginated — because the activity log for one invoice is bounded (typically <20 events)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/activity-log","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","activity-log"],"variable":[{"key":"id","value":"42","description":"Local SKU.io Stripe invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 305,\n      \"integration_instance_id\": 7,\n      \"stripe_event_id\": \"evt_3Oabc789\",\n      \"event_type\": \"invoice.paid\",\n      \"account_id\": \"acct_live_xxx\",\n      \"livemode\": true,\n      \"related_object_id\": \"in_1Oabc123\",\n      \"status\": \"processed\",\n      \"attempts\": 1,\n      \"last_error\": null,\n      \"event_created_at\": \"2026-06-05T05:09:00.000000Z\",\n      \"processed_at\": \"2026-06-05T05:09:01.000000Z\",\n      \"created_at\": \"2026-06-05T05:09:00.000000Z\",\n      \"updated_at\": \"2026-06-05T05:09:01.000000Z\"\n    },\n    {\n      \"id\": 303,\n      \"integration_instance_id\": 7,\n      \"stripe_event_id\": \"evt_3Oabc456\",\n      \"event_type\": \"invoice.finalized\",\n      \"account_id\": \"acct_live_xxx\",\n      \"livemode\": true,\n      \"related_object_id\": \"in_1Oabc123\",\n      \"status\": \"processed\",\n      \"attempts\": 1,\n      \"last_error\": null,\n      \"event_created_at\": \"2026-06-04T05:09:00.000000Z\",\n      \"processed_at\": \"2026-06-04T05:09:01.000000Z\",\n      \"created_at\": \"2026-06-04T05:09:00.000000Z\",\n      \"updated_at\": \"2026-06-04T05:09:01.000000Z\"\n    }\n  ]\n}"}]},{"name":"Void Invoice","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/void","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","void"],"variable":[{"key":"id","value":"42","description":"Local SKU.io invoice ID"}]},"description":"Voids an open Stripe Invoice. Voiding marks the invoice uncollectable at Stripe so the customer cannot pay it anymore. Only valid for invoices in `open` or `draft` status — paid invoices cannot be voided (issue a refund instead).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/void","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","void"],"variable":[{"key":"id","value":"42","description":"Local SKU.io invoice ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\"data\": {\"id\": 42, \"integration_instance_id\": 7, \"sales_order_id\": 1234, \"sales_order_number\": \"SO-2026-00100\"\u0002 \"user_id\": 8, \"stripe_invoice_id\": \"in_1Oabc123\", \"stripe_customer_id\": \"cus_OabcDEF\", \"stripe_payment_intent_id\": null, \"stripe_charge_id\": null, \"amount\": 19999, \"amount_paid\": 0, \"amount_refunded\": 0, \"currency\": \"USD\", \"status\": \"void\", \"customer_email\": \"buyer@example.com\", \"hosted_invoice_url\": \"https://invoice.stripe.com/i/acct_1Oabc/test_YWNjdF8x\", \"invoice_pdf\": \"https://pay.stripe.com/invoice/acct_1Oabc/invst_xxx/pdf\", \"days_until_due\": 30, \"due_date\": \"2026-06-01T00:00:00.000000Z\", \"finalized_at\": \"2026-05-01T07:30:00.000000Z\", \"paid_at\": null, \"voided_at\": \"2026-05-01T08:30:00.000000Z\", \"last_refunded_at\": null, \"metadata\": {\"sku9_sales_order_id\": 1234, \"sku9_user_id\": 8}, \"created_at\": \"2026-05-01T07:30:00.000000Z\", \"updated_at\": \"2026-05-01T08:30:00.000000Z\"}, \"message\": \"Invoice voided.\"}"}]},{"name":"List Invoices by Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/invoices","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","invoices"],"variable":[{"key":"id","value":"7","description":"Stripe integration instance ID"}]},"description":"Returns a paginated list of all Stripe Invoices for a Stripe integration instance, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/integrations/{id}/invoices","host":["{{baseUrl}}"],"path":["api","stripe","integrations",":id","invoices"],"variable":[{"key":"id","value":"7","description":"Stripe integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\"current_page\": 1, \"data\": [{\"id\": 42, \"integration_instance_id\": 7, \"sales_order_id\": 1234, \"sales_order_number\": \"SO-2026-00100\"\u0002 \"user_id\": 8, \"stripe_invoice_id\": \"in_1Oabc123\", \"stripe_customer_id\": \"cus_OabcDEF\", \"stripe_payment_intent_id\": \"pi_3OabcDEF\", \"stripe_charge_id\": \"ch_3OabcDEF\", \"amount\": 19999, \"amount_paid\": 19999, \"amount_refunded\": 0, \"currency\": \"USD\", \"status\": \"paid\", \"customer_email\": \"buyer@example.com\", \"hosted_invoice_url\": \"https://invoice.stripe.com/i/acct_1Oabc/test_YWNjdF8x\", \"invoice_pdf\": \"https://pay.stripe.com/invoice/acct_1Oabc/invst_xxx/pdf\", \"days_until_due\": 30, \"due_date\": \"2026-06-01T00:00:00.000000Z\", \"finalized_at\": \"2026-05-01T07:30:00.000000Z\", \"paid_at\": \"2026-05-01T08:00:00.000000Z\", \"voided_at\": null, \"last_refunded_at\": null, \"metadata\": {\"sku9_sales_order_id\": 1234, \"sku9_user_id\": 8}, \"created_at\": \"2026-05-01T07:30:00.000000Z\", \"updated_at\": \"2026-05-01T08:00:00.000000Z\"}], \"per_page\": 25, \"total\": 1, \"last_page\": 1}"}]},{"name":"List Invoices for Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/sales-orders/{salesOrderId}/invoices","host":["{{baseUrl}}"],"path":["api","stripe","sales-orders",":salesOrderId","invoices"],"variable":[{"key":"salesOrderId","value":"1234","description":"Sales order ID"}]},"description":"Returns all Stripe Invoices linked to a sales order across all Stripe integration instances, newest first. Used by the sales order detail page to render the Stripe Invoices panel.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/sales-orders/{salesOrderId}/invoices","host":["{{baseUrl}}"],"path":["api","stripe","sales-orders",":salesOrderId","invoices"],"variable":[{"key":"salesOrderId","value":"1234","description":"Sales order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\"data\": [{\"id\": 42, \"integration_instance_id\": 7, \"sales_order_id\": 1234, \"sales_order_number\": \"SO-2026-00100\"\u0002 \"user_id\": 8, \"stripe_invoice_id\": \"in_1Oabc123\", \"stripe_customer_id\": \"cus_OabcDEF\", \"stripe_payment_intent_id\": \"pi_3OabcDEF\", \"stripe_charge_id\": \"ch_3OabcDEF\", \"amount\": 19999, \"amount_paid\": 19999, \"amount_refunded\": 0, \"currency\": \"USD\", \"status\": \"paid\", \"customer_email\": \"buyer@example.com\", \"hosted_invoice_url\": \"https://invoice.stripe.com/i/acct_1Oabc/test_YWNjdF8x\", \"invoice_pdf\": \"https://pay.stripe.com/invoice/acct_1Oabc/invst_xxx/pdf\", \"days_until_due\": 30, \"due_date\": \"2026-06-01T00:00:00.000000Z\", \"finalized_at\": \"2026-05-01T07:30:00.000000Z\", \"paid_at\": \"2026-05-01T08:00:00.000000Z\", \"voided_at\": null, \"last_refunded_at\": null, \"metadata\": {\"sku9_sales_order_id\": 1234, \"sku9_user_id\": 8}, \"created_at\": \"2026-05-01T07:30:00.000000Z\", \"updated_at\": \"2026-05-01T08:00:00.000000Z\"}]}"}]},{"name":"Issue Refund","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/refunds","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","refunds"],"variable":[{"key":"id","value":"42","description":"Local SKU.io invoice ID"}]},"description":"Issues a partial or full refund against the charge backing a paid Stripe Invoice. Requires admin or power-user privileges. Throttled to 20 requests/minute.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nFields:\n- `amount_in_cents` (optional, integer, min 1) — refund amount; if omitted, refunds the full remaining refundable amount\n- `reason` (optional, enum) — one of `duplicate`, `fraudulent`, `requested_by_customer`","body":{"mode":"raw","raw":"{\n  \"amount_in_cents\": 5000,\n  \"reason\": \"requested_by_customer\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/invoices/{id}/refunds","host":["{{baseUrl}}"],"path":["api","stripe","invoices",":id","refunds"],"variable":[{"key":"id","value":"42","description":"Local SKU.io invoice ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"refund_id\": \"re_3OabcDEF\",\n    \"amount\": 5000,\n    \"currency\": \"usd\",\n    \"status\": \"succeeded\"\n  },\n  \"message\": \"Refund issued.\"\n}"}]},{"name":"List Webhook Events","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/webhook-events","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events"]},"description":"Returns a paginated list of received Stripe webhook events, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/webhook-events","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 21,\n      \"integration_instance_id\": 7,\n      \"stripe_event_id\": \"evt_1Oxxxxxxx\",\n      \"event_type\": \"checkout.session.completed\",\n      \"account_id\": \"acct_1Oxxxxxxx\",\n      \"livemode\": false,\n      \"related_object_id\": \"cs_test_a1B2C3\",\n      \"status\": \"processed\",\n      \"attempts\": 1,\n      \"last_error\": null,\n      \"event_created_at\": \"2026-05-01T08:00:01.000000Z\",\n      \"processed_at\": \"2026-05-01T08:00:02.000000Z\",\n      \"created_at\": \"2026-05-01T08:00:01.000000Z\",\n      \"updated_at\": \"2026-05-01T08:00:02.000000Z\"\n    }\n  ],\n  \"per_page\": 25,\n  \"total\": 1,\n  \"last_page\": 1\n}"}]},{"name":"Show Webhook Event","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/webhook-events/{id}","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Returns a single webhook event. Pass `include_payload=1` to also receive the raw Stripe payload for debugging.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/stripe/webhook-events/{id}","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events",":id"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 21,\n    \"integration_instance_id\": 7,\n    \"stripe_event_id\": \"evt_1Oxxxxxxx\",\n    \"event_type\": \"checkout.session.completed\",\n    \"account_id\": \"acct_1Oxxxxxxx\",\n    \"livemode\": false,\n    \"related_object_id\": \"cs_test_a1B2C3\",\n    \"status\": \"processed\",\n    \"attempts\": 1,\n    \"last_error\": null,\n    \"event_created_at\": \"2026-05-01T08:00:01.000000Z\",\n    \"processed_at\": \"2026-05-01T08:00:02.000000Z\",\n    \"created_at\": \"2026-05-01T08:00:01.000000Z\",\n    \"updated_at\": \"2026-05-01T08:00:02.000000Z\",\n    \"payload\": {\n      \"id\": \"evt_1Oxxxxxxx\",\n      \"type\": \"checkout.session.completed\",\n      \"data\": {\n        \"object\": {\n          \"id\": \"cs_test_a1B2C3\"\n        }\n      }\n    }\n  }\n}"}]},{"name":"Replay Webhook Event","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/stripe/webhook-events/{id}/replay","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events",":id","replay"],"variable":[{"key":"id","value":"","description":"The record ID."}]},"description":"Re-queues a previously received webhook event for processing. Useful when an event failed transiently or you've fixed a bug in the handler.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/stripe/webhook-events/{id}/replay","host":["{{baseUrl}}"],"path":["api","stripe","webhook-events",":id","replay"],"variable":[{"key":"id","value":"","description":"The record ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Webhook event re-queued for processing.\"\n}"}]},{"name":"Platform Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/stripe","host":["{{baseUrl}}"],"path":["api","webhooks","stripe"]},"description":"Platform-level webhook endpoint. Receives events from the platform's Stripe account (e.g. `account.application.deauthorized`).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nRequires the `Stripe-Signature` header — requests without a valid signature return 400.","body":{"mode":"raw","raw":"{\n  \"id\": \"evt_1Oxxxxxxx\",\n  \"type\": \"account.application.deauthorized\",\n  \"data\": {\n    \"object\": {\n      \"id\": \"acct_1Oxxxxxxx\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhooks/stripe","host":["{{baseUrl}}"],"path":["api","webhooks","stripe"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"received\": true\n}"}]},{"name":"Connect Account Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/stripe/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","webhooks","stripe",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]},"description":"Per-Stripe-account webhook endpoint registered for each connected Stripe account during onboarding. Receives events for that specific connected account (e.g. `checkout.session.completed`, `charge.refunded`, `charge.dispute.created`).\n\nRequires the `Stripe-Signature` header. The integration instance ID in the URL must match the receiver registered with Stripe.","body":{"mode":"raw","raw":"{\n  \"id\": \"evt_1Oxxxxxxx\",\n  \"type\": \"checkout.session.completed\",\n  \"data\": {\n    \"object\": {\n      \"id\": \"cs_test_a1B2C3\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhooks/stripe/{integration_instance_id}","host":["{{baseUrl}}"],"path":["api","webhooks","stripe",":integration_instance_id"],"variable":[{"key":"integration_instance_id","value":"","description":"The integration instance ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"received\": true\n}"}]}]},{"name":"Google Calendar","item":[{"name":"List Google Calendar Connections","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/integrations","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations"]},"description":"List the authenticated user's Google Calendar connection. Connections are per-user — each user links their own Google account — so the list contains at most one entry (empty when the user has not connected).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe connection itself is created by authorizing through the SKU.io web app (Integrations → Google Calendar); this API manages an existing connection.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/google-calendar/integrations","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"Google Calendar\",\n      \"google_email\": \"ops@acme.com\",\n      \"calendar_id\": \"primary\",\n      \"is_authenticated\": true,\n      \"is_auto_sync_enabled\": true,\n      \"settings\": {\n        \"all_day_events\": true,\n        \"event_time_local\": \"09:00\"\n      },\n      \"created_at\": \"2026-05-30T12:00:00.000000Z\",\n      \"updated_at\": \"2026-06-18T09:30:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Google Calendars","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/calendars","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations","calendars"]},"description":"List the calendars available on the authenticated user's connected Google account (fetched live from Google, all pages). Use a calendar's `id` as the `calendar_id` when updating the connection settings to choose which calendar events sync to.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n404 when the user has no Google Calendar connection; 400 when the Google API call fails.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/calendars","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations","calendars"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": \"primary\",\n      \"summary\": \"ops@acme.com\",\n      \"primary\": true,\n      \"time_zone\": \"America/Chicago\"\n    },\n    {\n      \"id\": \"c_ops123@group.calendar.google.com\",\n      \"summary\": \"Purchasing\",\n      \"primary\": false,\n      \"time_zone\": \"America/Chicago\"\n    }\n  ]\n}"}]},{"name":"Test Google Calendar Connection","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/test-connection","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations","test-connection"]},"description":"Make a minimal Google Calendar API call to confirm the authenticated user's stored authorization still works. Returns the target calendar's summary and time zone on success; a failed test returns 400 with the upstream message.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n404 when the user has no Google Calendar connection.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/test-connection","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations","test-connection"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"message\": \"Connection successful\",\n    \"calendar_summary\": \"ops@acme.com\",\n    \"calendar_time_zone\": \"America/Chicago\"\n  }\n}"}]},{"name":"Update Google Calendar Settings","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/{id}","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations",":id"],"variable":[{"key":"id","value":"3","description":"Google Calendar connection ID (must belong to the authenticated user)"}]},"description":"Update the authenticated user's Google Calendar connection settings. Only the caller's own connection can be updated (404 otherwise).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields (all optional):**\n- `calendar_id` (string, max 255) — which Google calendar events sync to (see List Google Calendars).\n- `all_day_events` (boolean) — create synced events as all-day events.\n- `event_time_local` (string, HH:MM) — local time of day for timed events when `all_day_events` is false.\n\nReturns the updated connection.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"calendar_id\": \"c_ops123@group.calendar.google.com\",\n  \"all_day_events\": false,\n  \"event_time_local\": \"09:00\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/{id}","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations",":id"],"variable":[{"key":"id","value":"3","description":"Google Calendar connection ID (must belong to the authenticated user)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Google Calendar\",\n    \"google_email\": \"ops@acme.com\",\n    \"calendar_id\": \"primary\",\n    \"is_authenticated\": true,\n    \"is_auto_sync_enabled\": true,\n    \"settings\": {\n      \"all_day_events\": true,\n      \"event_time_local\": \"09:00\"\n    },\n    \"created_at\": \"2026-05-30T12:00:00.000000Z\",\n    \"updated_at\": \"2026-06-18T09:30:00.000000Z\"\n  }\n}"}]},{"name":"Delete Google Calendar Connection","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/{id}","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations",":id"],"variable":[{"key":"id","value":"3","description":"Google Calendar connection ID (must belong to the authenticated user)"}]},"description":"Disconnect the authenticated user's Google Calendar. The stored authorization is revoked and the connection removed, along with the user's calendar sync subscriptions. Only the caller's own connection can be deleted (404 otherwise).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/google-calendar/integrations/{id}","host":["{{baseUrl}}"],"path":["api","google-calendar","integrations",":id"],"variable":[{"key":"id","value":"3","description":"Google Calendar connection ID (must belong to the authenticated user)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Google Calendar disconnected.\"\n}"}]},{"name":"List Calendar Sync Features","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/catalog","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions","catalog"]},"description":"The catalog of features that can sync to a user's Google Calendar. Each entry's `key` is the `feature_key` used when subscribing; `manage_route` is the in-app page where that feature's data lives.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nCurrently available features: `po_cash_flow` (payment milestones from the purchase order cash-flow schedule) and `vendor_deposits` (vendor deposit due dates).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/catalog","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions","catalog"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"key\": \"po_cash_flow\",\n      \"label\": \"Purchase Order Cash Flow\",\n      \"description\": \"Payment milestones from the PO cash-flow schedule.\",\n      \"manage_route\": \"/orders/purchase-orders/cash-flow-schedule\"\n    },\n    {\n      \"key\": \"vendor_deposits\",\n      \"label\": \"Vendor Deposits\",\n      \"description\": \"Vendor deposit due dates.\",\n      \"manage_route\": \"/orders/vendor-deposits\"\n    }\n  ]\n}"}]},{"name":"List Calendar Sync Subscriptions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions"]},"description":"List the authenticated user's calendar sync subscriptions — each one says \"sync feature X to my Google Calendar\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 6,\n      \"feature_key\": \"po_cash_flow\",\n      \"feature_label\": \"Purchase Order Cash Flow\",\n      \"manage_route\": \"/orders/purchase-orders/cash-flow-schedule\",\n      \"is_enabled\": true,\n      \"options\": null,\n      \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n      \"updated_at\": \"2026-06-01T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Calendar Sync Subscription","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions"]},"description":"Subscribe the authenticated user to a calendar sync feature so its events appear on their connected Google Calendar.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:**\n- `feature_key` (required, string) — one of the keys from List Calendar Sync Features (`po_cash_flow`, `vendor_deposits`).\n- `options` (optional, object) — feature-specific options.\n\nReturns the created (or re-enabled) subscription. 400 when subscribing fails (e.g. no Google Calendar connection).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"feature_key\": \"po_cash_flow\",\n  \"options\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"data\": {\n    \"id\": 6,\n    \"feature_key\": \"po_cash_flow\",\n    \"feature_label\": \"Purchase Order Cash Flow\",\n    \"manage_route\": \"/orders/purchase-orders/cash-flow-schedule\",\n    \"is_enabled\": true,\n    \"options\": null,\n    \"created_at\": \"2026-06-01T10:00:00.000000Z\",\n    \"updated_at\": \"2026-06-01T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Sync Calendar Feature Now","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/{featureKey}/sync-now","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions",":featureKey","sync-now"],"variable":[{"key":"featureKey","value":"po_cash_flow","description":"Feature key (po_cash_flow or vendor_deposits)"}]},"description":"Manually queue a sync of the authenticated user's Google Calendar for the given feature — useful for immediate confirmation instead of waiting for the scheduled sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**This endpoint is asynchronous**: it queues a background sync and returns immediately; the calendar updates shortly after.\n\n404 for an unknown feature key; 400 when the user is not subscribed to the feature.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/{featureKey}/sync-now","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions",":featureKey","sync-now"],"variable":[{"key":"featureKey","value":"po_cash_flow","description":"Feature key (po_cash_flow or vendor_deposits)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Sync queued.\"\n}"}]},{"name":"Delete Calendar Sync Subscription","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/{featureKey}","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions",":featureKey"],"variable":[{"key":"featureKey","value":"po_cash_flow","description":"Feature key (po_cash_flow or vendor_deposits)"}]},"description":"Unsubscribe the authenticated user from a calendar sync feature. Events already created on the user's Google Calendar for this feature are removed by the sync.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n404 for an unknown feature key.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/google-calendar/subscriptions/{featureKey}","host":["{{baseUrl}}"],"path":["api","google-calendar","subscriptions",":featureKey"],"variable":[{"key":"featureKey","value":"po_cash_flow","description":"Feature key (po_cash_flow or vendor_deposits)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Unsubscribed.\"\n}"}]}]}]},{"name":"Platform","item":[{"name":"Misc","item":[{"name":"Login","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/auth/login","host":["{{baseUrl}}"],"path":["api","auth","login"]},"description":"Authenticates a user and returns a Bearer token.\n\nLocal development credentials:","body":{"mode":"raw","raw":"{\n  \"email\": \"jane@example.com\",\n  \"password\": \"your-password\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/auth/login","host":["{{baseUrl}}"],"path":["api","auth","login"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"token\": \"1|abcdefghijklmnopqrstuvwxyz1234567890\",\n  \"user\": {\n    \"id\": 1,\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\"\n  }\n}"}]},{"name":"Logout","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/auth/logout","host":["{{baseUrl}}"],"path":["api","auth","logout"]},"description":"Revokes the current Bearer token.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/auth/logout","host":["{{baseUrl}}"],"path":["api","auth","logout"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Logged out successfully.\"\n}"}]},{"name":"List Integration Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances?per_page=10","host":["{{baseUrl}}"],"path":["api","integration-instances"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]},"description":"Returns all integration instances (connections to external platforms like Shopify, Amazon, Xero, etc.).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integration-instances?per_page=10","host":["{{baseUrl}}"],"path":["api","integration-instances"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"name\": \"My Shopify Store\",\n      \"type\": \"shopify\",\n      \"status\": \"active\",\n      \"created_at\": \"2023-06-01T00:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 3\n}"}]},{"name":"Get Authenticated User","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/auth/user","host":["{{baseUrl}}"],"path":["api","auth","user"]},"description":"Returns the currently authenticated user's profile. The `features` object reports per-tenant feature flags (e.g. `features.granular_permissions` — whether granular role/permission enforcement is enabled for the tenant; `false` when the flag is off or unset).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/auth/user","host":["{{baseUrl}}"],"path":["api","auth","user"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 1,\n  \"name\": \"Dev User\",\n  \"email\": \"dev@sku.io\",\n  \"role\": \"admin\",\n  \"features\": {\n    \"granular_permissions\": false\n  },\n  \"created_at\": \"2023-01-01T00:00:00.000000Z\"\n}"}]},{"name":"Account Setup","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/account-setup","host":["{{baseUrl}}"],"path":["api","account-setup"]},"description":"Completes initial account setup after registration.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"company_name\": \"My Company\",\n  \"timezone\": \"America/New_York\",\n  \"currency\": \"USD\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/account-setup","host":["{{baseUrl}}"],"path":["api","account-setup"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Account setup completed successfully.\"\n}"}]},{"name":"Get Company Profile","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/company-profile","host":["{{baseUrl}}"],"path":["api","company-profile"]},"description":"Returns the company profile settings.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/company-profile","host":["{{baseUrl}}"],"path":["api","company-profile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"company_name\": \"My Company\",\n    \"timezone\": \"America/New_York\",\n    \"currency\": \"USD\",\n    \"logo_url\": null\n  }\n}"}]},{"name":"Update Company Profile","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/company-profile","host":["{{baseUrl}}"],"path":["api","company-profile"]},"description":"Updates the company profile.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"company_name\": \"My Updated Company\",\n  \"timezone\": \"America/Los_Angeles\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/company-profile","host":["{{baseUrl}}"],"path":["api","company-profile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"company_name\": \"My Updated Company\",\n    \"timezone\": \"America/Los_Angeles\",\n    \"currency\": \"USD\"\n  }\n}"}]},{"name":"App Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/app-settings","host":["{{baseUrl}}"],"path":["api","app-settings"]},"description":"Returns global application settings (feature flags, configuration) for the frontend.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/app-settings","host":["{{baseUrl}}"],"path":["api","app-settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"features\": {\n      \"inventory_forecasting\": true,\n      \"amazon_integration\": true\n    },\n    \"limits\": {\n      \"max_products\": 10000\n    }\n  }\n}"}]},{"name":"List Activity","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/activity?per_page=20&page=1","host":["{{baseUrl}}"],"path":["api","activity"],"query":[{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated activity/audit log across all entities.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/activity?per_page=20&page=1","host":["{{baseUrl}}"],"path":["api","activity"],"query":[{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"log_name\": \"default\",\n      \"description\": \"created\",\n      \"subject_type\": \"App\\\\Models\\\\SalesOrder\",\n      \"subject_id\": 30,\n      \"causer_type\": \"App\\\\Models\\\\User\",\n      \"causer_id\": 1,\n      \"properties\": {\n        \"attributes\": {\n          \"status\": \"open\"\n        }\n      },\n      \"created_at\": \"2024-03-10T09:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 50,\n  \"per_page\": 20,\n  \"total\": 982\n}"}]},{"name":"Update Address","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/addresses/{address}","host":["{{baseUrl}}"],"path":["api","addresses",":address"],"variable":[{"key":"address","value":"1","description":"Address ID"}]},"description":"Updates an address record.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"line1\": \"123 Main St\",\n  \"city\": \"New York\",\n  \"state\": \"NY\",\n  \"postcode\": \"10001\",\n  \"country\": \"US\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/addresses/{address}","host":["{{baseUrl}}"],"path":["api","addresses",":address"],"variable":[{"key":"address","value":"1","description":"Address ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"line1\": \"123 Main St\",\n    \"line2\": null,\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"postcode\": \"10001\",\n    \"country\": \"US\"\n  }\n}"}]},{"name":"Delete Address","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/addresses/{address}","host":["{{baseUrl}}"],"path":["api","addresses",":address"],"variable":[{"key":"address","value":"1","description":"Address ID"}]},"description":"Deletes an address record.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/addresses/{address}","host":["{{baseUrl}}"],"path":["api","addresses",":address"],"variable":[{"key":"address","value":"1","description":"Address ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null\n}"}]},{"name":"Check If Address Is Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/addresses/deletable","host":["{{baseUrl}}"],"path":["api","addresses","deletable"]},"description":"Checks whether an address can be safely deleted (not referenced by active records).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"address_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/addresses/deletable","host":["{{baseUrl}}"],"path":["api","addresses","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"deletable\": true\n}"}]},{"name":"Check If Address Is Locked","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/addresses/locked","host":["{{baseUrl}}"],"path":["api","addresses","locked"]},"description":"Checks whether an address is locked (read-only due to being used in finalized orders).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"address_id\": 1\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/addresses/locked","host":["{{baseUrl}}"],"path":["api","addresses","locked"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"locked\": false\n}"}]},{"name":"List Alert Preferences","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alert-preferences","host":["{{baseUrl}}"],"path":["api","alert-preferences"]},"description":"Returns the current user's alert notification preferences.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequires a token with permission to view alert preferences."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alert-preferences","host":["{{baseUrl}}"],"path":["api","alert-preferences"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"alert_type\": \"low_stock\",\n      \"email\": true,\n      \"in_app\": true\n    },\n    {\n      \"alert_type\": \"order_pending\",\n      \"email\": false,\n      \"in_app\": true\n    }\n  ]\n}"}]},{"name":"Bulk Update Alert Preferences","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alert-preferences","host":["{{baseUrl}}"],"path":["api","alert-preferences"]},"description":"Updates multiple alert preferences at once.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nRequires a token with permission to update alert preferences.","body":{"mode":"raw","raw":"{\n  \"preferences\": [\n    {\n      \"alert_type\": \"low_stock\",\n      \"email\": true,\n      \"in_app\": true\n    },\n    {\n      \"alert_type\": \"order_pending\",\n      \"email\": true,\n      \"in_app\": true\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alert-preferences","host":["{{baseUrl}}"],"path":["api","alert-preferences"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Alert preferences updated.\"\n}"}]},{"name":"Create Note","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/notes","host":["{{baseUrl}}"],"path":["api","notes"]},"description":"Creates a note on a noteable entity (SalesOrder, PurchaseOrder, etc.).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"notable_type\": \"SalesOrder\",\n  \"notable_id\": 30,\n  \"content\": \"Customer requested gift wrapping.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/notes","host":["{{baseUrl}}"],"path":["api","notes"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"notable_type\": \"App\\\\Models\\\\SalesOrder\",\n    \"notable_id\": 30,\n    \"content\": \"Customer requested gift wrapping.\",\n    \"user\": {\n      \"id\": 1,\n      \"name\": \"Dev User\"\n    },\n    \"created_at\": \"2024-03-20T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Note","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/notes/{note}","host":["{{baseUrl}}"],"path":["api","notes",":note"],"variable":[{"key":"note","value":"55","description":"Note ID"}]},"description":"Updates a note.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"content\": \"Updated note content.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/notes/{note}","host":["{{baseUrl}}"],"path":["api","notes",":note"],"variable":[{"key":"note","value":"55","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 55,\n    \"content\": \"Updated note content.\",\n    \"updated_at\": \"2024-03-20T11:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Note","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/notes/{note}","host":["{{baseUrl}}"],"path":["api","notes",":note"],"variable":[{"key":"note","value":"55","description":"Note ID"}]},"description":"Deletes a note.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/notes/{note}","host":["{{baseUrl}}"],"path":["api","notes",":note"],"variable":[{"key":"note","value":"55","description":"Note ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null\n}"}]},{"name":"Global Search","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/search?q=widget&types[]=products","host":["{{baseUrl}}"],"path":["api","search"],"query":[{"key":"q","value":"widget","description":"Search query string","disabled":true},{"key":"types[]","value":"products","description":"Entity types to search (products, sales_orders, customers, suppliers, purchase_orders)","disabled":true}]},"description":"Performs a global search across multiple entity types.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nQuery Parameters:\n- q (required): Search term\n- types[] (optional): Limit search to specific entity types"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/search?q=widget&types[]=products","host":["{{baseUrl}}"],"path":["api","search"],"query":[{"key":"q","value":"widget","description":"Search query string","disabled":true},{"key":"types[]","value":"products","description":"Entity types to search (products, sales_orders, customers, suppliers, purchase_orders)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"products\": [\n      {\n        \"id\": 15,\n        \"sku\": \"WIDGET-001\",\n        \"name\": \"Blue Widget\",\n        \"type\": \"product\"\n      }\n    ],\n    \"sales_orders\": []\n  }\n}"}]},{"name":"List Enums","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/enums","host":["{{baseUrl}}"],"path":["api","enums"]},"description":"Returns all application enum values used by the frontend for dropdowns and validation.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/enums","host":["{{baseUrl}}"],"path":["api","enums"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order_statuses\": [\n      \"open\",\n      \"processing\",\n      \"shipped\",\n      \"completed\",\n      \"cancelled\"\n    ],\n    \"fulfillment_types\": [\n      \"standard\",\n      \"dropship\",\n      \"fba\"\n    ],\n    \"inventory_statuses\": [\n      \"on_hand\",\n      \"committed\",\n      \"available\",\n      \"incoming\"\n    ]\n  }\n}"}]},{"name":"List User API Keys","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/user-api","host":["{{baseUrl}}"],"path":["api","user-api"]},"description":"Returns all API keys for the current user.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/user-api","host":["{{baseUrl}}"],"path":["api","user-api"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My API Key\",\n      \"last_used_at\": \"2024-03-19T15:30:00.000000Z\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create API Key","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/user-api","host":["{{baseUrl}}"],"path":["api","user-api"]},"description":"Creates a new API key for the current user. The token is only shown once in the response.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"My New API Key\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/user-api","host":["{{baseUrl}}"],"path":["api","user-api"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"My New API Key\",\n    \"token\": \"2|secretTokenValueOnlyShownOnce1234567890\",\n    \"created_at\": \"2024-03-20T10:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete API Key","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/user-api/{token}","host":["{{baseUrl}}"],"path":["api","user-api",":token"],"variable":[{"key":"token","value":"1","description":"API Token ID"}]},"description":"Revokes an API key.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/user-api/{token}","host":["{{baseUrl}}"],"path":["api","user-api",":token"],"variable":[{"key":"token","value":"1","description":"API Token ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"API key revoked.\"\n}"}]},{"name":"Get Low Stock Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/low-stock-items?per_page=20","host":["{{baseUrl}}"],"path":["api","low-stock-items"],"query":[{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}]},"description":"Returns products that are at or below their reorder point.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/low-stock-items?per_page=20","host":["{{baseUrl}}"],"path":["api","low-stock-items"],"query":[{"key":"per_page","value":"20","description":"Results per page (default 10).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"product_id\": 15,\n      \"sku\": \"WIDGET-001\",\n      \"name\": \"Blue Widget\",\n      \"available_quantity\": 3,\n      \"reorder_point\": 10,\n      \"warehouse_id\": 2\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 20,\n  \"total\": 8\n}"}]},{"name":"Export Low Stock Items","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/low-stock-items/export?format=csv","host":["{{baseUrl}}"],"path":["api","low-stock-items","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv (default) or xlsx","disabled":true}]},"description":"Exports low-stock items as a downloadable CSV or XLSX file.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nFilename pattern: `low-stock-items-{Y-m-d_His}.{ext}`\n\nSupports the same filters as `GET /api/low-stock-items` (search, severity, brand_id, warehouse_id, archived_status). The `columns` query parameter accepts a comma-separated list of columns to include in the export — defaults to all available columns.\n\nResponse Content-Type:\n- CSV → `text/csv`\n- XLSX → `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/low-stock-items/export?format=csv","host":["{{baseUrl}}"],"path":["api","low-stock-items","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv (default) or xlsx","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"sku,name,brand,supplier,inventory_available,min_stock_level,daily_average_consumption,days_of_supply,deficit\nWIDGET-001,Blue Widget,Acme,Acme Supply,3,10,1.5,2,7\n"}]},{"name":"Inventory Management Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-management","host":["{{baseUrl}}"],"path":["api","inventory-management"]},"description":"Returns inventory management configuration settings.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-management","host":["{{baseUrl}}"],"path":["api","inventory-management"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"costing_method\": \"fifo\",\n    \"negative_stock_allowed\": false,\n    \"auto_allocate\": true\n  }\n}"}]},{"name":"Get Inventory Valuation","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-management/valuation","host":["{{baseUrl}}"],"path":["api","inventory-management","valuation"]},"description":"Returns the total value of on-hand and in-transit inventory across all warehouses, broken down by inventory status. Each status carries both a quantity and a valuation, plus an overall average unit cost. Use it to power an inventory valuation summary. Optionally scope the figures to a single warehouse or to an as-of cut-off date.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-management/valuation","host":["{{baseUrl}}"],"path":["api","inventory-management","valuation"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"total_quantity\": 18450,\n    \"total_valuation\": 254310.75,\n    \"average_cost\": 13.78,\n    \"active_quantity\": 17200,\n    \"active_valuation\": 236100.5,\n    \"in_transit_quantity\": 1250,\n    \"in_transit_valuation\": 18210.25\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Inventory Valuation by Product","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/inventory-management/valuation-by-product","host":["{{baseUrl}}"],"path":["api","inventory-management","valuation-by-product"]},"description":"Returns a flat, per-product breakdown of inventory value. Every product row includes quantities and valuations split by status (active, reserved, in-transit, inbound, on-hand) together with average unit costs, and the response ends with a totals block summing all products. Use it to build a detailed inventory valuation report.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/inventory-management/valuation-by-product","host":["{{baseUrl}}"],"path":["api","inventory-management","valuation-by-product"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"products\": [\n      {\n        \"sku\": \"WIDGET-BLK-01\",\n        \"name\": \"Black Widget\",\n        \"active_quantity\": 320,\n        \"reserved_quantity\": 40,\n        \"in_transit_quantity\": 60,\n        \"inbound_quantity\": 100,\n        \"total_quantity\": 380,\n        \"average_cost\": 12.5,\n        \"on_hand_average_cost\": 12.5,\n        \"in_transit_average_cost\": 12.75,\n        \"inbound_average_cost\": 12.9,\n        \"active_valuation\": 4000,\n        \"reserved_valuation\": 500,\n        \"in_transit_valuation\": 765,\n        \"inbound_valuation\": 1290,\n        \"on_hand_valuation\": 4500,\n        \"total_valuation\": 4750\n      }\n    ],\n    \"totals\": {\n      \"active_quantity\": 320,\n      \"reserved_quantity\": 40,\n      \"in_transit_quantity\": 60,\n      \"inbound_quantity\": 100,\n      \"total_quantity\": 380,\n      \"active_valuation\": 4000,\n      \"reserved_valuation\": 500,\n      \"in_transit_valuation\": 765,\n      \"inbound_valuation\": 1290,\n      \"on_hand_valuation\": 4500,\n      \"total_valuation\": 4750\n    }\n  },\n  \"status\": \"success\"\n}"}]},{"name":"Get Low Stock Metrics","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/low-stock-items/metrics","host":["{{baseUrl}}"],"path":["api","low-stock-items","metrics"]},"description":"Returns summary counts for the low-stock report: how many products are low on stock, how many are critically low (below the configured days-of-supply threshold), how many are out of stock, and how many have no minimum stock level configured, along with the threshold in days. Accepts the same filters as the low-stock list so the metrics match the filtered view.\n\n**Required scope: `inventory:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/low-stock-items/metrics","host":["{{baseUrl}}"],"path":["api","low-stock-items","metrics"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"total_low_stock\": 42,\n  \"critically_low\": 9,\n  \"out_of_stock\": 5,\n  \"without_min_stock_level\": 130,\n  \"threshold_days\": 14\n}"}]},{"name":"Update Custom Field Values","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/custom-field-values/{entity}/{entityId}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":entity",":entityId"],"variable":[{"key":"entity","value":"product","description":"Entity type"},{"key":"entityId","value":"15","description":"Entity ID"}]},"description":"Sets custom field values for a specific entity instance.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"values\": {\n    \"1\": true,\n    \"2\": \"some text value\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/custom-field-values/{entity}/{entityId}","host":["{{baseUrl}}"],"path":["api","custom-field-values",":entity",":entityId"],"variable":[{"key":"entity","value":"product","description":"Entity type"},{"key":"entityId","value":"15","description":"Entity ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Custom field values updated.\"\n}"}]},{"name":"Delete Sales Rep","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"1","description":"Sales rep ID"}]},"description":"Deletes a sales rep.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token\n\nSide effects (performed in a single transaction before the delete):\n- Unlinks the rep from all sales orders (sales_orders.sales_rep_id set to null)\n- Clears the rep as the default on any linked customers (customers.default_sales_rep_id set to null)\n\nReturns 404 if the sales rep does not exist."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/sales-reps/{id}","host":["{{baseUrl}}"],"path":["api","sales-reps",":id"],"variable":[{"key":"id","value":"1","description":"Sales rep ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"Success\",\n  \"message\": \"Sales rep 'Jane Doe' deleted successfully.\"\n}"}]},{"name":"Lookup","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/lookup?type=warehouses&search=main","host":["{{baseUrl}}"],"path":["api","lookup"],"query":[{"key":"type","value":"warehouses","description":"Entity type for autocomplete lookup","disabled":true},{"key":"search","value":"main","description":"Search term","disabled":true}]},"description":"Generic autocomplete lookup endpoint used by select/dropdown inputs throughout the UI. Returns a list of matching records for a given entity type.\n\nAuthentication: Requires Bearer token.\n\nCommon types: warehouses, products, customers, suppliers, sales_channels, tags, users"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/lookup?type=warehouses&search=main","host":["{{baseUrl}}"],"path":["api","lookup"],"query":[{"key":"type","value":"warehouses","description":"Entity type for autocomplete lookup","disabled":true},{"key":"search","value":"main","description":"Search term","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"label\": \"Main Warehouse\",\n      \"value\": 2\n    }\n  ]\n}"}]},{"name":"List Constants","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/constants","host":["{{baseUrl}}"],"path":["api","constants"]},"description":"Returns application constants used for frontend configuration.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/constants","host":["{{baseUrl}}"],"path":["api","constants"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"max_import_rows\": 5000,\n    \"supported_currencies\": [\n      \"USD\",\n      \"EUR\",\n      \"GBP\",\n      \"AUD\",\n      \"CAD\"\n    ]\n  }\n}"}]},{"name":"List Sales Channels","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/sales-channels","host":["{{baseUrl}}"],"path":["api","sales-channels"]},"description":"Returns all sales channels (Shopify stores, Amazon marketplaces, etc.).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/sales-channels","host":["{{baseUrl}}"],"path":["api","sales-channels"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 5,\n      \"name\": \"My Shopify Store\",\n      \"type\": \"shopify\",\n      \"integration_instance_id\": 3,\n      \"is_active\": true,\n      \"created_at\": \"2023-06-01T00:00:00.000000Z\"\n    },\n    {\n      \"id\": 6,\n      \"name\": \"Amazon US\",\n      \"type\": \"amazon\",\n      \"integration_instance_id\": 5,\n      \"is_active\": true,\n      \"created_at\": \"2023-07-01T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Change Password","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/password/change","host":["{{baseUrl}}"],"path":["api","password","change"]},"description":"Changes the current user's password.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"current_password\": \"current-password\",\n  \"password\": \"new-secure-password\",\n  \"password_confirmation\": \"new-secure-password\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/password/change","host":["{{baseUrl}}"],"path":["api","password","change"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Password changed successfully.\"\n}"}]},{"name":"Request Password Reset Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/password/email","host":["{{baseUrl}}"],"path":["api","password","email"]},"description":"Sends a password-reset link to the supplied email address if an account exists for it. This is a public, unauthenticated endpoint. Returns a confirmation message on success, or a validation error if the email is missing/invalid or no account matches.","body":{"mode":"raw","raw":"{\n  \"email\": \"user@example.com\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/password/email","host":["{{baseUrl}}"],"path":["api","password","email"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"We have emailed your password reset link.\"\n}"}]},{"name":"Reset Password","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/password/reset","host":["{{baseUrl}}"],"path":["api","password","reset"]},"description":"Completes a password reset using the token from the reset email. Provide the token, the account email, and the new password with its confirmation. This is a public, unauthenticated endpoint. On success the password is updated (and an invited-but-unactivated account is activated); on failure a validation error is returned.","body":{"mode":"raw","raw":"{\n  \"token\": \"9f8c1b2a3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f6071829304a5b6c7d8\",\n  \"email\": \"user@example.com\",\n  \"password\": \"new-secret-password\",\n  \"password_confirmation\": \"new-secret-password\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/password/reset","host":["{{baseUrl}}"],"path":["api","password","reset"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Your password has been reset.\"\n}"}]},{"name":"List Webhooks","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhooks","host":["{{baseUrl}}"],"path":["api","webhooks"]},"description":"Returns all configured outbound webhooks.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhooks","host":["{{baseUrl}}"],"path":["api","webhooks"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"url\": \"https://example.com/webhook\",\n      \"events\": [\n        \"order.created\",\n        \"order.shipped\"\n      ],\n      \"is_active\": true\n    }\n  ]\n}"}]},{"name":"Create Webhook","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks","host":["{{baseUrl}}"],"path":["api","webhooks"]},"description":"Creates a new outbound webhook.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"url\": \"https://example.com/webhook\",\n  \"events\": [\n    \"order.created\",\n    \"order.shipped\"\n  ],\n  \"secret\": \"my-webhook-secret\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhooks","host":["{{baseUrl}}"],"path":["api","webhooks"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"url\": \"https://example.com/webhook\",\n    \"events\": [\n      \"order.created\",\n      \"order.shipped\"\n    ],\n    \"is_active\": true\n  }\n}"}]},{"name":"Show Webhook","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]},"description":"Returns a single webhook.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"url\": \"https://example.com/webhook\",\n    \"events\": [\n      \"order.created\"\n    ],\n    \"is_active\": true\n  }\n}"}]},{"name":"Update Webhook","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]},"description":"Updates a webhook.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"is_active\": false\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"url\": \"https://example.com/webhook\",\n    \"is_active\": false\n  }\n}"}]},{"name":"Delete Webhook","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]},"description":"Deletes a webhook.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/webhooks/{webhook}","host":["{{baseUrl}}"],"path":["api","webhooks",":webhook"],"variable":[{"key":"webhook","value":"1","description":"The webhook ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null\n}"}]}]},{"name":"Authentication","item":[{"name":"Refresh Token","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/auth/refresh","host":["{{baseUrl}}"],"path":["api","auth","refresh"]},"description":"Refreshes the authentication token. Does not require Bearer token as the current token is used from the request context.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nAuthentication: Not required (uses current token for refresh)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/auth/refresh","host":["{{baseUrl}}"],"path":["api","auth","refresh"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"access_token\": \"2|newtoken123abc456def789ghi012jkl345mno678pqr\",\n  \"token_type\": \"bearer\"\n}"}]},{"name":"Get Profile","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/auth/profile","host":["{{baseUrl}}"],"path":["api","auth","profile"]},"description":"Returns the authenticated user's profile information along with a top-level `is_production_server` flag indicating whether the server is running in production (used by the SPA to gate sandbox-environment UI affordances).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Response flags:**\n- `is_production_server` (boolean) — true when this pod is the production environment.\n- `features` (object) — per-account feature-flag map (same as `GET /api/features`); each value is a boolean."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/auth/profile","host":["{{baseUrl}}"],"path":["api","auth","profile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"email_verified_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"activated_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"deleted_at\": null,\n    \"is_admin\": true,\n    \"is_power_user\": true,\n    \"is_super_admin\": false,\n    \"role\": \"Admin\",\n    \"features\": {\n      \"granular_permissions\": false\n    }\n  },\n  \"is_production_server\": false\n}"}]},{"name":"Update Profile","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/auth/profile","host":["{{baseUrl}}"],"path":["api","auth","profile"]},"description":"Updates the authenticated user's profile (name and email).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required): Full name (max 255 chars)\n- email (required): Email address (must be unique)","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Name\",\n  \"email\": \"newemail@sku.io\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/auth/profile","host":["{{baseUrl}}"],"path":["api","auth","profile"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated\"\n}"}]},{"name":"Update Password","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/auth/password","host":["{{baseUrl}}"],"path":["api","auth","password"]},"description":"Updates the authenticated user's password. Sends a confirmation email upon success.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- old_password (required): Current password (verified against stored hash)\n- password (required): New password (min 8 chars)\n- password_confirmation (required): Must match password field","body":{"mode":"raw","raw":"{\n  \"old_password\": \"current-password\",\n  \"password\": \"new-secure-password\",\n  \"password_confirmation\": \"new-secure-password\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/auth/password","host":["{{baseUrl}}"],"path":["api","auth","password"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Successfully updated password\"\n}"}]},{"name":"Get Alerts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/auth/alerts?limit=10","host":["{{baseUrl}}"],"path":["api","auth","alerts"],"query":[{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true}]},"description":"Returns paginated alerts for the authenticated user.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nQuery params:\n- limit: Number of alerts per page (default: 10)"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/auth/alerts?limit=10","host":["{{baseUrl}}"],"path":["api","auth","alerts"],"query":[{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10,\n      \"user_id\": 1,\n      \"activity_log_id\": 500,\n      \"show_in_ui_notification\": 1,\n      \"read_at\": null,\n      \"created_at\": \"2024-06-01T09:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Get Unread Notifications","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/auth/unread-notifications?limit=10","host":["{{baseUrl}}"],"path":["api","auth","unread-notifications"],"query":[{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true}]},"description":"Returns paginated unread UI notifications for the authenticated user. Only returns alerts with show_in_ui_notification=1 that have not been read.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/auth/unread-notifications?limit=10","host":["{{baseUrl}}"],"path":["api","auth","unread-notifications"],"query":[{"key":"limit","value":"10","description":"Items per page (default: 10)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 10,\n      \"user_id\": 1,\n      \"activity_log_id\": 500,\n      \"show_in_ui_notification\": 1,\n      \"read_at\": null,\n      \"created_at\": \"2024-06-01T09:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 10,\n  \"total\": 1\n}"}]},{"name":"Mark Notification as Read","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/auth/{id}/read-notification","host":["{{baseUrl}}"],"path":["api","auth",":id","read-notification"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Marks a specific notification as read for the authenticated user.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPath params:\n- activity_log_id: ID of the activity log / notification to mark as read"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/auth/{id}/read-notification","host":["{{baseUrl}}"],"path":["api","auth",":id","read-notification"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"status\": \"success\"\n}"}]},{"name":"Sign Out of All Sessions (Global Logout)","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/auth/token","host":["{{baseUrl}}"],"path":["api","auth","token"]},"description":"Signs the authenticated user out of every browser and device — across every subdomain and every pod.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nWhat it does:\n- Increments the user's central `auth_version` counter by 1\n- Deletes every Session-type Personal Access Token for the user (Sanctum bearer sessions)\n- Invalidates the caller's own cookie session (if cookie-authenticated)\n- Busts the per-user auth_version cache so the next request reads the new value immediately\n\nWhat survives:\n- Personal Access Tokens (PAT type) — long-lived API credentials. Revoke individually from Settings → Developer → Personal Access Tokens.\n- Integration tokens (3PL / channel connections). Revoke individually from Connected Apps.\n\nHow other devices are kicked: every request authenticated by a Session token (or cookie session) carries a stamped `auth_v`. The EnforceAuthVersion middleware compares it to the current `auth_version` on the user row; if the stamp is stale, the request is rejected with 401 / ERR_AUTH_REVOKED and the cookie session is invalidated. This works across all pods because `users.auth_version` lives in the central DB.\n\nAuthentication: Requires Bearer token (Session type) or active cookie session.\n\nNote: Not available when CACHE_STORE is 'array' — the auth_version cache bust would be a no-op across processes."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/auth/token","host":["{{baseUrl}}"],"path":["api","auth","token"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All sessions logged out.\"\n}"}]}]},{"name":"Users","item":[{"name":"Get User Lookup List","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/users/list","host":["{{baseUrl}}"],"path":["api","users","list"]},"description":"Returns a minimal list of users (id and name only), ordered by name. Intended for dropdown/combo box lookups.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nTenant scoping: Results are restricted to users who are members of the current tenant. The `users` table lives on the central connection and is shared across all tenants, so without scoping every dropdown would leak users from every tenant in the installation.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/users/list","host":["{{baseUrl}}"],"path":["api","users","list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Alice Johnson\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Bob Smith\"\n    },\n    {\n      \"id\": 3,\n      \"name\": \"Carol White\"\n    }\n  ]\n}"}]},{"name":"Invite User","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/users/store-user","host":["{{baseUrl}}"],"path":["api","users","store-user"]},"description":"Creates a new user and sends them an email invitation to set their own password (in production). In non-production environments, a password is generated and returned in the response.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nFields:\n- email (required, unique, max:255) — User's email address\n- name (required, string, max:255) — User's full name\n- is_admin (optional, boolean, default: false) — Grant admin privileges\n- is_power_user (optional, boolean, default: false) — Grant power user privileges\n\n**Requires permission:** `users.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"David Lee\",\n  \"email\": \"david@example.com\",\n  \"is_admin\": false,\n  \"is_power_user\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/users/store-user","host":["{{baseUrl}}"],"path":["api","users","store-user"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"user David Lee was successfully created\"\n}"}]},{"name":"Show User","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]},"description":"Returns a single user by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nTenant scoping: Returns 404 if the user is not a member of the current tenant. The `users` table is on the central connection, so route model binding would otherwise resolve any user ID system-wide.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Alice Johnson\",\n    \"email\": \"alice@example.com\",\n    \"email_verified_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"activated_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"updated_at\": \"2024-03-15T12:00:00.000000Z\",\n    \"deleted_at\": null,\n    \"is_admin\": true,\n    \"is_power_user\": false,\n    \"is_super_admin\": false,\n    \"role\": \"Admin\"\n  }\n}"}]},{"name":"Update User","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]},"description":"Updates an existing user. The is_admin field can only be set by admin users.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nTenant scoping: Returns 404 if the user is not a member of the current tenant. Closes a privilege-escalation hole where any tenant admin could otherwise mutate any user system-wide by guessing IDs.\n\nis_admin / is_power_user propagation: when provided, these flags are mirrored to the `tenant_users` pivot row for the current tenant (the per-tenant source of truth) and also written to the central `users` columns (for legacy readers). Without this mirror, an admin elevated in one tenant would silently become admin in every tenant they're attached to.\n\nAuthentication: Requires Bearer token.\n\nFields (all optional):\n- name (optional, max:255) — User's full name\n- email (optional, email, max:255) — User's email address\n- is_admin (optional, boolean) — Admin privileges (only settable by admins)\n- is_power_user (optional, boolean) — Power user privileges\n\n**Requires permission:** `users.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Alice Johnson-Smith\",\n  \"email\": \"alice.new@example.com\",\n  \"is_admin\": false,\n  \"is_power_user\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"user Alice Johnson-Smith was successfully updated\"\n}"}]},{"name":"Delete (Deactivate) / Restore User","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]},"description":"Toggles user activation status, scoped to the current tenant.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nDelete (user not trashed): detaches the `tenant_users` pivot row for the current tenant. If the user has no remaining pivot rows after the detach, the central `users` row is soft-deleted as well; otherwise the central row stays intact so the user remains usable in other tenants.\n\nRestore (user trashed): re-attaches the pivot row for the current tenant (mirroring central's is_admin / is_power_user flags) and un-soft-deletes the central row. Restore is allowed when the user is already attached here OR is fully orphaned (no pivot rows anywhere). Restoring a user whose only pivots are to OTHER tenants is rejected (404) to prevent cross-tenant claim attacks.\n\nTenant scoping: Returns 404 if the user is not a member of the current tenant on the delete path. Prevents any tenant admin from deactivating users system-wide by guessing IDs.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `users.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/users/{user}","host":["{{baseUrl}}"],"path":["api","users",":user"],"variable":[{"key":"user","value":"1","description":"User ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"user Alice Johnson-Smith was successfully deleted\"\n}"}]},{"name":"List Users (list view)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/users?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","users"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]},"description":"Returns a paginated list view list of users. Supports search, sort, and pagination.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- page — Page number (default: 1)\n- limit — Results per page (default: 15)\n- search — Full-text search across name and email\n- sort — Sort field, prefix with - for descending (e.g., -created_at)\n- archived — 0 = active users, 1 = soft-deleted users\n- included[] — IDs to force-include in results\n- excluded[] — IDs to exclude from results"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/users?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","users"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Alice Johnson\",\n      \"email\": \"alice@example.com\",\n      \"email_verified_at\": \"2024-01-10T08:00:00.000000Z\",\n      \"activated_at\": \"2024-01-10T08:00:00.000000Z\",\n      \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n      \"updated_at\": \"2024-03-15T12:00:00.000000Z\",\n      \"deleted_at\": null,\n      \"is_admin\": true,\n      \"is_power_user\": false,\n      \"is_super_admin\": false,\n      \"role\": \"Admin\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Bob Smith\",\n      \"email\": \"bob@example.com\",\n      \"email_verified_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"activated_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"created_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"updated_at\": \"2024-02-01T09:00:00.000000Z\",\n      \"deleted_at\": null,\n      \"is_admin\": false,\n      \"is_power_user\": true,\n      \"is_super_admin\": false,\n      \"role\": \"Power User\"\n    }\n  ],\n  \"total\": 25,\n  \"per_page\": 15,\n  \"current_page\": 1,\n  \"last_page\": 2\n}"}]}]},{"name":"Roles & Permissions","item":[{"name":"List Roles","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/roles","host":["{{baseUrl}}"],"path":["api","roles"]},"description":"Lists all roles (sanctum guard) with their permissions and a users_count.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/roles","host":["{{baseUrl}}"],"path":["api","roles"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"admin\",\n      \"description\": \"Full system access with all permissions including user management, settings, and system configuration.\",\n      \"guard_name\": \"sanctum\",\n      \"users_count\": 3,\n      \"permissions\": [\n        {\n          \"id\": 1,\n          \"name\": \"users.index\",\n          \"guard_name\": \"sanctum\",\n          \"resource\": \"users\",\n          \"action\": \"index\",\n          \"created_at\": \"2024-01-01T00:00:00+00:00\",\n          \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"users.show\",\n          \"guard_name\": \"sanctum\",\n          \"resource\": \"users\",\n          \"action\": \"show\",\n          \"created_at\": \"2024-01-01T00:00:00+00:00\",\n          \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n        }\n      ],\n      \"created_at\": \"2024-01-01T00:00:00+00:00\",\n      \"updated_at\": \"2024-01-15T10:00:00+00:00\"\n    }\n  ]\n}"}]},{"name":"Create Role","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/roles","host":["{{baseUrl}}"],"path":["api","roles"]},"description":"Creates a new role (guard_name is forced to 'sanctum') and syncs the given permissions.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nBody fields:\n- name (required, string, max 255, unique in roles)\n- description (optional, string, max 500)\n- permissions (optional, array of permission names; each must exist in permissions)\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `roles.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"warehouse_manager\",\n  \"description\": \"Manage warehouses and inventory\",\n  \"permissions\": [\n    \"warehouses.index\",\n    \"warehouses.update\",\n    \"inventory.index\",\n    \"inventory.adjust\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/roles","host":["{{baseUrl}}"],"path":["api","roles"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"admin\",\n    \"description\": \"Full system access with all permissions including user management, settings, and system configuration.\",\n    \"guard_name\": \"sanctum\",\n    \"users_count\": 3,\n    \"permissions\": [\n      {\n        \"id\": 1,\n        \"name\": \"users.index\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"index\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"users.show\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"show\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      }\n    ],\n    \"created_at\": \"2024-01-01T00:00:00+00:00\",\n    \"updated_at\": \"2024-01-15T10:00:00+00:00\"\n  }\n}"}]},{"name":"Get Permissions (Grouped)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/roles/permissions/grouped","host":["{{baseUrl}}"],"path":["api","roles","permissions","grouped"]},"description":"Returns the full permission catalog grouped by resource for the permission-matrix UI. Each group has a resource key, human label, icon, and its permissions.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/roles/permissions/grouped","host":["{{baseUrl}}"],"path":["api","roles","permissions","grouped"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"resource\": \"users\",\n      \"label\": \"Users\",\n      \"icon\": \"mdi-account-group\",\n      \"permissions\": [\n        {\n          \"id\": 1,\n          \"name\": \"users.index\",\n          \"guard_name\": \"sanctum\",\n          \"resource\": \"users\",\n          \"action\": \"index\",\n          \"created_at\": \"2024-01-01T00:00:00+00:00\",\n          \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"users.show\",\n          \"guard_name\": \"sanctum\",\n          \"resource\": \"users\",\n          \"action\": \"show\",\n          \"created_at\": \"2024-01-01T00:00:00+00:00\",\n          \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n        }\n      ]\n    }\n  ]\n}"}]},{"name":"Show Role","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]},"description":"Returns a single role with its permissions and users_count.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"admin\",\n    \"description\": \"Full system access with all permissions including user management, settings, and system configuration.\",\n    \"guard_name\": \"sanctum\",\n    \"users_count\": 3,\n    \"permissions\": [\n      {\n        \"id\": 1,\n        \"name\": \"users.index\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"index\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"users.show\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"show\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      }\n    ],\n    \"created_at\": \"2024-01-01T00:00:00+00:00\",\n    \"updated_at\": \"2024-01-15T10:00:00+00:00\"\n  }\n}"}]},{"name":"Update Role","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]},"description":"Updates an existing role and re-syncs its permissions.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nBody fields:\n- name (required, string, max 255, unique in roles ignoring this role)\n- description (optional, string, max 500)\n- permissions (optional, array of permission names; each must exist in permissions)\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `roles.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"warehouse_manager\",\n  \"description\": \"Manage warehouses and inventory\",\n  \"permissions\": [\n    \"warehouses.index\",\n    \"warehouses.update\",\n    \"inventory.index\",\n    \"inventory.adjust\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"admin\",\n    \"description\": \"Full system access with all permissions including user management, settings, and system configuration.\",\n    \"guard_name\": \"sanctum\",\n    \"users_count\": 3,\n    \"permissions\": [\n      {\n        \"id\": 1,\n        \"name\": \"users.index\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"index\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"users.show\",\n        \"guard_name\": \"sanctum\",\n        \"resource\": \"users\",\n        \"action\": \"show\",\n        \"created_at\": \"2024-01-01T00:00:00+00:00\",\n        \"updated_at\": \"2024-01-01T00:00:00+00:00\"\n      }\n    ],\n    \"created_at\": \"2024-01-01T00:00:00+00:00\",\n    \"updated_at\": \"2024-01-15T10:00:00+00:00\"\n  }\n}"}]},{"name":"Delete Role","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]},"description":"Deletes a role. Users assigned the role lose its permissions.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nReturns 204 No Content on success.\n\nAuthentication: Requires Bearer token AND the `roles.delete` permission (403 Forbidden otherwise).\n\n**Requires permission:** `roles.delete`"},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/roles/{role}","host":["{{baseUrl}}"],"path":["api","roles",":role"],"variable":[{"key":"role","value":"1","description":"Role ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Assign Roles to User","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/users/{user}/roles","host":["{{baseUrl}}"],"path":["api","users",":user","roles"],"variable":[{"key":"user","value":"1","description":"User ID"}]},"description":"Syncs the Spatie roles assigned to a user (sanctum guard). Replaces the user's current roles with the provided list.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nBody fields:\n- roles (array of role names; each must exist in roles)\n\nReturns the updated user (including roles and flattened permissions).\n\nAuthentication: Requires Bearer token AND the `users.update` permission (403 Forbidden otherwise).\n\nErrors:\n- 403 Forbidden — authenticated user lacks the `users.update` permission\n- 404 Not Found — the target user does not belong to the current tenant (cross-tenant access is rejected)\n- 422 Unprocessable Entity — a provided role name does not exist\n\n**Requires permission:** `users.update`","body":{"mode":"raw","raw":"{\n  \"roles\": [\n    \"admin\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/users/{user}/roles","host":["{{baseUrl}}"],"path":["api","users",":user","roles"],"variable":[{"key":"user","value":"1","description":"User ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Alice Johnson\",\n    \"email\": \"alice@example.com\",\n    \"is_admin\": true,\n    \"is_power_user\": false,\n    \"is_super_admin\": false,\n    \"role\": \"Admin\",\n    \"roles\": [\n      {\n        \"id\": 1,\n        \"name\": \"admin\",\n        \"description\": \"Full system access...\",\n        \"guard_name\": \"sanctum\"\n      }\n    ],\n    \"permissions\": [\n      \"users.index\",\n      \"users.show\",\n      \"users.create\"\n    ]\n  }\n}"}]},{"name":"Bulk Update User Roles","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/users/roles/bulk","host":["{{baseUrl}}"],"path":["api","users","roles","bulk"]},"description":"Add or remove Spatie roles across many users at once (sanctum guard). Each user's other roles are left unchanged — this is NOT a sync/replace.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nTwo targeting modes:\n- Selected rows — pass `ids` (array of user IDs).\n- All filtered — pass `apply_to_all: true` and `filters` (the same filter set as the users list); every user matching the filters is targeted. Empty `filters` targets all tenant users.\n\nBody fields:\n- ids (array of user IDs; required unless filters/apply_to_all provided)\n- apply_to_all (boolean; optional)\n- filters (object; required unless ids provided — flat `column.operator` keys and/or a `filter_groups` tree)\n- action (string; required; one of: add, remove)\n- roles (array of role names; required, min 1; each must exist in roles)\n\nOnly users attached to the current tenant are affected — cross-tenant IDs are silently ignored.\n\nReturns a count message. If no users matched, returns 200 with a \"No users matched\" message.\n\nAuthentication: Requires Bearer token AND the `users.update` permission (403 Forbidden otherwise).\n\nErrors:\n- 403 Forbidden — authenticated user lacks the `users.update` permission\n- 422 Unprocessable Entity — invalid action, empty roles, or a role name that does not exist\n\n**Requires permission:** `users.update`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ],\n  \"action\": \"add\",\n  \"roles\": [\n    \"admin\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/users/roles/bulk","host":["{{baseUrl}}"],"path":["api","users","roles","bulk"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 user(s) updated — roles added to the selection.\"\n}"}]}]},{"name":"Feature Flags","item":[{"name":"Get Feature Flags","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/features","host":["{{baseUrl}}"],"path":["api","features"]},"description":"Returns the resolved feature-flag map for the account associated with the authenticated token. Each key is a feature name and each value is a boolean indicating whether that feature is enabled for the account. The same map is also included on `GET /api/auth/profile` under `features`; this standalone endpoint lets a client refresh feature state without re-fetching the full profile.\n\nAuthentication: Requires Bearer token.\n\n**Response fields (`data`):**\n- `granular_permissions` (boolean) — granular role/permission authorization is enabled.\n\nA feature absent from the map (or any value other than `true`) should be treated as disabled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/features","host":["{{baseUrl}}"],"path":["api","features"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"granular_permissions\": false\n  },\n  \"status\": \"success\"\n}"}]}]},{"name":"Alerts","item":[{"name":"List Alerts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alerts","host":["{{baseUrl}}"],"path":["api","alerts"]},"description":"Paginated list of the authenticated user's alerts.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAlerts are deduplicated: repeat occurrences of the same condition update a single alert (see `occurrences` and `last_seen_at`) instead of creating duplicates. State-type alerts (`lifecycle: state`) describe an ongoing condition and are automatically resolved when it clears — resolved alerts move out of the default listing and are available via `filter[status]=resolved`.\n\nEach alert carries a `reason` and human-readable `reason_label` explaining why the user received it (for example, \"You're an administrator\" or \"You're subscribed to this alert type\").\n\nDefault listing excludes dismissed and resolved alerts. Default sort: -last_seen_at."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alerts","host":["{{baseUrl}}"],"path":["api","alerts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": \"9c2f4c1e-8a4e-4f7c-9a2b-1d2f3a4b5c6d\",\n      \"priority\": \"high\",\n      \"category\": \"integrations\",\n      \"alert_type\": \"amazon_missing_nominal_code\",\n      \"lifecycle\": \"state\",\n      \"entity_tag\": \"Amazon\",\n      \"title\": \"Missing Amazon Accounting Mappings\",\n      \"message\": \"65 Amazon settlement codes need mapping for Amazon Leaf Shave.\",\n      \"action_url\": \"/integrations/amazon/finance/settlement-mappings\",\n      \"alertable_type\": null,\n      \"alertable_id\": null,\n      \"reason\": \"role:admin\",\n      \"reason_label\": \"You're an administrator\",\n      \"occurrences\": 4,\n      \"status\": \"active\",\n      \"is_read\": false,\n      \"read_at\": null,\n      \"resolved_at\": null,\n      \"resolved_ago\": null,\n      \"last_seen_at\": \"2026-07-16T14:05:00+00:00\",\n      \"created_at\": \"2026-07-13T09:12:00+00:00\",\n      \"first_seen_ago\": \"3 days ago\",\n      \"time_ago\": \"2 hours ago\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 20,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Get Unread Count","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/unread-count","host":["{{baseUrl}}"],"path":["api","alerts","unread-count"]},"description":"Returns unread alert counts broken down by priority for the authenticated user. Used to populate notification badges.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alerts/unread-count","host":["{{baseUrl}}"],"path":["api","alerts","unread-count"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"high\": 3,\n  \"normal\": 12\n}"}]},{"name":"Get Category Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/category-counts","host":["{{baseUrl}}"],"path":["api","alerts","category-counts"]},"description":"Returns alert counts grouped by category for the authenticated user. Used to show category-level notification counts in the UI.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nCategories: orders, inventory, purchase_orders, integrations, system, financial"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alerts/category-counts","host":["{{baseUrl}}"],"path":["api","alerts","category-counts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"orders\": 5,\n  \"inventory\": 2,\n  \"purchase_orders\": 0,\n  \"integrations\": 1,\n  \"system\": 0,\n  \"financial\": 3\n}"}]},{"name":"Mark Alert as Read","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/{alert}/read","host":["{{baseUrl}}"],"path":["api","alerts",":alert","read"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]},"description":"Marks the specified alert as read by setting the read_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/{alert}/read","host":["{{baseUrl}}"],"path":["api","alerts",":alert","read"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Alert marked as read.\"\n}"}]},{"name":"Mark Alert as Unread","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/{alert}/unread","host":["{{baseUrl}}"],"path":["api","alerts",":alert","unread"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]},"description":"Marks the specified alert as unread by clearing the read_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/{alert}/unread","host":["{{baseUrl}}"],"path":["api","alerts",":alert","unread"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Alert marked as unread.\"\n}"}]},{"name":"Mark All as Read","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/mark-all-read","host":["{{baseUrl}}"],"path":["api","alerts","mark-all-read"]},"description":"Marks all alerts as read for the authenticated user. Optionally filter by priority.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body (optional):\n- priority (string, optional): Filter to only mark alerts of this priority as read. Values: 'high', 'normal'. Omit to mark all alerts read.","body":{"mode":"raw","raw":"{\n  \"priority\": \"high\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/mark-all-read","host":["{{baseUrl}}"],"path":["api","alerts","mark-all-read"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All alerts marked as read.\"\n}"}]},{"name":"Dismiss All Alerts","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/dismiss-all","host":["{{baseUrl}}"],"path":["api","alerts","dismiss-all"]},"description":"Dismisses all alerts for the authenticated user by setting their dismissed_at timestamp. Optionally filter by priority.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body (optional):\n- priority (string, optional): Filter to only dismiss alerts of this priority. Values: 'high', 'normal'. Omit to dismiss all.","body":{"mode":"raw","raw":"{\n  \"priority\": \"normal\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/dismiss-all","host":["{{baseUrl}}"],"path":["api","alerts","dismiss-all"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"All alerts dismissed.\"\n}"}]},{"name":"Dismiss Alert","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/{alert}/dismiss","host":["{{baseUrl}}"],"path":["api","alerts",":alert","dismiss"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]},"description":"Dismisses the specified alert by setting the dismissed_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/{alert}/dismiss","host":["{{baseUrl}}"],"path":["api","alerts",":alert","dismiss"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Alert dismissed.\"\n}"}]},{"name":"Undismiss Alert","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/alerts/{alert}/undismiss","host":["{{baseUrl}}"],"path":["api","alerts",":alert","undismiss"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]},"description":"Restores (undismisses) the specified alert by clearing the dismissed_at timestamp.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token"},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/{alert}/undismiss","host":["{{baseUrl}}"],"path":["api","alerts",":alert","undismiss"],"variable":[{"key":"alert","value":"550e8400-e29b-41d4-a716-446655440000","description":"Alert ID (UUID)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Alert restored.\"\n}"}]},{"name":"Bulk Mark as Read","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/bulk-read","host":["{{baseUrl}}"],"path":["api","alerts","bulk-read"]},"description":"Marks multiple alerts as read in a single request.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of alert UUIDs to mark as read","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    \"550e8400-e29b-41d4-a716-446655440000\",\n    \"661f9511-f30c-52e5-b827-557766551111\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/bulk-read","host":["{{baseUrl}}"],"path":["api","alerts","bulk-read"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 alerts marked as read.\"\n}"}]},{"name":"Bulk Mark as Unread","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/bulk-unread","host":["{{baseUrl}}"],"path":["api","alerts","bulk-unread"]},"description":"Marks multiple alerts as unread in a single request.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of alert UUIDs to mark as unread","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    \"550e8400-e29b-41d4-a716-446655440000\",\n    \"661f9511-f30c-52e5-b827-557766551111\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/bulk-unread","host":["{{baseUrl}}"],"path":["api","alerts","bulk-unread"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 alerts marked as unread.\"\n}"}]},{"name":"Bulk Dismiss","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/bulk-dismiss","host":["{{baseUrl}}"],"path":["api","alerts","bulk-dismiss"]},"description":"Dismisses multiple alerts in a single request.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of alert UUIDs to dismiss","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    \"550e8400-e29b-41d4-a716-446655440000\",\n    \"661f9511-f30c-52e5-b827-557766551111\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/bulk-dismiss","host":["{{baseUrl}}"],"path":["api","alerts","bulk-dismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 alerts dismissed.\"\n}"}]},{"name":"Bulk Undismiss","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alerts/bulk-undismiss","host":["{{baseUrl}}"],"path":["api","alerts","bulk-undismiss"]},"description":"Restores (undismisses) multiple alerts in a single request.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token\n\nRequest body:\n- ids (array, required): Array of alert UUIDs to undismiss","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    \"550e8400-e29b-41d4-a716-446655440000\",\n    \"661f9511-f30c-52e5-b827-557766551111\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alerts/bulk-undismiss","host":["{{baseUrl}}"],"path":["api","alerts","bulk-undismiss"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 alerts restored.\"\n}"}]},{"name":"Get Alert Audience","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alert-subscriptions?alert_type=amazon_missing_nominal_code","host":["{{baseUrl}}"],"path":["api","alert-subscriptions"],"query":[{"key":"alert_type","value":"amazon_missing_nominal_code","description":"The alert type to inspect (required). One of the alert type identifiers returned by List Alert Preferences.","disabled":true}]},"description":"Returns the resolved audience for one alert type: every user who currently receives it and why. The audience is the type's default audience (administrators, all users, or holders of a permission) merged with explicit subscribe/unsubscribe changes.\n\nEach member's `source` explains their inclusion: `role:admin`, `permission:<name>`, `subscription`, or `all_users`.\n\nRequires a token with permission to view alert preferences."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alert-subscriptions?alert_type=amazon_missing_nominal_code","host":["{{baseUrl}}"],"path":["api","alert-subscriptions"],"query":[{"key":"alert_type","value":"amazon_missing_nominal_code","description":"The alert type to inspect (required). One of the alert type identifiers returned by List Alert Preferences.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"alert_type\": \"amazon_missing_nominal_code\",\n    \"default_audience\": \"all administrators\",\n    \"mandatory\": false,\n    \"users\": [\n      {\n        \"id\": 7,\n        \"name\": \"Jane Winters\",\n        \"email\": \"jane@acme.com\",\n        \"source\": \"role:admin\"\n      },\n      {\n        \"id\": 42,\n        \"name\": \"Sam Okafor\",\n        \"email\": \"sam@acme.com\",\n        \"source\": \"subscription\"\n      }\n    ]\n  }\n}"}]},{"name":"Update Alert Audience","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alert-subscriptions","host":["{{baseUrl}}"],"path":["api","alert-subscriptions"]},"description":"Applies audience changes for one alert type.\n\nActions per change:\n- `subscribe` — add the user to the audience (beyond the default audience)\n- `unsubscribe` — remove the user, including default-audience members\n- `reset` — remove any explicit change so the user reverts to plain default-audience membership\n\nReturns the refreshed audience. Returns 422 when a change would leave a critical alert type with an empty audience, or when a user does not belong to this account.\n\nRequires a token with permission to update alert preferences.","body":{"mode":"raw","raw":"{\n  \"alert_type\": \"amazon_missing_nominal_code\",\n  \"changes\": [\n    {\n      \"user_id\": 42,\n      \"action\": \"subscribe\"\n    },\n    {\n      \"user_id\": 7,\n      \"action\": \"unsubscribe\"\n    },\n    {\n      \"user_id\": 13,\n      \"action\": \"reset\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alert-subscriptions","host":["{{baseUrl}}"],"path":["api","alert-subscriptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"alert_type\": \"amazon_missing_nominal_code\",\n    \"default_audience\": \"all administrators\",\n    \"mandatory\": false,\n    \"users\": [\n      {\n        \"id\": 7,\n        \"name\": \"Jane Winters\",\n        \"email\": \"jane@acme.com\",\n        \"source\": \"role:admin\"\n      },\n      {\n        \"id\": 42,\n        \"name\": \"Sam Okafor\",\n        \"email\": \"sam@acme.com\",\n        \"source\": \"subscription\"\n      }\n    ]\n  }\n}"}]},{"name":"Get Alert Audience Counts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alert-subscriptions/counts","host":["{{baseUrl}}"],"path":["api","alert-subscriptions","counts"]},"description":"Audience size per alert type — how many users currently receive each type after subscribe/unsubscribe changes are applied to the default audience. A count of 0 means nobody will receive that alert.\n\nRequires a token with permission to view alert preferences."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alert-subscriptions/counts","host":["{{baseUrl}}"],"path":["api","alert-subscriptions","counts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"export_completed\": 3,\n    \"amazon_missing_nominal_code\": 4,\n    \"integration_sync_inactive\": 3\n  }\n}"}]},{"name":"Get My Notification Preferences","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/alert-preferences/mine","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine"]},"description":"The authenticated user's personal notification preference matrix. Only alert types whose audience includes the user are returned, grouped by category (and by integration for integration-specific types).\n\nEach row shows the resolved value per channel plus an `inherited` marker — `true` means the value comes from the account-wide preference or the built-in default rather than a personal override. Rows with `mandatory: true` cannot have their in-app channel disabled. `audience_reason` explains why the user receives the type at all."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/alert-preferences/mine","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"groups\": {\n      \"purchase_orders\": {\n        \"label\": \"Purchase Orders\",\n        \"icon\": null,\n        \"preferences\": [\n          {\n            \"alert_type\": \"purchase_order_approval_requested\",\n            \"label\": \"Purchase Order Approval Requested\",\n            \"description\": \"Triggered when a user without approval permission submits a purchase order for approval.\",\n            \"mandatory\": false,\n            \"audience_reason\": \"permission:purchase_orders.approve\",\n            \"audience_reason_label\": \"You can approve purchase orders\",\n            \"priority\": \"high\",\n            \"tenant_enabled\": true,\n            \"in_app\": {\n              \"value\": true,\n              \"inherited\": true\n            },\n            \"email\": {\n              \"value\": false,\n              \"inherited\": true\n            },\n            \"frequency\": {\n              \"value\": \"instant\",\n              \"inherited\": true\n            }\n          }\n        ]\n      }\n    }\n  }\n}"}]},{"name":"Update My Notification Preferences","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alert-preferences/mine","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine"]},"description":"Updates the authenticated user's personal notification overrides. Fields are tri-state: send `null` to reset a field so it inherits the account-wide preference / built-in default again; omit a field to leave it unchanged.\n\nFields per preference:\n- `alert_type` (string, required)\n- `in_app_enabled` (boolean or null) — whether this alert appears in your in-app alert tray\n- `email_enabled` (boolean or null) — whether this alert is emailed to your own address\n- `notification_frequency` (string or null) — `instant`, `daily_digest`, or `weekly_digest`\n\nReturns 422 when disabling the in-app channel for a critical (mandatory) alert type.","body":{"mode":"raw","raw":"{\n  \"preferences\": [\n    {\n      \"alert_type\": \"purchase_order_approval_requested\",\n      \"in_app_enabled\": true,\n      \"email_enabled\": false,\n      \"notification_frequency\": \"daily_digest\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/alert-preferences/mine","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Notification preferences updated.\"\n}"}]},{"name":"Apply My Notification Preset","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/alert-preferences/mine/preset","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine","preset"]},"description":"Applies a notification preset as a starting point for the authenticated user's preference matrix (individual rows stay editable afterwards).\n\nPresets:\n- `everything` — clear all personal overrides; every channel inherits the defaults\n- `important` — keep the in-app channel for high-priority and critical types only\n- `critical` — keep the in-app channel for critical types only","body":{"mode":"raw","raw":"{\n  \"preset\": \"important\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/alert-preferences/mine/preset","host":["{{baseUrl}}"],"path":["api","alert-preferences","mine","preset"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Preset applied.\"\n}"}]}]},{"name":"Jobs & Logs","item":[{"name":"Show Tracked Job Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]},"description":"Returns a single tracked job log by ID with full progress details including batch progress, results, and status transitions.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 142,\n    \"job_type\": \"App\\\\Jobs\\\\Shopify\\\\SyncShopifyOrdersJob\",\n    \"queue\": \"default\",\n    \"job_name\": \"Sync Shopify Orders: MyStore\",\n    \"status\": \"completed\",\n    \"related_model\": {\n      \"id\": 5,\n      \"type\": \"App\\\\Modules\\\\Shopify\\\\Models\\\\ShopifyIntegrationInstance\",\n      \"reference\": \"MyStore\"\n    },\n    \"related_model_reference\": \"MyStore\",\n    \"messages\": null,\n    \"attempted_at\": \"2024-06-01T09:00:00.000000Z\",\n    \"completed_at\": \"2024-06-01T09:05:23.000000Z\",\n    \"duration\": 323,\n    \"created_at\": \"2024-06-01T09:00:00.000000Z\",\n    \"updated_at\": \"2024-06-01T09:05:23.000000Z\",\n    \"fetch_batch\": {\n      \"batch_id\": \"abc123\",\n      \"total\": 50,\n      \"processed\": 50,\n      \"failed\": 0,\n      \"progress_percentage\": 100,\n      \"finished\": true\n    },\n    \"detail_batch\": null,\n    \"status_batches\": null,\n    \"results\": {\n      \"synced_orders\": 45,\n      \"skipped\": 2,\n      \"has_failures\": false,\n      \"failed_count\": 0\n    },\n    \"total_items\": 47,\n    \"processed_items\": 47,\n    \"progress_percentage\": 100\n  }\n}"}]},{"name":"Update Tracked Job Log","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]},"description":"Updates a tracked job log (e.g., to mark it as cancelled). Used by the frontend tracked job log endpoints to cancel running jobs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"status\": \"cancelled\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 142,\n    \"status\": \"cancelled\"\n  }\n}"}]},{"name":"Delete Tracked Job Log","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]},"description":"Deletes a tracked job log by ID.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tracked-job-logs/{tracked_job_log}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs",":tracked_job_log"],"variable":[{"key":"tracked_job_log","value":"142","description":"Tracked job log ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"Retry Job","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs/retry/{trackedJobLog}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs","retry",":trackedJobLog"],"variable":[{"key":"trackedJobLog","value":"142","description":"Tracked job log ID"}]},"description":"Re-dispatches a previously tracked background job using the same arguments stored in the job log. The job is re-created via reflection and dispatched to the same queue.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tracked-job-logs/retry/{trackedJobLog}","host":["{{baseUrl}}"],"path":["api","tracked-job-logs","retry",":trackedJobLog"],"variable":[{"key":"trackedJobLog","value":"142","description":"Tracked job log ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Job has been requeued.\"\n}"}]},{"name":"List Tracked Job Logs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","tracked-job-logs"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]},"description":"Returns a paginated list view list of tracked job logs. Tracked jobs represent background queue jobs visible via the tracked job log endpoints.\n\nAuthentication: Requires Bearer token.\n\nQuery parameters:\n- page — Page number (default: 1)\n- limit — Results per page (default: 15)\n- search — Full-text search by job name or type\n- sort — Sort field, prefix with - for descending (e.g., -created_at)\n- archived — 0 = active records, 1 = archived records"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tracked-job-logs?page=1&limit=15","host":["{{baseUrl}}"],"path":["api","tracked-job-logs"],"query":[{"key":"page","value":"1","description":"Page number for pagination","disabled":true},{"key":"limit","value":"15","description":"Number of results per page","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 142,\n      \"job_type\": \"App\\\\Jobs\\\\Shopify\\\\SyncShopifyOrdersJob\",\n      \"queue\": \"default\",\n      \"job_name\": \"Sync Shopify Orders: MyStore\",\n      \"status\": \"completed\",\n      \"related_model\": {\n        \"id\": 5,\n        \"type\": \"App\\\\Modules\\\\Shopify\\\\Models\\\\ShopifyIntegrationInstance\",\n        \"reference\": \"MyStore\"\n      },\n      \"related_model_reference\": \"MyStore\",\n      \"messages\": null,\n      \"attempted_at\": \"2024-06-01T09:00:00.000000Z\",\n      \"completed_at\": \"2024-06-01T09:05:23.000000Z\",\n      \"duration\": 323,\n      \"created_at\": \"2024-06-01T09:00:00.000000Z\",\n      \"updated_at\": \"2024-06-01T09:05:23.000000Z\",\n      \"fetch_batch\": null,\n      \"detail_batch\": null,\n      \"status_batches\": null,\n      \"results\": {\n        \"synced_orders\": 45,\n        \"skipped\": 2\n      },\n      \"total_items\": 47,\n      \"processed_items\": 47,\n      \"progress_percentage\": 100\n    }\n  ],\n  \"total\": 350,\n  \"per_page\": 15,\n  \"current_page\": 1,\n  \"last_page\": 24\n}"}]},{"name":"Create Tracked Job Log","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tracked-job-logs","host":["{{baseUrl}}"],"path":["api","tracked-job-logs"]},"description":"Creates a new tracked job log entry. Note: Tracked job logs are typically created automatically by the TrackableJobTrait when background jobs are dispatched.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"job_name\": \"Manual Job Entry\",\n  \"status\": \"pending\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tracked-job-logs","host":["{{baseUrl}}"],"path":["api","tracked-job-logs"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 143,\n  \"job_name\": \"Manual Job Entry\",\n  \"status\": \"pending\"\n}"}]}]},{"name":"Integration Instances","item":[{"name":"List Integrations (Picker)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integrations?include_sku_io=0","host":["{{baseUrl}}"],"path":["api","integrations"],"query":[{"key":"include_sku_io","value":"0","description":"Optional (0/1). When 1, prepends the internal SKU.io integration to the list.","disabled":true}]},"description":"List all available integrations and their connected instances. Powers the integration picker in the UI.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token + Power User access.\n\nEach integration includes a `deprecated` boolean. **Deprecated integrations (e.g. ShipMyOrders) are hidden from this list unless the tenant still has at least one connected instance**, in which case the integration is returned so its existing instances can be shown read-only. Deprecated integrations can no longer be connected (see `POST /api/integration-instances`)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integrations?include_sku_io=0","host":["{{baseUrl}}"],"path":["api","integrations"],"query":[{"key":"include_sku_io","value":"0","description":"Optional (0/1). When 1, prepends the internal SKU.io integration to the list.","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Shopify\",\n      \"integration_settings_template\": {},\n      \"image_url\": \"https://cdn.sku.io/integrations/shopify.png\",\n      \"country\": null,\n      \"supports_multiple_instances\": true,\n      \"integration_type\": \"sales_channel\",\n      \"integration_sub_type\": null,\n      \"deprecated\": false,\n      \"last_sync\": \"2026-06-15T08:30:00.000000Z\",\n      \"integration_instances\": []\n    },\n    {\n      \"id\": 12,\n      \"name\": \"ShipMyOrders\",\n      \"integration_settings_template\": {},\n      \"image_url\": \"https://cdn.sku.io/integrations/shipmyorders.png\",\n      \"country\": null,\n      \"supports_multiple_instances\": false,\n      \"integration_type\": \"shipping_provider\",\n      \"integration_sub_type\": null,\n      \"deprecated\": true,\n      \"last_sync\": null,\n      \"integration_instances\": [\n        {\n          \"id\": 44,\n          \"integration_id\": 12,\n          \"name\": \"ShipMyOrders\"\n        }\n      ]\n    }\n  ],\n  \"automated_warehouses\": [],\n  \"status\": \"success\"\n}"}]},{"name":"Create Integration Instance","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances","host":["{{baseUrl}}"],"path":["api","integration-instances"]},"description":"Create a new integration instance.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nRequired: integration_id. Either name or integration_settings.settings.connectionName must be provided.\n\nThe store ID from integration_settings.settings.store.id will create an associated sales channel.\nFor Shopify: triggers location, webhook, products, and orders download if credentials are present.\nFor ShipStation: fetches shipping services and creates webhooks.\nFor ShipMyOrders: queues warehouse initialization.\nFor Veracore: converts linked warehouse type to 3PL.\n\nNote: name must be unique across all integration instances.\n\n**Requires permission:** `integrations.create`\n\n**Deprecated integrations:** If the supplied `integration_id` belongs to a permanently deprecated integration (e.g. ShipMyOrders), the request is rejected with `400 Bad Request` and code `IsUnacceptable`. Existing instances and their historical data are retained read-only, but no new instance can be connected.","body":{"mode":"raw","raw":"{\n  \"integration_id\": 3,\n  \"name\": \"My Shopify Store\",\n  \"connection_settings\": {},\n  \"integration_settings\": {\n    \"settings\": {\n      \"connectionName\": \"My Shopify Store\",\n      \"store\": {\n        \"id\": \"myshop.myshopify.com\"\n      }\n    },\n    \"orders\": {\n      \"download\": {\n        \"open_start_date\": \"2024-01-01T00:00:00\",\n        \"closed_start_date\": \"2024-01-01T00:00:00\"\n      }\n    },\n    \"emailCustomers\": false\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances","host":["{{baseUrl}}"],"path":["api","integration-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_id\": 3,\n    \"integration\": {\n      \"id\": 3,\n      \"name\": \"Shopify\",\n      \"integration_type\": \"sales_channel\"\n    },\n    \"name\": \"My Shopify Store\",\n    \"connection_settings\": {},\n    \"integration_settings\": {\n      \"settings\": {\n        \"connectionName\": \"My Shopify Store\"\n      },\n      \"emailCustomers\": false\n    },\n    \"sales_channel\": {\n      \"id\": 8,\n      \"integration_instance_id\": 12,\n      \"store_id\": \"myshop.myshopify.com\"\n    },\n    \"store_mappings\": [],\n    \"is_deleting\": false,\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true\n  },\n  \"automated_warehouses\": []\n}"}]},{"name":"Get Integration Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Get a single integration instance with its integration, store mappings, and warehouse location map.\n\n**Required scope: `integrations:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nNote: access_token is stripped from connection_settings before returning."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_id\": 3,\n    \"integration\": {\n      \"id\": 3,\n      \"name\": \"Shopify\",\n      \"integration_type\": \"sales_channel\"\n    },\n    \"name\": \"My Shopify Store\",\n    \"connection_settings\": {\n      \"shop_url\": \"myshop.myshopify.com\"\n    },\n    \"integration_settings\": {\n      \"settings\": {\n        \"connectionName\": \"My Shopify Store\"\n      },\n      \"emailCustomers\": false,\n      \"inventory\": {\n        \"sync_all_warehouses\": true\n      }\n    },\n    \"sales_channel\": {\n      \"id\": 8,\n      \"store_id\": \"myshop.myshopify.com\"\n    },\n    \"store_mappings\": [],\n    \"is_deleting\": false,\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true\n  },\n  \"automated_warehouses\": [],\n  \"warehouse_location_map\": [\n    {\n      \"shopify_location_id\": 123456789,\n      \"name\": \"Main Warehouse\",\n      \"warehouse_id\": 1,\n      \"warehouse_name\": \"Main Warehouse\"\n    }\n  ]\n}"}]},{"name":"Update Integration Instance","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Update an integration instance. Settings are merged (not replaced) with existing settings.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nAll fields are optional. Name must be unique.\n\nIf inventory settings change for a sales channel integration, triggers inventory cache invalidation.\nIf pricing settings change, triggers product listing price cache refresh.\nFor sales channel integrations: syncs accounting transaction statuses if sync settings change.\n\nAllowed integration_settings.batch_period_sales_order_fulfillments values: daily, monthly, none.\n\n**Requires permission:** `integrations.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"My Shopify Store (Updated)\",\n  \"integration_settings\": {\n    \"settings\": {\n      \"connectionName\": \"My Shopify Store (Updated)\"\n    },\n    \"inventory\": {\n      \"sync_all_warehouses\": true\n    },\n    \"sync_sales_order_invoices_to_accounting\": false,\n    \"sync_sales_credit_to_accounting\": false,\n    \"batch_period_sales_order_fulfillments\": \"daily\",\n    \"proforma_marketplace_cost_percentage\": 2.5,\n    \"proforma_payment_cost_percentage\": 1.5\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"name\": \"My Shopify Store (Updated)\",\n    \"integration_settings\": {\n      \"settings\": {\n        \"connectionName\": \"My Shopify Store (Updated)\"\n      },\n      \"inventory\": {\n        \"sync_all_warehouses\": true\n      },\n      \"sync_sales_order_invoices_to_accounting\": false\n    },\n    \"is_automatic_sync_enabled\": true\n  },\n  \"automated_warehouses\": []\n}"}]},{"name":"Delete Integration Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Queue deletion of an integration instance. The actual deletion is handled asynchronously via the salesOrderProcessing queue.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\n**Requires permission:** `integrations.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to the queue.\"\n}"}]},{"name":"Get Single Listing","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/{id}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings",":id"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"id","value":"abc123","description":"Listing ID (SKU, variant_id, seller_sku, or _id depending on integration)"}]},"description":"Lookup a listing document in the sales channel. For Amazon: searches by seller_sku. For Shopify: by variant_id, sku, or id. For others: by sku or _id.\n\n**Required scope: `integrations:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/{id}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings",":id"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"id","value":"abc123","description":"Listing ID (SKU, variant_id, seller_sku, or _id depending on integration)"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"abc123\",\n    \"sku\": \"WIDGET-001\",\n    \"title\": \"Widget A\",\n    \"integration_instance_id\": 12,\n    \"product_listing\": {\n      \"id\": 300,\n      \"product\": {\n        \"id\": 55,\n        \"name\": \"Widget A\"\n      }\n    }\n  }\n}"}]},{"name":"Delete Single Listing","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/{id}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings",":id"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"id","value":"abc123","description":"Listing ID"}]},"description":"Delete a single listing from the integration instance.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nReturns 400 if the listing is linked and cannot be deleted."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/{id}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings",":id"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"id","value":"abc123","description":"Listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"listing abc123 deleted successfully\"\n}"}]},{"name":"Download Listings from Channel","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/download","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings","download"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Queue a download of listings (products) from the sales channel.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nSupports: Shopify. Other integrations return an informational message."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/listings/download","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","listings","download"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Shopify Listings download added to the Queue, it will be processed shortly.\"\n}"}]},{"name":"Import Listing Mappings","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/import-mappings","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","import-mappings"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Import listing mappings from a previously uploaded file. Dispatches an ImportListingMapping job.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nReturns a task_id for progress tracking.\n\n**Requires permission:** `integrations.manage`","body":{"mode":"raw","raw":"{\n  \"original_name\": \"mappings.csv\",\n  \"stored_name\": \"abc123.csv\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/import-mappings","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","import-mappings"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"task_id\": \"task-uuid-abc123\"\n}"}]},{"name":"Get Single Sales Channel Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]},"description":"Get a single sales channel order with its linked SKU sales order.\n\n**Required scope: `integrations:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": \"order_abc\",\n    \"order_number\": \"#1001\",\n    \"integration_instance_id\": 12,\n    \"sales_order\": null\n  }\n}"}]},{"name":"Refresh Order from Sales Channel","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/refresh","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","refresh"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]},"description":"Refresh a sales channel order with fresh data from the channel API, then reconcile the linked SKU sales order.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nSupported channels: Shopify, WooCommerce, eBay, Walmart, BigCommerce, and Faire. Fetches the latest order from the channel and propagates changes to the linked SKU sales order (status/payment, and — for Faire — line additions, quantity edits, and removals). Returns the updated SalesOrder resource. Unsupported channels return an UnsupportedChannel error."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/refresh","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","refresh"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 501,\n    \"order_number\": \"SO-2024-1001\",\n    \"status\": \"open\"\n  }\n}"}]},{"name":"Download Orders from Channel","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/download-orders","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","download-orders"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Queue a download of orders from the sales channel.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nFor Shopify: date_method (created|updated) and from_date.\nFor Amazon: downloads MFN orders.\n\n**Requires permission:** `integrations.sync`","body":{"mode":"raw","raw":"{\n  \"date_method\": \"created\",\n  \"from_date\": \"2024-01-01\",\n  \"status\": \"open\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/download-orders","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","download-orders"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Added to the Queue, it will be processed shortly\"\n}"}]},{"name":"Archive Single Channel Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","archive"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]},"description":"Archive a single sales channel order.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/archive","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","archive"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"order archived successfully\"\n}"}]},{"name":"Unarchive Single Channel Order","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/unarchived","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","unarchived"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]},"description":"Unarchive a single sales channel order.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/orders/{order}/unarchived","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","orders",":order","unarchived"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"},{"key":"order","value":"order_abc","description":"Order ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"order unarchived successfully\"\n}"}]},{"name":"Preview Sync Inventory","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-inventory/preview?location_id=123456","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-inventory","preview"],"query":[{"key":"location_id","value":"123456","description":"Optional: filter to a specific location ID","disabled":true}],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Preview what inventory values would be synced to the sales channel before actually syncing.\n\n**Required scope: `integrations:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nCalculates current available quantities for all product listings in the integration. Returns 400 if no product listings found.\n\n**Requires permission:** `integrations.sync`"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-inventory/preview?location_id=123456","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-inventory","preview"],"query":[{"key":"location_id","value":"123456","description":"Optional: filter to a specific location ID","disabled":true}],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"[\n  {\n    \"sku\": \"WIDGET-001\",\n    \"product_name\": \"Widget A\",\n    \"current_quantity\": 150,\n    \"calculated_quantity\": 145,\n    \"location_id\": 123456\n  }\n]"}]},{"name":"Store Mapped Warehouse Locations","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Save Shopify location to warehouse mappings for an integration instance.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + Power User access.\n\nRequired: warehouse_mappings array. shopify_location_id must exist in shopify_locations. warehouse_id must exist in warehouses.","body":{"mode":"raw","raw":"{\n  \"warehouse_mappings\": [\n    {\n      \"shopify_location_id\": 123456789,\n      \"warehouse_id\": 1\n    },\n    {\n      \"shopify_location_id\": 987654321,\n      \"warehouse_id\": 2\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/store-mapped-warehouse-locations","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","store-mapped-warehouse-locations"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Warehouse mappings updated successfully.\"\n}"}]},{"name":"Update Sync Controls","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Apply a granular, direction- and entity-aware sync-controls update for a channel integration instance. Replaces the overloaded `is_automatic_sync_enabled` boolean with per-capability toggles.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + `integrations.update` permission.\n\nAll sections are OPTIONAL — send a partial PATCH and only the provided keys are merged onto the instance's current (or default) controls:\n\n- `schedule_state` — `active` or `paused`. Drives the derived `is_automatic_sync_enabled` coarse flag and pauses/resumes all scheduled sync.\n- `capabilities` — map of direction (`inbound`/`outbound`) to a map of entity (`orders`, `products`, `inventory`, `pricing`, `tracking`) to boolean. Capabilities outside the integration's applicable matrix are silently discarded.\n- `source_of_truth` — for BIDIRECTIONAL entities only (`inventory`, `pricing`): `sku` or `channel`. Non-bidirectional entries are ignored.\n\nReturns the updated integration instance object, including `sync_controls`, `applicable_sync_capabilities`, and `is_sync_schedule_paused`. Each `applicable_sync_capabilities` descriptor carries `entity`, `label`, `capability_label`, `is_bidirectional`, plus `environment_blocked` (bool) and `environment_blocked_reason` (string|null). `environment_blocked` is `true` when the current backend environment refuses to run that outbound push — e.g. outside production, Amazon's production-only inventory feed, or Shopify's inventory push (unless `shopify.inventory_sync_enabled`) and tracking push. Always `false` in production and for unrestricted pushes — so the UI renders that toggle as disabled with `environment_blocked_reason` as the explanation.\n\nAccounting integrations are rejected with 400 — they use the separate accounting sync configuration.\n\n**Deprecation note:** `is_automatic_sync_enabled` is a legacy coarse flag kept as a derived mirror of the sync-controls schedule state (`sync_controls.scheduleState`). New consumers should read `is_sync_schedule_paused` for the schedule and `sync_controls` for per-capability state; the legacy field is slated for rename to `sync_schedule_active`.","body":{"mode":"raw","raw":"{\n  \"schedule_state\": \"active\",\n  \"capabilities\": {\n    \"inbound\": {\n      \"orders\": true,\n      \"products\": true\n    },\n    \"outbound\": {\n      \"tracking\": true,\n      \"inventory\": true,\n      \"pricing\": false\n    }\n  },\n  \"source_of_truth\": {\n    \"inventory\": \"sku\",\n    \"pricing\": \"channel\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_id\": 3,\n    \"name\": \"My Shopify Store\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true,\n    \"sync_status\": \"active\",\n    \"sync_controls\": {\n      \"schedule_state\": \"active\",\n      \"capabilities\": {\n        \"inbound\": {\n          \"orders\": true,\n          \"products\": true\n        },\n        \"outbound\": {\n          \"tracking\": true,\n          \"inventory\": true,\n          \"pricing\": false\n        }\n      },\n      \"source_of_truth\": {\n        \"inventory\": \"sku\",\n        \"pricing\": \"channel\"\n      }\n    },\n    \"applicable_sync_capabilities\": {\n      \"inbound\": [\n        {\n          \"entity\": \"orders\",\n          \"label\": \"Orders\",\n          \"capability_label\": \"Import Orders\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"products\",\n          \"label\": \"Products\",\n          \"capability_label\": \"Import Products\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ],\n      \"outbound\": [\n        {\n          \"entity\": \"tracking\",\n          \"label\": \"Tracking\",\n          \"capability_label\": \"Submit Tracking\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"inventory\",\n          \"label\": \"Inventory\",\n          \"capability_label\": \"Push Inventory\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"pricing\",\n          \"label\": \"Pricing\",\n          \"capability_label\": \"Push Pricing\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ]\n    },\n    \"is_sync_schedule_paused\": false\n  }\n}"}]},{"name":"Pause Sync Schedule","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls/pause","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls","pause"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Pause the integration instance's automatic sync schedule. Sets `schedule_state` to `paused`, which short-circuits all scheduled inbound pulls, inbound webhook processing, and outbound submissions, and flips the derived `is_automatic_sync_enabled` flag to false. Per-capability toggles are preserved so resuming restores the prior configuration.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + `integrations.update` permission.\n\nNo request body. Returns the updated integration instance object.\n\n**Deprecation note:** `is_automatic_sync_enabled` is a legacy coarse flag kept as a derived mirror of the sync-controls schedule state (`sync_controls.scheduleState`). New consumers should read `is_sync_schedule_paused` for the schedule and `sync_controls` for per-capability state; the legacy field is slated for rename to `sync_schedule_active`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls/pause","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls","pause"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_id\": 3,\n    \"name\": \"My Shopify Store\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": false,\n    \"sync_status\": \"active\",\n    \"sync_controls\": {\n      \"schedule_state\": \"paused\",\n      \"capabilities\": {\n        \"inbound\": {\n          \"orders\": true,\n          \"products\": true\n        },\n        \"outbound\": {\n          \"tracking\": true,\n          \"inventory\": true,\n          \"pricing\": false\n        }\n      },\n      \"source_of_truth\": {\n        \"inventory\": \"sku\",\n        \"pricing\": \"channel\"\n      }\n    },\n    \"applicable_sync_capabilities\": {\n      \"inbound\": [\n        {\n          \"entity\": \"orders\",\n          \"label\": \"Orders\",\n          \"capability_label\": \"Import Orders\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"products\",\n          \"label\": \"Products\",\n          \"capability_label\": \"Import Products\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ],\n      \"outbound\": [\n        {\n          \"entity\": \"tracking\",\n          \"label\": \"Tracking\",\n          \"capability_label\": \"Submit Tracking\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"inventory\",\n          \"label\": \"Inventory\",\n          \"capability_label\": \"Push Inventory\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"pricing\",\n          \"label\": \"Pricing\",\n          \"capability_label\": \"Push Pricing\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ]\n    },\n    \"is_sync_schedule_paused\": true\n  }\n}"}]},{"name":"Resume Sync Schedule","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls/resume","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls","resume"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]},"description":"Resume the integration instance's automatic sync schedule. Sets `schedule_state` to `active`, re-enabling scheduled sync and flipping the derived `is_automatic_sync_enabled` flag back to true. Per-capability toggles set before pausing are restored unchanged.\n\n**Required scope: `integrations:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token + `integrations.update` permission.\n\nNo request body. Returns the updated integration instance object.\n\n**Deprecation note:** `is_automatic_sync_enabled` is a legacy coarse flag kept as a derived mirror of the sync-controls schedule state (`sync_controls.scheduleState`). New consumers should read `is_sync_schedule_paused` for the schedule and `sync_controls` for per-capability state; the legacy field is slated for rename to `sync_schedule_active`."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/integration-instances/{integration_instance}/sync-controls/resume","host":["{{baseUrl}}"],"path":["api","integration-instances",":integration_instance","sync-controls","resume"],"variable":[{"key":"integration_instance","value":"12","description":"Integration instance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 12,\n    \"integration_id\": 3,\n    \"name\": \"My Shopify Store\",\n    \"connection_status\": \"connected\",\n    \"is_automatic_sync_enabled\": true,\n    \"sync_status\": \"active\",\n    \"sync_controls\": {\n      \"schedule_state\": \"active\",\n      \"capabilities\": {\n        \"inbound\": {\n          \"orders\": true,\n          \"products\": true\n        },\n        \"outbound\": {\n          \"tracking\": true,\n          \"inventory\": true,\n          \"pricing\": false\n        }\n      },\n      \"source_of_truth\": {\n        \"inventory\": \"sku\",\n        \"pricing\": \"channel\"\n      }\n    },\n    \"applicable_sync_capabilities\": {\n      \"inbound\": [\n        {\n          \"entity\": \"orders\",\n          \"label\": \"Orders\",\n          \"capability_label\": \"Import Orders\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"products\",\n          \"label\": \"Products\",\n          \"capability_label\": \"Import Products\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ],\n      \"outbound\": [\n        {\n          \"entity\": \"tracking\",\n          \"label\": \"Tracking\",\n          \"capability_label\": \"Submit Tracking\",\n          \"is_bidirectional\": false,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"inventory\",\n          \"label\": \"Inventory\",\n          \"capability_label\": \"Push Inventory\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        },\n        {\n          \"entity\": \"pricing\",\n          \"label\": \"Pricing\",\n          \"capability_label\": \"Push Pricing\",\n          \"is_bidirectional\": true,\n          \"environment_blocked\": false,\n          \"environment_blocked_reason\": null\n        }\n      ]\n    },\n    \"is_sync_schedule_paused\": false\n  }\n}"}]},{"name":"List Instances","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances"]},"description":"List every Magento 2 IntegrationInstance in your tenant. Returns the same shape as `Show` but as a collection. Sorted by instance name ascending. No pagination at Phase 1 — most tenants have a handful of instances."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"integration_id\": 17,\n      \"name\": \"Acme — EU Storefront\",\n      \"country\": \"DE\",\n      \"sync_status\": null,\n      \"connection_status\": null,\n      \"is_automatic_sync_enabled\": false,\n      \"connection_settings\": {\n        \"base_url\": \"https://shop-eu.example.com\",\n        \"access_token_masked\": \"••••••••••••••••••••wxyz\"\n      },\n      \"integration_settings\": {\n        \"orders\": {\n          \"download\": {\n            \"auto_download\": {\n              \"enabled\": false,\n              \"frequency_mins\": 15\n            }\n          }\n        },\n        \"inventory\": {\n          \"master_of_stock\": null\n        }\n      },\n      \"created_at\": \"2026-06-10T12:34:56+00:00\",\n      \"updated_at\": \"2026-06-10T12:34:56+00:00\"\n    },\n    {\n      \"id\": 43,\n      \"integration_id\": 17,\n      \"name\": \"Acme — US Storefront\",\n      \"country\": \"US\",\n      \"sync_status\": null,\n      \"connection_status\": null,\n      \"is_automatic_sync_enabled\": false,\n      \"connection_settings\": {\n        \"base_url\": \"https://shop.example.com\",\n        \"access_token_masked\": \"••••••••••••••••••••abcd\"\n      },\n      \"integration_settings\": {\n        \"orders\": {\n          \"download\": {\n            \"auto_download\": {\n              \"enabled\": false,\n              \"frequency_mins\": 15\n            }\n          }\n        },\n        \"inventory\": {\n          \"master_of_stock\": null\n        }\n      },\n      \"created_at\": \"2026-06-10T12:34:56+00:00\",\n      \"updated_at\": \"2026-06-10T12:34:56+00:00\"\n    }\n  ]\n}"}]},{"name":"Get Instance","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Retrieve a single Magento 2 IntegrationInstance by ID. The route is scoped to this tenant's Magento 2 instances; IDs that belong to other integration types or other tenants return `404`."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_id\": 17,\n    \"name\": \"Acme — US Storefront\",\n    \"country\": \"US\",\n    \"sync_status\": null,\n    \"connection_status\": null,\n    \"is_automatic_sync_enabled\": false,\n    \"connection_settings\": {\n      \"base_url\": \"https://shop.example.com\",\n      \"access_token_masked\": \"••••••••••••••••••••abcd\",\n      \"admin_path\": \"admin_gmr1iop\"\n    },\n    \"integration_settings\": {\n      \"orders\": {\n        \"download\": {\n          \"last_updated_after\": null,\n          \"status\": [],\n          \"auto_download\": {\n            \"enabled\": false,\n            \"frequency_mins\": 15\n          }\n        }\n      },\n      \"inventory\": {\n        \"master_of_stock\": null\n      },\n      \"communications\": {\n        \"email_customers\": true\n      }\n    },\n    \"created_at\": \"2026-06-10T12:34:56+00:00\",\n    \"updated_at\": \"2026-06-10T12:34:56+00:00\"\n  }\n}"}]},{"name":"Update Instance","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Partial update — every field is `sometimes`. `connection_settings` and `integration_settings` are deep-merged with the existing values, so rotating just the access_token does NOT wipe the base_url. Top-level scalars like `name`, `country`, and `is_automatic_sync_enabled` overwrite directly.\n\n**Body parameters (all optional):**\n- `name` (string, max 255)\n- `country` (string, 2 chars — nullable)\n- `connection_settings.base_url` (URL)\n- `connection_settings.access_token` (string, min 8 chars, max 255) — merchant-rotated tokens land here.\n- `connection_settings.admin_path` (string, max 120, regex `^[A-Za-z0-9_\\-/]+$`, nullable) — Magento admin URL frontname (e.g. `admin_gmr1iop`). Used to build deep-links into the Magento admin panel; defaults to `admin` server-side when null/blank. Magento installs typically randomise this in `app/etc/env.php` → `backend.frontName` for security.\n- `integration_settings` (object) — merged into existing settings.\n- `is_automatic_sync_enabled` (boolean)\n\n**Payment-pending order policy** (`integration_settings.orders.payment_pending`) — controls how orders that arrive from Magento 2 unpaid are imported:\n- `integration_settings.orders.payment_pending.enabled` (boolean) — turn the policy on/off. When off, unpaid orders import normally.\n- `integration_settings.orders.payment_pending.disposition` (string: `open`, `draft`, `reserve`) — what happens to an unpaid order: `open` imports it normally (no hold), `draft` imports it without allocating stock until approved, `reserve` allocates stock and holds fulfillment until payment arrives.\n- `integration_settings.orders.payment_pending.reserve_expiry_days` (integer 1-90, nullable) — for the `reserve` disposition, how many days the stock reservation is held before it auto-releases if payment never arrives; null means the reservation does not expire.\n- `integration_settings.orders.payment_pending.auto_open_on_payment` (boolean) — automatically open a held order as soon as its payment is confirmed.\n- Per-payment-method overrides are available via the Payment Method Mappings endpoints (`unpaid_disposition`).\n\n**Accounting sync trigger** (`integration_settings.accounting.sales_order_sync_trigger`, string: `always` or `when_paid`, nullable) — when this store's sales orders are pushed to the connected accounting provider: `always` (default — the invoice is pushed once the order is confirmed) or `when_paid` (unpaid orders stay out of the ledger until payment arrives). Per-payment-method overrides are available via the Payment Method Mappings endpoints (`accounting_sync`).\n\nDoes not re-probe Magento — use the test-connection endpoint first if the merchant changed `base_url` or `access_token`.","body":{"mode":"raw","raw":"{\n  \"name\": \"Acme — US Storefront (renamed)\",\n  \"connection_settings\": {\n    \"access_token\": \"magento_integration_access_token_rotated_yyyyyyyy\",\n    \"admin_path\": \"admin_gmr1iop\"\n  },\n  \"integration_settings\": {\n    \"orders\": {\n      \"download\": {\n        \"auto_download\": {\n          \"enabled\": true,\n          \"frequency_mins\": 15\n        }\n      },\n      \"payment_pending\": {\n        \"enabled\": true,\n        \"disposition\": \"reserve\",\n        \"reserve_expiry_days\": 14,\n        \"auto_open_on_payment\": true\n      }\n    },\n    \"accounting\": {\n      \"sales_order_sync_trigger\": \"when_paid\"\n    }\n  },\n  \"is_automatic_sync_enabled\": true\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PATCH","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"integration_id\": 17,\n    \"name\": \"Acme — US Storefront (renamed)\",\n    \"country\": \"US\",\n    \"sync_status\": null,\n    \"connection_status\": null,\n    \"is_automatic_sync_enabled\": true,\n    \"connection_settings\": {\n      \"base_url\": \"https://shop.example.com\",\n      \"access_token_masked\": \"••••••••••••••••••••yyyy\"\n    },\n    \"integration_settings\": {\n      \"orders\": {\n        \"download\": {\n          \"last_updated_after\": null,\n          \"status\": [],\n          \"auto_download\": {\n            \"enabled\": true,\n            \"frequency_mins\": 15\n          }\n        }\n      },\n      \"inventory\": {\n        \"master_of_stock\": null\n      },\n      \"communications\": {\n        \"email_customers\": true\n      }\n    },\n    \"created_at\": \"2026-06-10T12:34:56+00:00\",\n    \"updated_at\": \"2026-06-10T13:21:00+00:00\"\n  }\n}"}]},{"name":"Delete Instance","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Permanently delete the IntegrationInstance and its linked SalesChannel, data-import mapping, and API logs. Subsequent phases will extend this to also clean up Magento2Order / Magento2Product rows.\n\nThis is irreversible — the merchant has to reconnect via `POST /install` to resume sync.\n\nReturns `204 No Content` on success."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]}]},{"name":"Data Imports","item":[{"name":"Upload Data Import","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/data-imports","host":["{{baseUrl}}"],"path":["api","v2","data-imports"]},"description":"Uploads mapped CSV data for import and kicks off background validation. Returns the data import ID and a tracked job log ID to poll for validation progress.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPer-entity authorization: For the gated entity types (customers, warehouses, suppliers, sales_reps, categories) the user must hold the matching `<entity>.import` permission (e.g. customers.import). Other entity types are not gated here. The check resolves through the granular_permissions feature flag — it is a no-op while that flag is off. Returns 403 when the user lacks the required permission.\n\nRequest Body:\n- entity_type (required, string): Type of entity being imported (e.g. products, customers, warehouses, suppliers, sales_reps)\n- file_name (required, string, max:255): Original filename for display\n- column_mapping (required, array): Maps column positions to field names\n- mapped_rows (required, array, min:1): Array of row objects with mapped field values\n- metadata (nullable, array): Optional metadata","body":{"mode":"raw","raw":"{\n  \"entity_type\": \"products\",\n  \"file_name\": \"products-import.csv\",\n  \"column_mapping\": {\n    \"A\": \"sku\",\n    \"B\": \"name\",\n    \"C\": \"cost\"\n  },\n  \"mapped_rows\": [\n    {\n      \"sku\": \"PROD-001\",\n      \"name\": \"Product One\",\n      \"cost\": \"9.99\"\n    },\n    {\n      \"sku\": \"PROD-002\",\n      \"name\": \"Product Two\",\n      \"cost\": \"14.99\"\n    }\n  ],\n  \"metadata\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/data-imports","host":["{{baseUrl}}"],"path":["api","v2","data-imports"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"tracked_job_log_id\": 88\n  },\n  \"message\": \"Import uploaded and validation started.\"\n}"}]},{"name":"Get Data Import Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/summary","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","summary"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]},"description":"Returns the summary for a data import including status, row counts, and validation/import summaries.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/summary","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","summary"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"status\": \"validated\",\n    \"file_name\": \"products-import.csv\",\n    \"total_rows\": 100,\n    \"validation_summary\": {\n      \"valid_rows\": 98,\n      \"invalid_rows\": 2,\n      \"errors\": [\n        \"Row 5: SKU is required\",\n        \"Row 12: Cost must be numeric\"\n      ]\n    },\n    \"import_summary\": null\n  }\n}"}]},{"name":"Get Validation Results","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/validation-results?per_page=50&page=1","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","validation-results"],"query":[{"key":"per_page","value":"50","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]},"description":"Returns paginated validation results for a data import. Optionally filter by result type.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nQuery Parameters:\n- filter: Filter by result type (errors, warnings, valid)\n- per_page: Results per page (default 50)\n- page: Page number"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/validation-results?per_page=50&page=1","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","validation-results"],"query":[{"key":"per_page","value":"50","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"row\": 5,\n      \"status\": \"error\",\n      \"errors\": [\n        \"SKU is required\"\n      ],\n      \"data\": {\n        \"name\": \"Missing SKU Product\",\n        \"cost\": \"9.99\"\n      }\n    },\n    {\n      \"row\": 1,\n      \"status\": \"valid\",\n      \"errors\": [],\n      \"data\": {\n        \"sku\": \"PROD-001\",\n        \"name\": \"Product One\",\n        \"cost\": \"9.99\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 50,\n  \"total\": 100\n}"}]},{"name":"Execute Data Import","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/execute","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","execute"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]},"description":"Executes a validated data import. Kicks off the background import job and returns a tracked job log ID to monitor progress.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\nPer-entity authorization: For the gated entity types (customers, warehouses, suppliers, sales_reps, categories) the user must hold the matching `<entity>.import` permission for the import's entity_type. Returns 403 when the user lacks the required permission. The check resolves through the granular_permissions feature flag — it is a no-op while that flag is off."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/execute","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","execute"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"tracked_job_log_id\": 92\n  },\n  \"message\": \"Import execution started.\"\n}"}]},{"name":"Get Import Results","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/import-results","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","import-results"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]},"description":"Returns the import results after execution has completed.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/data-imports/{dataImport}/import-results","host":["{{baseUrl}}"],"path":["api","v2","data-imports",":dataImport","import-results"],"variable":[{"key":"dataImport","value":"5","description":"Data Import ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"created\": 96,\n    \"updated\": 2,\n    \"failed\": 2,\n    \"errors\": [\n      {\n        \"row\": 5,\n        \"error\": \"SKU is required\"\n      },\n      {\n        \"row\": 12,\n        \"error\": \"Cost must be numeric\"\n      }\n    ]\n  }\n}"}]},{"name":"Download Import Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-imports/template?entity_type=contacts","host":["{{baseUrl}}"],"path":["api","v2","data-imports","template"],"query":[{"key":"entity_type","value":"contacts","description":"Registered import type (e.g. `suppliers`, `customers`, `warehouses`, `contacts`).","disabled":true}]},"description":"Download an XLSX import template for the given import type: the field labels as headers plus a sample data row where available. Headers match the import wizard's field labels exactly, so an exported template maps automatically."}}]},{"name":"Settings","item":[{"name":"List Settings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/settings","host":["{{baseUrl}}"],"path":["api","v2","settings"]},"description":"Returns all application settings.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/settings","host":["{{baseUrl}}"],"path":["api","v2","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"slug\": \"default_warehouse_id\",\n      \"value\": \"2\",\n      \"label\": \"Default Warehouse\"\n    },\n    {\n      \"slug\": \"currency\",\n      \"value\": \"USD\",\n      \"label\": \"Currency\"\n    },\n    {\n      \"slug\": \"timezone\",\n      \"value\": \"America/New_York\",\n      \"label\": \"Timezone\"\n    }\n  ]\n}"}]},{"name":"Bulk Update Settings","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/settings","host":["{{baseUrl}}"],"path":["api","v2","settings"]},"description":"Updates multiple settings at once.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `settings.update`","body":{"mode":"raw","raw":"{\n  \"settings\": [\n    {\n      \"slug\": \"default_warehouse_id\",\n      \"value\": \"3\"\n    },\n    {\n      \"slug\": \"timezone\",\n      \"value\": \"America/Los_Angeles\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/settings","host":["{{baseUrl}}"],"path":["api","v2","settings"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"slug\": \"default_warehouse_id\",\n      \"value\": \"3\"\n    },\n    {\n      \"slug\": \"timezone\",\n      \"value\": \"America/Los_Angeles\"\n    }\n  ],\n  \"message\": \"Settings updated successfully.\"\n}"}]},{"name":"Show Setting","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/settings/{slug}","host":["{{baseUrl}}"],"path":["api","v2","settings",":slug"],"variable":[{"key":"slug","value":"default_warehouse_id","description":"Setting slug"}]},"description":"Returns a single settings group by slug as a flat JSON object of its fields.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\n**Slug `general`** includes (among others):\n- `connectivity_alert_sound_enabled` (boolean, default `false`) — play a repeating audio alert on the device when the app loses connection to the server, and a confirmation tone when restored.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/settings/{slug}","host":["{{baseUrl}}"],"path":["api","v2","settings",":slug"],"variable":[{"key":"slug","value":"default_warehouse_id","description":"Setting slug"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"slug\": \"default_warehouse_id\",\n    \"value\": \"2\",\n    \"label\": \"Default Warehouse\"\n  }\n}"}]},{"name":"Update Setting","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/settings/{slug}","host":["{{baseUrl}}"],"path":["api","v2","settings",":slug"],"variable":[{"key":"slug","value":"default_warehouse_id","description":"Setting slug"}]},"description":"Updates a single setting by slug. Body shape varies per slug — for simple settings the body is `{\"value\": ...}`; for grouped settings (e.g. `purchase-order`, `forecasting`, `general`) the body is a flat object of allowed keys.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\n**Slug `purchase-order`** accepts:\n- `cc_outgoing_email` (string|null, max 500) — comma-separated CC list applied to outgoing PO emails.\n\n**Slug `general`** accepts (validated keys):\n- `connectivity_alert_sound_enabled` (boolean) — play a repeating audio alert on the device when the app loses connection to the server, and a confirmation tone when restored. Non-boolean values are rejected with 422.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `settings.update`","body":{"mode":"raw","raw":"{\n  \"value\": \"3\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/settings/{slug}","host":["{{baseUrl}}"],"path":["api","v2","settings",":slug"],"variable":[{"key":"slug","value":"default_warehouse_id","description":"Setting slug"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"slug\": \"default_warehouse_id\",\n    \"value\": \"3\",\n    \"label\": \"Default Warehouse\"\n  }\n}"}]}]},{"name":"Tracked Job Logs","item":[{"name":"List Tracked Job Logs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]},"description":"Returns a paginated list of tracked job logs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs?per_page=10&page=1","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs"],"query":[{"key":"per_page","value":"10","description":"Results per page (default 10).","disabled":true},{"key":"page","value":"1","description":"Page number (default 1).","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 88,\n      \"job_name\": \"Import Products: products.csv\",\n      \"status\": \"completed\",\n      \"progress\": 100,\n      \"total\": 100,\n      \"results\": {\n        \"created\": 96,\n        \"updated\": 2,\n        \"failed\": 2\n      },\n      \"created_at\": \"2024-03-20T10:00:00.000000Z\",\n      \"updated_at\": \"2024-03-20T10:05:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 10,\n  \"total\": 42\n}"}]},{"name":"List Active Tracked Job Logs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/active","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs","active"]},"description":"Returns all currently active (running or pending) tracked job logs. Used by the tracked job log endpoints to poll for running jobs.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/active","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs","active"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 92,\n      \"job_name\": \"Sync Shopify Orders: My Store\",\n      \"status\": \"processing\",\n      \"progress\": 45,\n      \"total\": 200,\n      \"results\": null,\n      \"created_at\": \"2024-03-20T10:10:00.000000Z\",\n      \"updated_at\": \"2024-03-20T10:10:30.000000Z\"\n    }\n  ]\n}"}]},{"name":"Cancel Tracked Job","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/{trackedJobLog}/cancel","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs",":trackedJobLog","cancel"],"variable":[{"key":"trackedJobLog","value":"92","description":"Tracked Job Log ID"}]},"description":"Requests cancellation of a running tracked job. The job will stop at the next cancellation checkpoint.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/{trackedJobLog}/cancel","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs",":trackedJobLog","cancel"],"variable":[{"key":"trackedJobLog","value":"92","description":"Tracked Job Log ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Job cancellation requested.\",\n  \"data\": {\n    \"id\": 92,\n    \"status\": \"cancelling\"\n  }\n}"}]},{"name":"Retry Tracked Job","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/{trackedJobLog}/retry","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs",":trackedJobLog","retry"],"variable":[{"key":"trackedJobLog","value":"88","description":"Tracked Job Log ID"}]},"description":"Retries a failed tracked job.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/tracked-job-logs/{trackedJobLog}/retry","host":["{{baseUrl}}"],"path":["api","v2","tracked-job-logs",":trackedJobLog","retry"],"variable":[{"key":"trackedJobLog","value":"88","description":"Tracked Job Log ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Job queued for retry.\",\n  \"data\": {\n    \"id\": 95,\n    \"status\": \"pending\"\n  }\n}"}]}]},{"name":"Reference Data (Read-Only)","item":[{"name":"List Attribute Groups","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/attribute-groups","host":["{{baseUrl}}"],"path":["api","v2","attribute-groups"]},"description":"Returns all attribute groups.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/attribute-groups","host":["{{baseUrl}}"],"path":["api","v2","attribute-groups"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Physical Attributes\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Attributes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/attributes","host":["{{baseUrl}}"],"path":["api","v2","attributes"]},"description":"Returns all product attributes.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/attributes","host":["{{baseUrl}}"],"path":["api","v2","attributes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Color\",\n      \"attribute_group_id\": 1,\n      \"type\": \"text\"\n    }\n  ]\n}"}]},{"name":"List Brands","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/brands","host":["{{baseUrl}}"],"path":["api","v2","brands"]},"description":"Returns all product brands.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/brands","host":["{{baseUrl}}"],"path":["api","v2","brands"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My Brand\",\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"List Categories","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/categories","host":["{{baseUrl}}"],"path":["api","v2","categories"]},"description":"Returns all product categories.\n\n**Required scope: `products:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/categories","host":["{{baseUrl}}"],"path":["api","v2","categories"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"parent_id\": null\n    }\n  ]\n}"}]},{"name":"List CSV Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/csv-templates","host":["{{baseUrl}}"],"path":["api","v2","csv-templates"]},"description":"Returns all CSV import/export templates.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/csv-templates","host":["{{baseUrl}}"],"path":["api","v2","csv-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Product Import Template\",\n      \"entity_type\": \"products\"\n    }\n  ]\n}"}]},{"name":"List Data Feeds","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/data-feeds","host":["{{baseUrl}}"],"path":["api","v2","data-feeds"]},"description":"Returns all data feeds.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/data-feeds","host":["{{baseUrl}}"],"path":["api","v2","data-feeds"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Daily Inventory Feed\",\n      \"type\": \"inventory\"\n    }\n  ]\n}"}]},{"name":"List Financial Alerts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financial-alerts","host":["{{baseUrl}}"],"path":["api","v2","financial-alerts"]},"description":"Returns all financial alerts.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financial-alerts","host":["{{baseUrl}}"],"path":["api","v2","financial-alerts"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Negative Margin Alert\",\n      \"type\": \"margin\",\n      \"threshold\": \"0\"\n    }\n  ]\n}"}]},{"name":"List Financial Line Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/financial-line-types","host":["{{baseUrl}}"],"path":["api","v2","financial-line-types"]},"description":"Returns all financial line types.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/financial-line-types","host":["{{baseUrl}}"],"path":["api","v2","financial-line-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Revenue\",\n      \"type\": \"revenue\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"COGS\",\n      \"type\": \"cogs\"\n    }\n  ]\n}"}]},{"name":"List Incoterms","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/incoterms","host":["{{baseUrl}}"],"path":["api","v2","incoterms"]},"description":"Paginated list of incoterms.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nSearch: `filter[search]` matches id, code, name, and description.\n\nText filters accept operator suffixes: `.is`, `.is_not`, `.contains`, `.does_not_contain`, `.starts_with`, `.does_not_start_with`, `.ends_with`, `.does_not_end_with`, `.is_one_of`, `.is_not_one_of`, `.is_empty`, `.is_not_empty`. The bare `filter[column]` form is an exact match. Filterable columns: code, name, description, transport_mode, family. `filter[is_standard.is]` filters on the standard ICC rows. `filter[archived]` accepts `only` or `all` to include archived rows.\n\nAllowed sorts: id, code, name, transport_mode, family, is_standard, created_at, updated_at. Prefix with `-` for descending (default: `-id`).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/incoterms","host":["{{baseUrl}}"],"path":["api","v2","incoterms"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"code\": \"EXW\",\n      \"id\": 1,\n      \"name\": \"Ex Works\",\n      \"description\": \"Ex Works — seller makes goods available at their premises.\",\n      \"transport_mode\": \"any\",\n      \"family\": \"E\",\n      \"seller_pays_main_carriage\": true,\n      \"export_cleared_by\": \"seller\",\n      \"import_cleared_by\": \"buyer\",\n      \"seller_insurance\": \"none\",\n      \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n      \"is_standard\": true,\n      \"is_deprecated\": false,\n      \"created_at\": \"2026-07-13T10:30:00.000000Z\",\n      \"updated_at\": \"2026-07-13T10:30:00.000000Z\",\n      \"archived_at\": null,\n      \"sort_order\": 1\n    },\n    {\n      \"code\": \"FOB\",\n      \"id\": 2,\n      \"name\": \"Free On Board\",\n      \"description\": \"Free On Board — risk passes when goods are on board the vessel.\",\n      \"transport_mode\": \"any\",\n      \"family\": \"F\",\n      \"seller_pays_main_carriage\": true,\n      \"export_cleared_by\": \"seller\",\n      \"import_cleared_by\": \"buyer\",\n      \"seller_insurance\": \"none\",\n      \"risk_transfer_point\": \"At the named place of destination, when goods are ready for unloading.\",\n      \"is_standard\": true,\n      \"is_deprecated\": false,\n      \"created_at\": \"2026-07-13T10:30:00.000000Z\",\n      \"updated_at\": \"2026-07-13T10:30:00.000000Z\",\n      \"archived_at\": null,\n      \"sort_order\": 2\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 2,\n  \"per_page\": 10,\n  \"total\": 12,\n  \"from\": 1,\n  \"to\": 10\n}"}]},{"name":"List Nominal Codes","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/nominal-codes","host":["{{baseUrl}}"],"path":["api","v2","nominal-codes"]},"description":"Returns all nominal codes (accounting chart of accounts codes).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/nominal-codes","host":["{{baseUrl}}"],"path":["api","v2","nominal-codes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"code\": \"4000\",\n      \"name\": \"Sales Revenue\"\n    },\n    {\n      \"id\": 2,\n      \"code\": \"5000\",\n      \"name\": \"Cost of Goods Sold\"\n    }\n  ]\n}"}]},{"name":"List Payment Terms","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/payment-terms","host":["{{baseUrl}}"],"path":["api","v2","payment-terms"]},"description":"Returns all payment terms.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/payment-terms","host":["{{baseUrl}}"],"path":["api","v2","payment-terms"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Net 30\",\n      \"days\": 30\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Net 60\",\n      \"days\": 60\n    }\n  ]\n}"}]},{"name":"List Payment Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/payment-types","host":["{{baseUrl}}"],"path":["api","v2","payment-types"]},"description":"Returns all payment types.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/payment-types","host":["{{baseUrl}}"],"path":["api","v2","payment-types"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Credit Card\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Bank Transfer\"\n    }\n  ]\n}"}]},{"name":"List Product Pricing Tiers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","v2","product-pricing-tiers"]},"description":"Returns all product pricing tiers.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/product-pricing-tiers","host":["{{baseUrl}}"],"path":["api","v2","product-pricing-tiers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Wholesale\",\n      \"discount_percent\": \"20.00\"\n    }\n  ]\n}"}]},{"name":"List Shipping Methods","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/shipping-methods","host":["{{baseUrl}}"],"path":["api","v2","shipping-methods"]},"description":"Returns all shipping methods.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/shipping-methods","host":["{{baseUrl}}"],"path":["api","v2","shipping-methods"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard Ground\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Express 2-Day\"\n    }\n  ]\n}"}]},{"name":"List Stores","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/stores","host":["{{baseUrl}}"],"path":["api","v2","stores"]},"description":"Returns all stores (sales channel store integrations).\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/stores","host":["{{baseUrl}}"],"path":["api","v2","stores"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"My Shopify Store\",\n      \"platform\": \"shopify\"\n    }\n  ]\n}"}]},{"name":"List Supplier Pricing Tiers","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","v2","supplier-pricing-tiers"]},"description":"Returns all supplier pricing tiers.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/supplier-pricing-tiers","host":["{{baseUrl}}"],"path":["api","v2","supplier-pricing-tiers"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Preferred\",\n      \"discount_percent\": \"10.00\"\n    }\n  ]\n}"}]},{"name":"List Tags","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tags","host":["{{baseUrl}}"],"path":["api","v2","tags"]},"description":"Returns all tags.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/tags","host":["{{baseUrl}}"],"path":["api","v2","tags"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Bestseller\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Seasonal\"\n    }\n  ]\n}"}]},{"name":"List Tax Rates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/tax-rates","host":["{{baseUrl}}"],"path":["api","v2","tax-rates"]},"description":"Returns all tax rates.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/tax-rates","host":["{{baseUrl}}"],"path":["api","v2","tax-rates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Standard Rate\",\n      \"rate\": \"20.00\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Zero Rate\",\n      \"rate\": \"0.00\"\n    }\n  ]\n}"}]},{"name":"List Users","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/users","host":["{{baseUrl}}"],"path":["api","v2","users"]},"description":"Returns a paginated list of users for the current tenant, with Spatie QueryBuilder filtering and sorting. Includes soft-deleted users.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nTenant scoping: Results are restricted to users who are members of the current tenant. The `users` table lives on the central connection and is shared across all tenants, so without scoping every tenant's settings UI would see every user in the entire installation.\n\nAuthentication: Requires Bearer token.\n\nResponse notes: Each user includes `roles` (the user's assigned roles with id, name, description, guard_name) and `permissions` (a flattened, de-duplicated list of permission names across all assigned roles) — both are always present since the endpoint eager-loads roles with their permissions. `features.granular_permissions` reflects the per-tenant feature flag; frontends treat anything other than `true` as OFF."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/users","host":["{{baseUrl}}"],"path":["api","v2","users"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"John Smith\",\n      \"email\": \"john@example.com\",\n      \"email_verified_at\": \"2025-01-15T10:00:00.000000Z\",\n      \"activated_at\": \"2025-01-15T10:00:00.000000Z\",\n      \"created_at\": \"2025-01-10T09:30:00.000000Z\",\n      \"updated_at\": \"2025-06-01T14:22:00.000000Z\",\n      \"deleted_at\": null,\n      \"is_admin\": true,\n      \"is_power_user\": false,\n      \"is_super_admin\": false,\n      \"features\": {\n        \"granular_permissions\": false\n      },\n      \"role\": \"Admin\",\n      \"roles\": [\n        {\n          \"id\": 1,\n          \"name\": \"admin\",\n          \"description\": \"Full access to all features and settings.\",\n          \"guard_name\": \"sanctum\"\n        }\n      ],\n      \"permissions\": [\n        \"users.index\",\n        \"users.create\",\n        \"users.update\",\n        \"roles.index\",\n        \"sales_orders.index\"\n      ]\n    }\n  ],\n  \"current_page\": 1,\n  \"first_page_url\": \"https://sku2.test/api/v2/users?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://sku2.test/api/v2/users?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://sku2.test/api/v2/users\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Incoterm","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","v2","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"4","description":"Incoterm id"}]},"description":"Returns a single incoterm for its detail page, including archived rows.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/incoterms/{incoterm}","host":["{{baseUrl}}"],"path":["api","v2","incoterms",":incoterm"],"variable":[{"key":"incoterm","value":"4","description":"Incoterm id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"code\": \"FOB\",\n    \"id\": 4,\n    \"name\": \"Free On Board\",\n    \"description\": \"Sea and inland-waterway transport only. The seller clears the goods for export and loads them onto the vessel; risk passes once they are on board.\",\n    \"transport_mode\": \"sea_inland\",\n    \"family\": \"F\",\n    \"seller_pays_main_carriage\": false,\n    \"export_cleared_by\": \"seller\",\n    \"import_cleared_by\": \"buyer\",\n    \"seller_insurance\": \"none\",\n    \"risk_transfer_point\": \"Goods on board the vessel at the named port of shipment.\",\n    \"is_standard\": true,\n    \"is_deprecated\": false,\n    \"sort_order\": 4,\n    \"created_at\": \"2026-07-15T06:16:45.000000Z\",\n    \"updated_at\": \"2026-07-15T06:16:45.000000Z\",\n    \"archived_at\": null\n  }\n}"}]},{"name":"Get Incoterm Activity Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/incoterms/{incoterm}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","incoterms",":incoterm","activity-log"],"variable":[{"key":"incoterm","value":"4","description":"Incoterm id"}]},"description":"Paginated activity history for an incoterm. Surfaces two signals: the term's own events (create, edit, archive, restore) and document assignment changes — a purchase or sales order whose incoterm was set to or cleared from this term.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/incoterms/{incoterm}/activity-log","host":["{{baseUrl}}"],"path":["api","v2","incoterms",":incoterm","activity-log"],"variable":[{"key":"incoterm","value":"4","description":"Incoterm id"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"description\": \"updated\",\n      \"event\": \"updated\",\n      \"subject_type\": \"Incoterm\",\n      \"subject_id\": 4,\n      \"properties\": {\n        \"attributes\": {\n          \"sort_order\": 44\n        },\n        \"old\": {\n          \"sort_order\": 4\n        }\n      },\n      \"causer_name\": \"Administrator\",\n      \"created_at\": \"2026-07-15T23:32:35.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Export Incoterms","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/incoterms/export","host":["{{baseUrl}}"],"path":["api","v2","incoterms","export"]},"description":"Downloads the incoterms reference table as a spreadsheet. Columns: code, name, description, transport mode, family, seller pays main carriage, export cleared by, import cleared by, seller insurance, risk transfer point, standard, deprecated.\n\nResponse is a file download (`text/csv` or the XLSX mime type), not JSON. Honors the current `filter[search]` / `filter[archived]` query params.\n\n`format` must be `csv` or `xlsx` — any other value returns a 422 validation error.\n\nAuthentication: Requires Bearer token."}}]},{"name":"Dashboard","item":[{"name":"Operational KPIs","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/dashboard/operational-kpis","host":["{{baseUrl}}"],"path":["api","v2","dashboard","operational-kpis"]},"description":"Returns operational KPI metrics for the dashboard.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/dashboard/operational-kpis","host":["{{baseUrl}}"],"path":["api","v2","dashboard","operational-kpis"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"open_sales_orders\": 42,\n    \"pending_fulfillments\": 15,\n    \"low_stock_products\": 8,\n    \"open_purchase_orders\": 6,\n    \"pending_receipts\": 3\n  }\n}"}]},{"name":"Dashboard Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/dashboard/summary","host":["{{baseUrl}}"],"path":["api","v2","dashboard","summary"]},"description":"Returns aggregated summary data for the dashboard.\n\n**Not yet available to API tokens**\nThis endpoint currently requires session authentication; Personal Access Token scope support is in progress.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/dashboard/summary","host":["{{baseUrl}}"],"path":["api","v2","dashboard","summary"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"revenue_30d\": \"125430.00\",\n    \"orders_30d\": 312,\n    \"units_sold_30d\": 1847,\n    \"inventory_value\": \"284500.00\"\n  }\n}"}]},{"name":"Get Instance Dashboard","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/dashboard","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","dashboard"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]},"description":"Dashboard metrics for a single Magento 2 integration instance. Backs the shared `<SalesChannelInstanceDashboard>` component on `/v2/integrations/magento2/dashboard`.\n\nReturns a hybrid payload: snake_case fields kept for legacy `Magento2DashboardMetrics` fallbacks, plus the camelCase `SalesChannelInstanceDashboardData` contract (`syncCards`, `integrations`, `entityCounts`, `financialSummary`, `syncStatus`) consumed directly by the dashboard component.\n\n**Path params:**\n- `magento2IntegrationInstance` (required, integer) — Magento 2 IntegrationInstance ID.\n\n**Query params:**\n- `period` (optional, string, default `30d`) — reporting window for `financialSummary` / `revenue_30d`. One of: `today`, `7d`, `30d`, `90d`, `All`.\n\n**Error responses:**\n- `404` — instance ID does not exist in this tenant.\n- `422` — `period` is not one of the allowed values.\n- `401` — caller is not authenticated."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/magento2/integration-instances/{magento2IntegrationInstance}/dashboard","host":["{{baseUrl}}"],"path":["api","magento2","integration-instances",":magento2IntegrationInstance","dashboard"],"variable":[{"key":"magento2IntegrationInstance","value":"42","description":"Internal IntegrationInstance ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"orders_total\": 128,\n    \"orders_unmapped\": 4,\n    \"orders_synced_today\": 6,\n    \"products_total\": 412,\n    \"products_mapped\": 380,\n    \"products_unmapped\": 32,\n    \"customers_total\": 95,\n    \"revenue_30d\": 18432.55,\n    \"currency\": \"USD\",\n    \"last_sync_at\": \"2026-06-16T05:32:11+00:00\",\n    \"last_sync_status\": \"success\",\n    \"generatedAt\": \"2026-06-16T07:00:00+00:00\",\n    \"channelName\": \"Magento 2\",\n    \"displayName\": \"Acme — US Storefront\",\n    \"urlColumnLabel\": \"Base URL\",\n    \"syncCards\": {\n      \"orders\": {\n        \"label\": \"Orders\",\n        \"icon\": \"mdi-cart\",\n        \"lastSyncHuman\": \"1 day ago\",\n        \"lastSyncDate\": \"2026-06-15T07:00:00+00:00\",\n        \"isStale\": false,\n        \"lastDataHuman\": \"5 months ago\",\n        \"latestItemLabel\": \"#100000128\",\n        \"latestItemDate\": \"2026-01-12T15:00:00+00:00\"\n      },\n      \"catalog\": {\n        \"label\": \"Products\",\n        \"icon\": \"mdi-package-variant\",\n        \"lastSyncHuman\": \"2 hours ago\",\n        \"lastSyncDate\": \"2026-06-16T05:00:00+00:00\",\n        \"isStale\": false,\n        \"lastDataHuman\": \"3 days ago\",\n        \"latestItemLabel\": \"Acme Hoodie\",\n        \"latestItemDate\": \"2026-06-13T09:14:11+00:00\"\n      }\n    },\n    \"integrations\": [\n      {\n        \"id\": 42,\n        \"name\": \"Acme — US Storefront\",\n        \"url\": \"https://shop.example.com\",\n        \"isAutomaticSyncEnabled\": true,\n        \"createdAt\": \"2026-06-10T12:34:56+00:00\",\n        \"updatedAt\": \"2026-06-16T05:32:11+00:00\"\n      }\n    ],\n    \"financialSummary\": {\n      \"grossRevenue\": 18432.55,\n      \"totalRefunds\": 312.4,\n      \"netRevenue\": 18120.15,\n      \"unitsSold\": 0,\n      \"unitsRefunded\": 0,\n      \"netUnitsSold\": 0\n    },\n    \"entityCounts\": {\n      \"totalRecords\": 635,\n      \"entities\": [\n        {\n          \"displayName\": \"Orders\",\n          \"total\": 128,\n          \"error\": null\n        },\n        {\n          \"displayName\": \"Products\",\n          \"total\": 412,\n          \"error\": null\n        },\n        {\n          \"displayName\": \"Customers\",\n          \"total\": 95,\n          \"error\": null\n        }\n      ]\n    },\n    \"syncStatus\": {\n      \"overallHealth\": {\n        \"status\": \"healthy\",\n        \"healthyEntities\": 3,\n        \"totalEntities\": 3,\n        \"healthPercentage\": 100\n      },\n      \"autoSync\": {\n        \"isEnabled\": true,\n        \"statusText\": \"Auto-sync enabled (USD)\"\n      },\n      \"syncTypes\": [\n        {\n          \"name\": \"Orders\",\n          \"lastSyncHuman\": \"1 day ago\",\n          \"lastSyncDate\": \"2026-06-15T07:00:00+00:00\",\n          \"isStale\": false,\n          \"recordsSyncedLast24h\": 6,\n          \"schedule\": \"Every 5 minutes\",\n          \"nextSyncCountdown\": null\n        },\n        {\n          \"name\": \"Products\",\n          \"lastSyncHuman\": \"2 hours ago\",\n          \"lastSyncDate\": \"2026-06-16T05:00:00+00:00\",\n          \"isStale\": false,\n          \"recordsSyncedLast24h\": 3,\n          \"schedule\": \"Every hour\",\n          \"nextSyncCountdown\": null\n        },\n        {\n          \"name\": \"Customers\",\n          \"lastSyncHuman\": \"12 hours ago\",\n          \"lastSyncDate\": \"2026-06-15T19:00:00+00:00\",\n          \"isStale\": false,\n          \"recordsSyncedLast24h\": 0,\n          \"schedule\": \"Daily\",\n          \"nextSyncCountdown\": null\n        }\n      ]\n    }\n  }\n}"}]}]},{"name":"Tags","item":[{"name":"Show Tag","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single tag by ID including counts of associated products, sales orders, and purchase orders.\n\n**Required scope: `settings:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Electronics\",\n    \"num_products\": 45,\n    \"num_sales_orders\": 120,\n    \"num_purchase_orders\": 30,\n    \"num_customers\": 3,\n    \"archived_at\": null,\n    \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n    \"updated_at\": \"2024-01-10T08:00:00.000000Z\"\n  }\n}"}]},{"name":"Update Tag","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates a tag's name. Name must be unique (ignores current record).\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Renamed Category\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"Renamed Category\",\n    \"num_products\": 0,\n    \"num_sales_orders\": 0,\n    \"num_purchase_orders\": 0,\n    \"num_customers\": 0,\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T13:00:00.000000Z\"\n  },\n  \"message\": \"tag Renamed Category updated successfully\"\n}"}]},{"name":"Delete Tag","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a tag. Returns an error if the tag is still linked to any products, sales orders, or purchase orders.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tags/{id}","host":["{{baseUrl}}"],"path":["api","tags",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"tag Renamed Category deleted successfully\"\n}"}]},{"name":"List Tags","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/tags?page=1&limit=25&sort=name&search=electronics&archived=0&included[]=name&excluded[]=archived_at","host":["{{baseUrl}}"],"path":["api","tags"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"search","value":"electronics","description":"Search by tag name","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"name","description":"Columns to include in DataTable response","disabled":true},{"key":"excluded[]","value":"archived_at","description":"Columns to exclude from DataTable response","disabled":true}]},"description":"Returns a paginated list of tags with standard list query parameters. Supports search, sort, archive filtering, and column inclusion/exclusion.\n\nAuthentication: Requires Bearer token.\n\nResponse includes counts: num_products, num_sales_orders, num_purchase_orders, num_customers."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/tags?page=1&limit=25&sort=name&search=electronics&archived=0&included[]=name&excluded[]=archived_at","host":["{{baseUrl}}"],"path":["api","tags"],"query":[{"key":"page","value":"1","description":"Page number","disabled":true},{"key":"limit","value":"25","description":"Items per page","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, created_at, updated_at","disabled":true},{"key":"search","value":"electronics","description":"Search by tag name","disabled":true},{"key":"archived","value":"0","description":"0 = active only, 1 = archived only","disabled":true},{"key":"included[]","value":"name","description":"Columns to include in DataTable response","disabled":true},{"key":"excluded[]","value":"archived_at","description":"Columns to exclude from DataTable response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"num_products\": 45,\n      \"num_sales_orders\": 120,\n      \"num_purchase_orders\": 30,\n      \"num_customers\": 3,\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-10T08:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T08:00:00.000000Z\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Clearance\",\n      \"num_products\": 12,\n      \"num_sales_orders\": 35,\n      \"num_purchase_orders\": 5,\n      \"num_customers\": 1,\n      \"archived_at\": null,\n      \"created_at\": \"2024-01-11T09:00:00.000000Z\",\n      \"updated_at\": \"2024-01-11T09:00:00.000000Z\"\n    }\n  ],\n  \"per_page\": 25,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2,\n  \"last_page\": 1\n}"}]},{"name":"Create Tag","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags","host":["{{baseUrl}}"],"path":["api","tags"]},"description":"Creates a new tag.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- name (required, string, unique across tags)\n\n**Requires permission:** `tags.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"New Category\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tags","host":["{{baseUrl}}"],"path":["api","tags"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 5,\n    \"name\": \"New Category\",\n    \"num_products\": 0,\n    \"num_sales_orders\": 0,\n    \"num_purchase_orders\": 0,\n    \"num_customers\": 0,\n    \"archived_at\": null,\n    \"created_at\": \"2024-03-01T12:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T12:00:00.000000Z\"\n  },\n  \"message\": \"tag created successfully\"\n}"}]},{"name":"Bulk Delete Tags","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/tags","host":["{{baseUrl}}"],"path":["api","tags"]},"description":"Bulk deletes multiple tags by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/tags","host":["{{baseUrl}}"],"path":["api","tags"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"2 tags deleted successfully\"\n}"}]},{"name":"Archive Tag","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/tags/{id}/archive","host":["{{baseUrl}}"],"path":["api","tags",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a tag. Returns a warning if already archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tags/{id}/archive","host":["{{baseUrl}}"],"path":["api","tags",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Electronics\",\n    \"archived_at\": \"2024-03-01T15:00:00.000000Z\"\n  },\n  \"message\": \"tag Electronics archived successfully\"\n}"}]},{"name":"Unarchive Tag","request":{"method":"PUT","header":[],"url":{"raw":"{{baseUrl}}/api/tags/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","tags",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Unarchives a tag. Returns a warning if not currently archived.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tags/{id}/unarchived","host":["{{baseUrl}}"],"path":["api","tags",":id","unarchived"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Electronics\",\n    \"archived_at\": null\n  },\n  \"message\": \"tag Electronics unarchived successfully\"\n}"}]},{"name":"Bulk Archive Tags","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/archive","host":["{{baseUrl}}"],"path":["api","tags","archive"]},"description":"Bulk archives multiple tags by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tags/archive","host":["{{baseUrl}}"],"path":["api","tags","archive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 tags archived successfully\"\n}"}]},{"name":"Bulk Unarchive Tags","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/unarchive","host":["{{baseUrl}}"],"path":["api","tags","unarchive"]},"description":"Bulk unarchives multiple tags by IDs.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.archive`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    3\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/tags/unarchive","host":["{{baseUrl}}"],"path":["api","tags","unarchive"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 tags unarchived successfully\"\n}"}]},{"name":"Check Deletable","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/deletable","host":["{{baseUrl}}"],"path":["api","tags","deletable"]},"description":"Checks which tags can be safely deleted (not linked to any products, sales orders, or purchase orders).\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.delete`","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    1,\n    2,\n    5\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tags/deletable","host":["{{baseUrl}}"],"path":["api","tags","deletable"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Electronics\",\n      \"deletable\": false,\n      \"reason\": {\n        \"tags\": \"This is currently used by 45 items.\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Clearance\",\n      \"deletable\": false,\n      \"reason\": {\n        \"tags\": \"This is currently used by 12 items.\"\n      }\n    },\n    {\n      \"id\": 5,\n      \"name\": \"Unused Tag\",\n      \"deletable\": true,\n      \"reason\": null\n    }\n  ]\n}"}]},{"name":"Import Tags","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/import","host":["{{baseUrl}}"],"path":["api","tags","import"]},"description":"Imports tags in bulk from JSON data.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.import`","body":{"mode":"raw","raw":"{\n  \"data\": [\n    {\n      \"name\": \"Imported Tag 1\"\n    },\n    {\n      \"name\": \"Imported Tag 2\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tags/import","host":["{{baseUrl}}"],"path":["api","tags","import"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Tags imported successfully\"\n}"}]},{"name":"Preview Import Tags","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/tags/import/preview","host":["{{baseUrl}}"],"path":["api","tags","import","preview"]},"description":"Previews a tag import without committing changes. Returns what would be created/updated.\n\n**Required scope: `settings:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `tags.import`","body":{"mode":"raw","raw":"{\n  \"data\": [\n    {\n      \"name\": \"Preview Tag 1\"\n    },\n    {\n      \"name\": \"Preview Tag 2\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/tags/import/preview","host":["{{baseUrl}}"],"path":["api","tags","import","preview"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"name\": \"Preview Tag 1\",\n      \"action\": \"create\"\n    },\n    {\n      \"name\": \"Preview Tag 2\",\n      \"action\": \"create\"\n    }\n  ]\n}"}]}]},{"name":"Subscriptions","item":[{"name":"List Subscription Editions (Paginated)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-editions?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","subscription-editions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}]},"description":"Returns a paginated list of all subscription editions across all offerings.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-editions?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","subscription-editions"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"subscription_offering_id\": 5,\n      \"edition_name\": \"Q1 2024 Edition\",\n      \"effective_date\": \"2024-01-01\",\n      \"cutoff_date\": \"2024-03-31\",\n      \"priority\": 1,\n      \"allocated_quantity\": 100,\n      \"consumed_quantity\": 45,\n      \"remaining_quantity\": 55,\n      \"product_id\": 10,\n      \"status\": \"active\",\n      \"notes\": \"Q1 release batch\",\n      \"created_at\": \"2023-12-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"subscription_offering\": {\n        \"id\": 5,\n        \"name\": \"Premium Widget Subscription\"\n      },\n      \"product\": {\n        \"id\": 10,\n        \"name\": \"Widget Pro\",\n        \"sku\": \"WIDGET-PRO-001\"\n      }\n    }\n  ],\n  \"last_page\": 1,\n  \"per_page\": 15,\n  \"total\": 1\n}"}]},{"name":"Create Subscription Edition","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-editions","host":["{{baseUrl}}"],"path":["api","subscription-editions"]},"description":"Creates a new subscription edition.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- subscription_offering_id (required): ID of the parent subscription offering\n- edition_name (required): Name of the edition (max 255 chars)\n- effective_date (required): When this edition becomes active (YYYY-MM-DD)\n- cutoff_date (optional): Last date for this edition (must be >= effective_date)\n- priority (optional): Sort priority (integer, min 1)\n- allocated_quantity (optional): Total quantity allocated to this edition\n- product_id (required): ID of the product for this edition\n- status (optional): One of: draft, active, archived\n- notes (optional): Free-text notes","body":{"mode":"raw","raw":"{\n  \"subscription_offering_id\": 5,\n  \"edition_name\": \"Q2 2024 Edition\",\n  \"effective_date\": \"2024-04-01\",\n  \"cutoff_date\": \"2024-06-30\",\n  \"priority\": 2,\n  \"allocated_quantity\": 150,\n  \"product_id\": 10,\n  \"status\": \"draft\",\n  \"notes\": \"Q2 pre-planned batch\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-editions","host":["{{baseUrl}}"],"path":["api","subscription-editions"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Edition created successfully.\",\n  \"data\": {\n    \"id\": 2,\n    \"subscription_offering_id\": 5,\n    \"edition_name\": \"Q2 2024 Edition\",\n    \"effective_date\": \"2024-04-01\",\n    \"cutoff_date\": \"2024-06-30\",\n    \"priority\": 2,\n    \"allocated_quantity\": 150,\n    \"consumed_quantity\": 0,\n    \"remaining_quantity\": 150,\n    \"product_id\": 10,\n    \"status\": \"draft\",\n    \"notes\": \"Q2 pre-planned batch\",\n    \"created_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"updated_at\": \"2024-03-01T10:00:00.000000Z\",\n    \"subscription_offering\": {\n      \"id\": 5,\n      \"name\": \"Premium Widget Subscription\"\n    },\n    \"product\": {\n      \"id\": 10,\n      \"name\": \"Widget Pro\",\n      \"sku\": \"WIDGET-PRO-001\"\n    }\n  }\n}"}]},{"name":"Get Subscription Edition","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Returns a single subscription edition with offering and product details.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"subscription_offering_id\": 5,\n    \"edition_name\": \"Q1 2024 Edition\",\n    \"effective_date\": \"2024-01-01\",\n    \"cutoff_date\": \"2024-03-31\",\n    \"priority\": 1,\n    \"allocated_quantity\": 100,\n    \"consumed_quantity\": 45,\n    \"remaining_quantity\": 55,\n    \"product_id\": 10,\n    \"status\": \"active\",\n    \"notes\": \"Q1 release batch\",\n    \"created_at\": \"2023-12-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"subscription_offering\": {\n      \"id\": 5,\n      \"name\": \"Premium Widget Subscription\"\n    },\n    \"product\": {\n      \"id\": 10,\n      \"name\": \"Widget Pro\",\n      \"sku\": \"WIDGET-PRO-001\"\n    }\n  }\n}"}]},{"name":"Update Subscription Edition","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Updates an existing subscription edition. All fields are optional for partial updates.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields (all optional):\n- edition_name: Updated name (max 255 chars)\n- effective_date: Updated effective date\n- cutoff_date: Updated cutoff date (must be >= effective_date)\n- priority: Updated priority (integer, min 1)\n- allocated_quantity: Updated allocated quantity\n- product_id: Updated product ID\n- status: One of: draft, active, archived\n- notes: Updated notes","body":{"mode":"raw","raw":"{\n  \"edition_name\": \"Q1 2024 Edition - Revised\",\n  \"effective_date\": \"2024-01-01\",\n  \"cutoff_date\": \"2024-04-15\",\n  \"priority\": 1,\n  \"allocated_quantity\": 120,\n  \"product_id\": 10,\n  \"status\": \"active\",\n  \"notes\": \"Extended cutoff date\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Edition 'Q1 2024 Edition - Revised' updated successfully.\",\n  \"data\": {\n    \"id\": 1,\n    \"subscription_offering_id\": 5,\n    \"edition_name\": \"Q1 2024 Edition - Revised\",\n    \"effective_date\": \"2024-01-01\",\n    \"cutoff_date\": \"2024-04-15\",\n    \"priority\": 1,\n    \"allocated_quantity\": 120,\n    \"consumed_quantity\": 45,\n    \"remaining_quantity\": 75,\n    \"product_id\": 10,\n    \"status\": \"active\",\n    \"notes\": \"Extended cutoff date\"\n  }\n}"}]},{"name":"Delete Subscription Edition","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Deletes a subscription edition.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Edition 'Q1 2024 Edition' deleted successfully.\"\n}"}]},{"name":"Activate Subscription Edition","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/activate","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","activate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Activates a draft subscription edition by setting its status to 'active'.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/activate","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","activate"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Edition activated successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"edition_name\": \"Q1 2024 Edition\",\n    \"status\": \"active\",\n    \"subscription_offering\": {\n      \"id\": 5,\n      \"name\": \"Premium Widget Subscription\"\n    },\n    \"product\": {\n      \"id\": 10,\n      \"name\": \"Widget Pro\",\n      \"sku\": \"WIDGET-PRO-001\"\n    }\n  }\n}"}]},{"name":"Archive Subscription Edition","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/archive","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Archives a subscription edition by setting its status to 'archived'.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/archive","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","archive"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Edition archived successfully\",\n  \"data\": {\n    \"id\": 1,\n    \"edition_name\": \"Q1 2024 Edition\",\n    \"status\": \"archived\"\n  }\n}"}]},{"name":"Copy Subscription Edition","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/copy","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","copy"],"variable":[{"key":"id","value":"","description":"The id identifier"}]},"description":"Creates a new draft edition by copying an existing one with a new name and effective date.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nFields:\n- edition_name (required): Name for the new copy (max 255 chars)\n- effective_date (required): Effective date for the copy (YYYY-MM-DD)","body":{"mode":"raw","raw":"{\n  \"edition_name\": \"Q2 2024 Edition (Copy of Q1)\",\n  \"effective_date\": \"2024-04-01\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-editions/{id}/copy","host":["{{baseUrl}}"],"path":["api","subscription-editions",":id","copy"],"variable":[{"key":"id","value":"","description":"The id identifier"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Edition created successfully.\",\n  \"data\": {\n    \"id\": 3,\n    \"subscription_offering_id\": 5,\n    \"edition_name\": \"Q2 2024 Edition (Copy of Q1)\",\n    \"effective_date\": \"2024-04-01\",\n    \"cutoff_date\": null,\n    \"priority\": 1,\n    \"allocated_quantity\": 100,\n    \"consumed_quantity\": 0,\n    \"remaining_quantity\": 100,\n    \"product_id\": 10,\n    \"status\": \"draft\",\n    \"notes\": \"Q1 release batch\",\n    \"subscription_offering\": {\n      \"id\": 5,\n      \"name\": \"Premium Widget Subscription\"\n    },\n    \"product\": {\n      \"id\": 10,\n      \"name\": \"Widget Pro\",\n      \"sku\": \"WIDGET-PRO-001\"\n    }\n  }\n}"}]},{"name":"List Subscription Offerings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings?page=1&per_page=15&sort=name&filter[status]=active&filter[name]=&filter[sku]=&filter[editions_count]=&filter[product_listings_count]=&filter[created_at]=&filter[updated_at]=&filter[search]=quarterly","host":["{{baseUrl}}"],"path":["api","subscription-offerings"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, sku, status, created_at. Default: name","disabled":true},{"key":"filter[status]","value":"active","description":"Filter by status (text filter). Values: active, paused, archived","disabled":true},{"key":"filter[name]","value":"","description":"Filter by offering name (text filter)","disabled":true},{"key":"filter[sku]","value":"","description":"Filter by offering SKU (text filter)","disabled":true},{"key":"filter[editions_count]","value":"","description":"Filter by edition count (numeric filter)","disabled":true},{"key":"filter[product_listings_count]","value":"","description":"Filter by product listings count (numeric filter)","disabled":true},{"key":"filter[created_at]","value":"","description":"Filter by created_at (datetime filter)","disabled":true},{"key":"filter[updated_at]","value":"","description":"Filter by updated_at (datetime filter)","disabled":true},{"key":"filter[search]","value":"quarterly","description":"Search across id, name, and sku","disabled":true}]},"description":"Get a paginated list of subscription offerings with filtering and sorting.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAllowed sorts: id, name, sku, status, created_at. Default sort: name.\nPagination defaults to 15 per page.\nEach offering includes edition count and product listings count."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings?page=1&per_page=15&sort=name&filter[status]=active&filter[name]=&filter[sku]=&filter[editions_count]=&filter[product_listings_count]=&filter[created_at]=&filter[updated_at]=&filter[search]=quarterly","host":["{{baseUrl}}"],"path":["api","subscription-offerings"],"query":[{"key":"page","value":"1","description":"Page number (default: 1)","disabled":true},{"key":"per_page","value":"15","description":"Items per page (default: 15)","disabled":true},{"key":"sort","value":"name","description":"Sort field. Prefix with - for descending. Allowed: id, name, sku, status, created_at. Default: name","disabled":true},{"key":"filter[status]","value":"active","description":"Filter by status (text filter). Values: active, paused, archived","disabled":true},{"key":"filter[name]","value":"","description":"Filter by offering name (text filter)","disabled":true},{"key":"filter[sku]","value":"","description":"Filter by offering SKU (text filter)","disabled":true},{"key":"filter[editions_count]","value":"","description":"Filter by edition count (numeric filter)","disabled":true},{"key":"filter[product_listings_count]","value":"","description":"Filter by product listings count (numeric filter)","disabled":true},{"key":"filter[created_at]","value":"","description":"Filter by created_at (datetime filter)","disabled":true},{"key":"filter[updated_at]","value":"","description":"Filter by updated_at (datetime filter)","disabled":true},{"key":"filter[search]","value":"quarterly","description":"Search across id, name, and sku","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Quarterly Beauty Box\",\n      \"sku\": \"QBB-Q1\",\n      \"default_product_id\": 55,\n      \"status\": \"active\",\n      \"settings\": null,\n      \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T12:00:00.000000Z\",\n      \"default_product\": {\n        \"id\": 55,\n        \"name\": \"Beauty Box Standard\",\n        \"sku\": \"BB-STD\"\n      },\n      \"editions_count\": 4,\n      \"product_listings_count\": 2,\n      \"editions\": null,\n      \"active_editions\": null\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 3,\n  \"per_page\": 15,\n  \"total\": 32\n}"}]},{"name":"Create Subscription Offering","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-offerings","host":["{{baseUrl}}"],"path":["api","subscription-offerings"]},"description":"Create a new subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: name. Optional: sku (unique), default_product_id, status (active|paused|archived), settings.","body":{"mode":"raw","raw":"{\n  \"name\": \"Quarterly Beauty Box\",\n  \"sku\": \"QBB-Q1\",\n  \"default_product_id\": 55,\n  \"status\": \"active\",\n  \"settings\": null\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings","host":["{{baseUrl}}"],"path":["api","subscription-offerings"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Quarterly Beauty Box\",\n    \"sku\": \"QBB-Q1\",\n    \"default_product_id\": 55,\n    \"status\": \"active\",\n    \"settings\": null,\n    \"created_at\": \"2024-02-01T09:00:00.000000Z\",\n    \"updated_at\": \"2024-02-01T09:00:00.000000Z\"\n  },\n  \"message\": \"Subscription Offering created successfully\"\n}"}]},{"name":"Get Active Offerings List (Picker)","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/active-list","host":["{{baseUrl}}"],"path":["api","subscription-offerings","active-list"]},"description":"Get a lightweight list of active subscription offerings with edition counts — for use in pickers and dropdowns.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns only active offerings, ordered by name."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/active-list","host":["{{baseUrl}}"],"path":["api","subscription-offerings","active-list"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Quarterly Beauty Box\",\n      \"sku\": \"QBB-Q1\",\n      \"active_editions_count\": 2,\n      \"default_product\": {\n        \"id\": 55,\n        \"name\": \"Beauty Box Standard\",\n        \"sku\": \"BB-STD\"\n      }\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Monthly Coffee Club\",\n      \"sku\": \"MCC-M1\",\n      \"active_editions_count\": 1,\n      \"default_product\": null\n    }\n  ]\n}"}]},{"name":"Get Subscription Offering","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get a subscription offering with full detail including editions and product listings count.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Quarterly Beauty Box\",\n    \"sku\": \"QBB-Q1\",\n    \"default_product_id\": 55,\n    \"status\": \"active\",\n    \"settings\": null,\n    \"created_at\": \"2024-01-01T00:00:00.000000Z\",\n    \"updated_at\": \"2024-01-15T12:00:00.000000Z\",\n    \"default_product\": {\n      \"id\": 55,\n      \"name\": \"Beauty Box Standard\",\n      \"sku\": \"BB-STD\"\n    },\n    \"editions_count\": 4,\n    \"product_listings_count\": 2,\n    \"editions\": [\n      {\n        \"id\": 10,\n        \"subscription_offering_id\": 1,\n        \"edition_name\": \"Q1 2024\",\n        \"effective_date\": \"2024-01-01\",\n        \"cutoff_date\": \"2024-03-15\",\n        \"priority\": 1,\n        \"allocated_quantity\": 500,\n        \"consumed_quantity\": 123,\n        \"remaining_quantity\": 377,\n        \"product_id\": 55,\n        \"status\": \"active\",\n        \"notes\": null\n      }\n    ]\n  }\n}"}]},{"name":"Update Subscription Offering","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Update an existing subscription offering. All fields are optional.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nSKU must be unique (ignores own record).","body":{"mode":"raw","raw":"{\n  \"name\": \"Quarterly Beauty Box (Updated)\",\n  \"sku\": \"QBB-Q1-V2\",\n  \"default_product_id\": 55,\n  \"status\": \"active\",\n  \"settings\": {\n    \"auto_resolve\": true\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Quarterly Beauty Box (Updated)\",\n    \"sku\": \"QBB-Q1-V2\",\n    \"status\": \"active\",\n    \"updated_at\": \"2024-02-01T10:00:00.000000Z\"\n  },\n  \"message\": \"Subscription Offering Quarterly Beauty Box (Updated) updated successfully\"\n}"}]},{"name":"Delete Subscription Offering","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Delete a subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns 422 if the offering has linked product listings."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Offering Quarterly Beauty Box deleted successfully\"\n}"}]},{"name":"Activate Offering","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/activate","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","activate"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Set the status of a subscription offering to active.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/activate","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","activate"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Quarterly Beauty Box\",\n    \"status\": \"active\"\n  },\n  \"message\": \"Subscription Offering Quarterly Beauty Box updated successfully\"\n}"}]},{"name":"Pause Offering","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/pause","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","pause"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Set the status of a subscription offering to paused.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/pause","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","pause"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Quarterly Beauty Box\",\n    \"status\": \"paused\"\n  },\n  \"message\": \"Subscription Offering Quarterly Beauty Box updated successfully\"\n}"}]},{"name":"List Editions for Offering","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get paginated editions for a subscription offering.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions?per_page=15&page=1","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions"],"query":[{"key":"per_page","value":"15","description":"Items per page","disabled":true},{"key":"page","value":"1","description":"Page number","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 10,\n      \"subscription_offering_id\": 1,\n      \"edition_name\": \"Q1 2024\",\n      \"effective_date\": \"2024-01-01\",\n      \"cutoff_date\": \"2024-03-15\",\n      \"priority\": 1,\n      \"allocated_quantity\": 500,\n      \"consumed_quantity\": 123,\n      \"remaining_quantity\": 377,\n      \"product_id\": 55,\n      \"status\": \"active\",\n      \"notes\": null,\n      \"created_at\": \"2023-12-01T00:00:00.000000Z\",\n      \"updated_at\": \"2024-01-10T00:00:00.000000Z\",\n      \"subscription_offering\": {\n        \"id\": 1,\n        \"name\": \"Quarterly Beauty Box\"\n      },\n      \"product\": {\n        \"id\": 55,\n        \"name\": \"Beauty Box Standard\",\n        \"sku\": \"BB-STD\"\n      }\n    }\n  ],\n  \"current_page\": 1,\n  \"per_page\": 15,\n  \"total\": 4\n}"}]},{"name":"Create Edition for Offering","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Create a new edition for a subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequired: edition_name, effective_date, product_id. Optional: cutoff_date (must be >= effective_date), priority, allocated_quantity, status, notes.","body":{"mode":"raw","raw":"{\n  \"edition_name\": \"Q2 2024\",\n  \"effective_date\": \"2024-04-01\",\n  \"cutoff_date\": \"2024-06-15\",\n  \"priority\": 1,\n  \"allocated_quantity\": 600,\n  \"product_id\": 56,\n  \"status\": \"draft\",\n  \"notes\": \"Spring edition with new formula\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 11,\n    \"subscription_offering_id\": 1,\n    \"edition_name\": \"Q2 2024\",\n    \"effective_date\": \"2024-04-01\",\n    \"cutoff_date\": \"2024-06-15\",\n    \"priority\": 1,\n    \"allocated_quantity\": 600,\n    \"consumed_quantity\": 0,\n    \"remaining_quantity\": 600,\n    \"product_id\": 56,\n    \"status\": \"draft\",\n    \"notes\": \"Spring edition with new formula\",\n    \"subscription_offering\": {\n      \"id\": 1,\n      \"name\": \"Quarterly Beauty Box\"\n    },\n    \"product\": {\n      \"id\": 56,\n      \"name\": \"Beauty Box Spring\",\n      \"sku\": \"BB-SPR\"\n    }\n  },\n  \"message\": \"Subscription Edition created successfully\"\n}"}]},{"name":"Get Edition for Offering","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]},"description":"Get a single subscription edition nested under an offering.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"subscription_offering_id\": 1,\n    \"edition_name\": \"Q1 2024\",\n    \"effective_date\": \"2024-01-01\",\n    \"cutoff_date\": \"2024-03-15\",\n    \"priority\": 1,\n    \"allocated_quantity\": 500,\n    \"consumed_quantity\": 123,\n    \"remaining_quantity\": 377,\n    \"product_id\": 55,\n    \"status\": \"active\",\n    \"notes\": null,\n    \"subscription_offering\": {\n      \"id\": 1,\n      \"name\": \"Quarterly Beauty Box\"\n    },\n    \"product\": {\n      \"id\": 55,\n      \"name\": \"Beauty Box Standard\",\n      \"sku\": \"BB-STD\"\n    }\n  }\n}"}]},{"name":"Update Edition for Offering","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]},"description":"Update an edition nested under an offering. All fields are optional.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\ncutoff_date must be on or after effective_date.","body":{"mode":"raw","raw":"{\n  \"edition_name\": \"Q1 2024 (Final)\",\n  \"cutoff_date\": \"2024-03-20\",\n  \"allocated_quantity\": 550,\n  \"status\": \"active\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 10,\n    \"edition_name\": \"Q1 2024 (Final)\",\n    \"allocated_quantity\": 550,\n    \"status\": \"active\",\n    \"updated_at\": \"2024-02-01T10:00:00.000000Z\"\n  },\n  \"message\": \"Subscription Edition Q1 2024 (Final) updated successfully\"\n}"}]},{"name":"Delete Edition for Offering","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]},"description":"Delete an edition from a subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/{edition}","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions",":edition"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"edition","value":"10","description":"Edition ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Subscription Edition Q1 2024 deleted successfully\"\n}"}]},{"name":"Editions Orders Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/orders-summary?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions","orders-summary"],"query":[{"key":"date_range","value":"90","description":"Date range in days to look back (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get orders summary grouped by edition for a subscription offering.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIncludes order count, units sold, revenue, average order value, fulfillment rate, and current edition flag."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/editions/orders-summary?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","editions","orders-summary"],"query":[{"key":"date_range","value":"90","description":"Date range in days to look back (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"edition_id\": 10,\n      \"edition_name\": \"Q1 2024\",\n      \"orders_count\": 123,\n      \"total_units\": 123,\n      \"total_revenue\": 4551,\n      \"avg_order_value\": 37,\n      \"effective_date\": \"2024-01-01\",\n      \"fulfillment_rate\": 87,\n      \"is_current\": true\n    }\n  ]\n}"}]},{"name":"List Product Listings","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings?filter[integration_id]=&filter[integration_instance_id]=5","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings"],"query":[{"key":"filter[integration_id]","value":"","description":"Filter by integration ID (comma-separated for multiple)","disabled":true},{"key":"filter[integration_instance_id]","value":"5","description":"Filter by integration instance ID (comma-separated for multiple)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get product listings linked to a subscription offering.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIncludes integration instance details via salesChannel."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings?filter[integration_id]=&filter[integration_instance_id]=5","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings"],"query":[{"key":"filter[integration_id]","value":"","description":"Filter by integration ID (comma-separated for multiple)","disabled":true},{"key":"filter[integration_instance_id]","value":"5","description":"Filter by integration instance ID (comma-separated for multiple)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 300,\n      \"product_id\": 55,\n      \"subscription_offering_id\": 1,\n      \"integration_instance\": {\n        \"id\": 5,\n        \"name\": \"Shopify Store\"\n      },\n      \"created_at\": \"2024-01-05T00:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Link Product Listing","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings/{product_listing}/link","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings",":product_listing","link"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"product_listing","value":"300","description":"Product listing ID"}]},"description":"Link a product listing to the subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nClears any existing product mapping on the listing and sets the subscription offering, keeping the product/offering XOR constraint satisfied (a listing maps to EITHER a product OR an offering, never both).\n\nAuthentication: Requires Bearer token.\n\nReturns 422 if the subscription offering is not found or is archived."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings/{product_listing}/link","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings",":product_listing","link"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"product_listing","value":"300","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product listing linked to subscription offering successfully\"\n}"}]},{"name":"Unlink Product Listing","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings/{product_listing}/unlink","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings",":product_listing","unlink"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"product_listing","value":"300","description":"Product listing ID"}]},"description":"Unlink a product listing from the subscription offering.\n\n**Required scope: `subscriptions:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nOffering-only listings carry no product mapping, so unlinking REMOVES the listing entirely rather than leaving it in a both-null state that would violate the product/offering XOR constraint. Deletion runs through the model so the FBA delete guard and cache observer both fire.\n\nAuthentication: Requires Bearer token.\n\nReturns 400 if the listing is not linked to this offering. Returns 422 if the listing cannot be deleted because it has associated orders (FBA-protected listing)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/product-listings/{product_listing}/unlink","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","product-listings",":product_listing","unlink"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"},{"key":"product_listing","value":"300","description":"Product listing ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Product listing unlinked from subscription offering successfully\"\n}"}]},{"name":"Performance Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/report?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","report"],"query":[{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get offering performance report data including summary metrics, edition performance, and upcoming cutoffs.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/report?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","report"],"query":[{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"summary\": {\n      \"total_orders\": 347,\n      \"total_revenue\": 12839,\n      \"total_units\": 347,\n      \"active_editions\": 2\n    },\n    \"editions\": [\n      {\n        \"id\": 10,\n        \"edition_name\": \"Q1 2024\",\n        \"orders\": 123,\n        \"revenue\": 4551,\n        \"units\": 123,\n        \"is_current\": true\n      }\n    ],\n    \"upcoming_cutoffs\": [\n      {\n        \"edition_id\": 10,\n        \"edition_name\": \"Q1 2024\",\n        \"cutoff_date\": \"2024-03-15\",\n        \"days_until\": 14\n      }\n    ]\n  }\n}"}]},{"name":"Demand Forecast","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/demand-forecast?forecast_days=30&lookback_days=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","demand-forecast"],"query":[{"key":"forecast_days","value":"30","description":"Forecast period in days (default: 30)","disabled":true},{"key":"lookback_days","value":"90","description":"Historical lookback period in days (default: 90)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get demand forecast for the offering based on historical order velocity.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nCalculates daily order velocity from lookback period and projects expected remaining orders for the current edition."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/demand-forecast?forecast_days=30&lookback_days=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","demand-forecast"],"query":[{"key":"forecast_days","value":"30","description":"Forecast period in days (default: 30)","disabled":true},{"key":"lookback_days","value":"90","description":"Historical lookback period in days (default: 90)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"current_edition\": {\n      \"id\": 10,\n      \"edition_name\": \"Q1 2024\",\n      \"remaining_expected_orders\": 42,\n      \"days_until_cutoff\": 14,\n      \"cutoff_date\": \"2024-03-15\"\n    },\n    \"upcoming_edition\": {\n      \"id\": 11,\n      \"edition_name\": \"Q2 2024\",\n      \"effective_date\": \"2024-04-01\",\n      \"product\": {\n        \"id\": 56,\n        \"name\": \"Beauty Box Spring\",\n        \"sku\": \"BB-SPR\"\n      }\n    },\n    \"forecast_metrics\": {\n      \"daily_order_velocity\": 3,\n      \"lookback_period_days\": 90,\n      \"forecast_period_days\": 30,\n      \"total_orders_in_lookback\": 270\n    }\n  }\n}"}]},{"name":"Low Stock Alerts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/low-stock-alerts","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","low-stock-alerts"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get low stock alerts for active edition products.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nAlert levels: critical (below min_stock_level), warning (< 2 weeks of stock), info (< 4 weeks of stock)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/low-stock-alerts","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","low-stock-alerts"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"alerts\": [\n      {\n        \"edition_id\": 10,\n        \"edition_name\": \"Q1 2024\",\n        \"product\": {\n          \"id\": 55,\n          \"name\": \"Beauty Box Standard\",\n          \"sku\": \"BB-STD\"\n        },\n        \"current_inventory\": 50,\n        \"min_stock_level\": 10,\n        \"weekly_velocity\": 30,\n        \"weeks_of_stock\": 1.67,\n        \"alert_level\": \"warning\"\n      }\n    ],\n    \"total_alerts\": 1\n  }\n}"}]},{"name":"Component Requirements","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/component-requirements","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","component-requirements"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get component requirements for bundle edition products.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nOnly returns data for editions whose product type is 'bundle'."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/component-requirements","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","component-requirements"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"requirements\": [\n      {\n        \"edition_id\": 10,\n        \"edition_name\": \"Q1 2024\",\n        \"bundle_product\": {\n          \"id\": 55,\n          \"name\": \"Beauty Box Standard\",\n          \"sku\": \"BB-STD\"\n        },\n        \"components\": [\n          {\n            \"id\": 60,\n            \"name\": \"Lip Gloss\",\n            \"sku\": \"LG-001\",\n            \"total_required\": 123,\n            \"current_inventory\": 200,\n            \"status\": \"sufficient\"\n          }\n        ],\n        \"total_bundle_orders\": 123\n      }\n    ],\n    \"total_bundle_editions\": 1\n  }\n}"}]},{"name":"Draft Editions Pending","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/draft-editions-pending","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","draft-editions-pending"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get draft editions pending activation, ordered by effective date.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nIncludes is_urgent flag for editions effective within 7 days."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/draft-editions-pending","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","draft-editions-pending"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"drafts\": [\n      {\n        \"id\": 11,\n        \"edition_name\": \"Q2 2024\",\n        \"effective_date\": \"2024-04-01\",\n        \"days_until_effective\": 5,\n        \"is_urgent\": true,\n        \"product\": {\n          \"id\": 56,\n          \"name\": \"Beauty Box Spring\",\n          \"sku\": \"BB-SPR\"\n        },\n        \"notes\": \"Spring edition\",\n        \"created_at\": \"2024-03-15T00:00:00.000000Z\"\n      }\n    ],\n    \"total_drafts\": 1,\n    \"urgent_activations\": 1\n  }\n}"}]},{"name":"Override Audit Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/override-audit-log?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","override-audit-log"],"query":[{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get edition override audit log — shows all order lines where the automatically-resolved edition was manually overridden.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/override-audit-log?date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","override-audit-log"],"query":[{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"overrides\": [\n      {\n        \"id\": 500,\n        \"sales_order_id\": 1001,\n        \"order_reference\": \"SO-2024-1001\",\n        \"overridden_edition_id\": 9,\n        \"original_edition\": \"Q4 2023\",\n        \"reason\": \"Customer requested old edition\",\n        \"created_at\": \"2024-01-10T00:00:00.000000Z\"\n      }\n    ],\n    \"total_overrides\": 1,\n    \"override_rate\": 0.81\n  }\n}"}]},{"name":"Offering Trends","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/offering-trends","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","offering-trends"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get trends data for the subscription offering.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/reports/offering-trends","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","reports","offering-trends"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {}\n}"}]},{"name":"Timeline","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/timeline","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","timeline"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Get all editions ordered by effective_date for timeline visualization.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/timeline","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","timeline"],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"offering\": {\n      \"id\": 1,\n      \"name\": \"Quarterly Beauty Box\"\n    },\n    \"editions\": [\n      {\n        \"id\": 9,\n        \"edition_name\": \"Q4 2023\",\n        \"effective_date\": \"2023-10-01\",\n        \"cutoff_date\": \"2023-12-15\",\n        \"status\": \"archived\",\n        \"product\": {\n          \"id\": 54,\n          \"name\": \"Beauty Box Winter\",\n          \"sku\": \"BB-WIN\"\n        }\n      },\n      {\n        \"id\": 10,\n        \"edition_name\": \"Q1 2024\",\n        \"effective_date\": \"2024-01-01\",\n        \"cutoff_date\": \"2024-03-15\",\n        \"status\": \"active\",\n        \"product\": {\n          \"id\": 55,\n          \"name\": \"Beauty Box Standard\",\n          \"sku\": \"BB-STD\"\n        }\n      }\n    ]\n  }\n}"}]},{"name":"Resolve Edition for Order Date","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/resolve?order_date=2024-02-15","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","resolve"],"query":[{"key":"order_date","value":"2024-02-15","description":"Order date to resolve edition for (Y-m-d format). Defaults to now.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Preview edition resolution for a given order date.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/resolve?order_date=2024-02-15","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","resolve"],"query":[{"key":"order_date","value":"2024-02-15","description":"Order date to resolve edition for (Y-m-d format). Defaults to now.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"order_date\": \"2024-02-15 00:00:00\",\n    \"resolved_edition\": {\n      \"id\": 10,\n      \"edition_name\": \"Q1 2024\",\n      \"effective_date\": \"2024-01-01\",\n      \"cutoff_date\": \"2024-03-15\"\n    },\n    \"resolved_product\": {\n      \"id\": 55,\n      \"name\": \"Beauty Box Standard\",\n      \"sku\": \"BB-STD\"\n    },\n    \"resolution_source\": \"edition\",\n    \"used_cutoff_logic\": false\n  }\n}"}]},{"name":"Resolve Edition for Sales Order","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/resolve-for-order?order_date=2024-02-15&quantity=2&edition_id=10","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","resolve-for-order"],"query":[{"key":"order_date","value":"2024-02-15","description":"Order date to resolve edition for (Y-m-d or datetime). Defaults to now.","disabled":true},{"key":"quantity","value":"2","description":"Quantity to check allocation for (default: 1)","disabled":true},{"key":"edition_id","value":"10","description":"Optional: manually override the resolved edition ID","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Resolve the edition for a sales order given an order date and optional quantity. Used by the sales order offering picker to preview resolution.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns the resolved edition with remaining quantity, is_fallback flag, and resolution reason."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/resolve-for-order?order_date=2024-02-15&quantity=2&edition_id=10","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","resolve-for-order"],"query":[{"key":"order_date","value":"2024-02-15","description":"Order date to resolve edition for (Y-m-d or datetime). Defaults to now.","disabled":true},{"key":"quantity","value":"2","description":"Quantity to check allocation for (default: 1)","disabled":true},{"key":"edition_id","value":"10","description":"Optional: manually override the resolved edition ID","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"resolved_edition\": {\n      \"id\": 10,\n      \"edition_name\": \"Q1 2024\",\n      \"effective_date\": \"2024-01-01\",\n      \"cutoff_date\": \"2024-03-15\",\n      \"priority\": 1,\n      \"allocated_quantity\": 500,\n      \"consumed_quantity\": 123,\n      \"remaining_quantity\": 377,\n      \"product\": {\n        \"id\": 55,\n        \"name\": \"Beauty Box Standard\",\n        \"sku\": \"BB-STD\"\n      }\n    },\n    \"product_id\": 55,\n    \"is_fallback\": false,\n    \"resolution_reason\": \"edition_match\"\n  }\n}"}]},{"name":"Product Stock Summary","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/product-stock-summary/{product}","host":["{{baseUrl}}"],"path":["api","subscription-offerings","product-stock-summary",":product"],"variable":[{"key":"product","value":"55","description":"Product ID"}]},"description":"Get stock summary for a product — used when planning edition allocations.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nReturns on-hand, reserved, allocated, available, in-transit inventory, plus incoming purchase orders and warehouse transfers."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/product-stock-summary/{product}","host":["{{baseUrl}}"],"path":["api","subscription-offerings","product-stock-summary",":product"],"variable":[{"key":"product","value":"55","description":"Product ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"product_id\": 55,\n    \"product_name\": \"Beauty Box Standard\",\n    \"product_sku\": \"BB-STD\",\n    \"on_hand\": 500,\n    \"reserved\": 50,\n    \"allocated\": 123,\n    \"available\": 327,\n    \"in_transit\": 0,\n    \"incoming_po\": 200,\n    \"incoming_transfers\": 0,\n    \"available_to_allocate\": 527,\n    \"purchase_orders\": [\n      {\n        \"po_number\": \"PO-2024-0022\",\n        \"po_id\": 22,\n        \"ordered_quantity\": 200,\n        \"received_quantity\": 0,\n        \"pending_quantity\": 200,\n        \"expected_date\": \"2024-03-01\"\n      }\n    ],\n    \"warehouse_transfers\": []\n  }\n}"}]},{"name":"Export Performance Report","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/report?format=xlsx&date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","report"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Export the offering performance report to XLSX or CSV.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nColumns: Edition, Product SKU, Product Name, Orders, Units Sold, Revenue, Effective Date, Status."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/report?format=xlsx&date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","report"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv (default: xlsx)","disabled":true},{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary xlsx/csv file)"}]},{"name":"Export Demand Forecast","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/demand-forecast?format=xlsx&forecast_days=30&lookback_days=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","demand-forecast"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true},{"key":"forecast_days","value":"30","description":"Forecast period in days (default: 30)","disabled":true},{"key":"lookback_days","value":"90","description":"Historical lookback period in days (default: 90)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Export demand forecast data to XLSX or CSV.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nColumns: Current Edition, Daily Velocity, Days Until Cutoff, Expected Remaining Orders, Lookback Period (Days), Total Orders in Lookback."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/demand-forecast?format=xlsx&forecast_days=30&lookback_days=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","demand-forecast"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true},{"key":"forecast_days","value":"30","description":"Forecast period in days (default: 30)","disabled":true},{"key":"lookback_days","value":"90","description":"Historical lookback period in days (default: 90)","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary xlsx/csv file)"}]},{"name":"Export Low Stock Alerts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/low-stock-alerts?format=xlsx","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","low-stock-alerts"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Export low stock alerts to XLSX or CSV.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nColumns: Edition, Product SKU, Product Name, Current Inventory, Min Stock Level, Weekly Velocity, Weeks of Stock, Alert Level."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/low-stock-alerts?format=xlsx","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","low-stock-alerts"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary xlsx/csv file)"}]},{"name":"Export Override Audit Log","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/override-audit-log?format=xlsx&date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","override-audit-log"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true},{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]},"description":"Export edition override audit log to XLSX or CSV.\n\n**Required scope: `subscriptions:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nColumns: Order Reference, Overridden Edition ID, Reason, Created At."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/subscription-offerings/{subscription_offering}/export/override-audit-log?format=xlsx&date_range=90","host":["{{baseUrl}}"],"path":["api","subscription-offerings",":subscription_offering","export","override-audit-log"],"query":[{"key":"format","value":"xlsx","description":"Export format: xlsx or csv","disabled":true},{"key":"date_range","value":"90","description":"Look-back period in days (default: 90). Use 'all' for all time.","disabled":true}],"variable":[{"key":"subscription_offering","value":"1","description":"Subscription offering ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"(binary xlsx/csv file)"}]}]},{"name":"UI Utilities","item":[{"name":"Query list view Model","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/data-tables?model=App%5CModels%5CSalesOrder&search=C-1001&include_data_table_blueprint=false&include_saved_views=false","host":["{{baseUrl}}"],"path":["api","data-tables"],"query":[{"key":"model","value":"App%5CModels%5CSalesOrder","description":"Required. Fully qualified model class name (must implement DataTableBlueprintInterface)","disabled":true},{"key":"search","value":"C-1001","description":"Optional. Full-text search query","disabled":true},{"key":"include_data_table_blueprint","value":"false","description":"Optional boolean. Include blueprint config and searchable fields in response","disabled":true},{"key":"include_saved_views","value":"false","description":"Optional boolean. Include saved views for the model in response","disabled":true}]},"description":"Execute a paginated list view query against a model. The model must implement DataTableBlueprintInterface. Supports search, filtering (via filter[] params or a saved_view_id), and pagination.\n\nAuthentication: Requires Bearer token.\n\nQuery Parameters:\n- model (required, string): Fully qualified model class name\n- search (optional, string): Full-text search query\n- filter (optional, array): Filter conditions — mutually exclusive with saved_view_id\n- saved_view_id (optional, integer): Load state from a saved view — mutually exclusive with filter[]\n- include_data_table_blueprint (optional, boolean): Include the blueprint config in response\n- include_saved_views (optional, boolean): Include all saved views for the model\n\nErrors:\n- 400 ScopeFilterDoesNotExistException: Invalid filter scope\n- 400 BadScopeFilterValueException: Invalid filter value"},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/data-tables?model=App%5CModels%5CSalesOrder&search=C-1001&include_data_table_blueprint=false&include_saved_views=false","host":["{{baseUrl}}"],"path":["api","data-tables"],"query":[{"key":"model","value":"App%5CModels%5CSalesOrder","description":"Required. Fully qualified model class name (must implement DataTableBlueprintInterface)","disabled":true},{"key":"search","value":"C-1001","description":"Optional. Full-text search query","disabled":true},{"key":"include_data_table_blueprint","value":"false","description":"Optional boolean. Include blueprint config and searchable fields in response","disabled":true},{"key":"include_saved_views","value":"false","description":"Optional boolean. Include saved views for the model in response","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1001,\n      \"sales_order_number\": \"C-1001\",\n      \"status\": \"open\",\n      \"created_at\": \"2024-04-15T10:00:00.000000Z\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 5,\n  \"per_page\": 15,\n  \"total\": 73,\n  \"from\": 1,\n  \"to\": 15\n}"}]}]},{"name":"Horizon","item":[{"name":"Restart Horizon","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/horizon-restart","host":["{{baseUrl}}"],"path":["horizon-restart"]},"description":"Custom application endpoint to trigger a Horizon restart. This sends a restart signal to Horizon workers, causing them to finish their current job and restart gracefully.\n\nAuthentication: Requires Bearer token.\n\nNote: This endpoint is at /horizon-restart (not under /horizon/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/horizon-restart","host":["{{baseUrl}}"],"path":["horizon-restart"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Horizon restart signal sent.\"\n}"}]}]},{"name":"Workflows","item":[{"name":"List Workflows","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows","host":["{{baseUrl}}"],"path":["api","automation","workflows"]},"description":"Paginated list of automation workflows with run statistics (total, successful, and failed runs, average duration, and last run).\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Filters:** `filter[status]` (draft, published, disabled), `filter[category]`, `filter[search]` (matches name or description).\n\n**Sorts:** `name`, `created_at`, `updated_at`. Prefix with `-` for descending. Default: `-updated_at`.\n\nPagination: `page`, `per_page` (default 10)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflows","host":["{{baseUrl}}"],"path":["api","automation","workflows"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": \"7\",\n      \"name\": \"Notify on new sales orders\",\n      \"description\": \"Posts a Slack message whenever a sales order is created\",\n      \"status\": \"published\",\n      \"category\": \"orders\",\n      \"version\": 3,\n      \"triggerCount\": 1,\n      \"nodeCount\": 2,\n      \"stats\": {\n        \"totalRuns\": 128,\n        \"successfulRuns\": 126,\n        \"failedRuns\": 2,\n        \"avgDuration\": 1840,\n        \"lastRun\": {\n          \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n          \"status\": \"success\",\n          \"duration\": 1650\n        }\n      },\n      \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n      \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n      \"createdBy\": \"Jane Smith\"\n    }\n  ],\n  \"first_page_url\": \"https://your-domain.sku.io/api/automation/workflows?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-domain.sku.io/api/automation/workflows?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://your-domain.sku.io/api/automation/workflows\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Create Workflow","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflows","host":["{{baseUrl}}"],"path":["api","automation","workflows"]},"description":"Create a new workflow in Draft status from a node/edge graph. The workflow's trigger type is derived automatically from the trigger node in the graph.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:** `name` (required, string, max 128), `description` (optional), `category` (optional, string, max 50), `nodes` (required array - may be empty while drafting), `edges` (required array), `viewport` (optional canvas position object).\n\nUse List Workflow Node Types to discover valid `nodes[*].type` values and each node's settings. Draft workflows are not executable until published.","body":{"mode":"raw","raw":"{\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"category\": \"orders\",\n  \"nodes\": [\n    {\n      \"id\": \"node_1\",\n      \"type\": \"sales-order-created\",\n      \"position\": {\n        \"x\": 80,\n        \"y\": 120\n      },\n      \"data\": {},\n      \"label\": \"Sales Order Created\"\n    },\n    {\n      \"id\": \"node_2\",\n      \"type\": \"slack-message\",\n      \"position\": {\n        \"x\": 360,\n        \"y\": 120\n      },\n      \"data\": {\n        \"channel\": \"#orders\"\n      },\n      \"label\": \"Send Slack Message\"\n    }\n  ],\n  \"edges\": [\n    {\n      \"id\": \"edge_1\",\n      \"source\": \"node_1\",\n      \"target\": \"node_2\"\n    }\n  ],\n  \"viewport\": {\n    \"x\": 0,\n    \"y\": 0,\n    \"zoom\": 1\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows","host":["{{baseUrl}}"],"path":["api","automation","workflows"]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"8\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"draft\",\n  \"version\": 1,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": null,\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Get Workflow","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Get a single workflow with its full node/edge graph, trigger configuration, and publication state.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: workflow = workflow id."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"7\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"published\",\n  \"version\": 3,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": \"2026-06-15T11:05:00+00:00\",\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Update Workflow","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Update a workflow's name, description, category, graph, or settings. When `nodes` are submitted, the trigger type and trigger configuration are re-derived from the graph.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields (all optional):** `name` (string, max 128), `description`, `category` (string, max 50), `nodes` (array - each node requires `id` (string, max 64), `type` (string, max 100), `position.x`/`position.y` (numeric), `data` (object, required per node), optional `label`), `edges` (array - each edge requires `id`, `source`, `target`; optional `sourceHandle`, `targetHandle`, `label`, `branchLabel`), `viewport`, `settings`.\n\nPath param: workflow = workflow id.","body":{"mode":"raw","raw":"{\n  \"name\": \"Notify on new sales orders\",\n  \"nodes\": [\n    {\n      \"id\": \"node_1\",\n      \"type\": \"sales-order-created\",\n      \"position\": {\n        \"x\": 80,\n        \"y\": 120\n      },\n      \"data\": {},\n      \"label\": \"Sales Order Created\"\n    },\n    {\n      \"id\": \"node_2\",\n      \"type\": \"slack-message\",\n      \"position\": {\n        \"x\": 360,\n        \"y\": 120\n      },\n      \"data\": {\n        \"channel\": \"#orders\"\n      },\n      \"label\": \"Send Slack Message\"\n    }\n  ],\n  \"edges\": [\n    {\n      \"id\": \"edge_1\",\n      \"source\": \"node_1\",\n      \"target\": \"node_2\"\n    }\n  ],\n  \"viewport\": {\n    \"x\": 0,\n    \"y\": 0,\n    \"zoom\": 1\n  },\n  \"settings\": {\n    \"errorHandling\": \"stop\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"7\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"published\",\n  \"version\": 3,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": \"2026-06-15T11:05:00+00:00\",\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Delete Workflow","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Permanently delete a workflow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: workflow = workflow id."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]}]},{"name":"Workflow Actions","item":[{"name":"Validate Workflow Graph","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflows/validate","host":["{{baseUrl}}"],"path":["api","automation","workflows","validate"]},"description":"Validate a node/edge graph without saving anything. Checks that the graph has exactly one trigger node, that every edge references existing nodes, and that every non-trigger node has an incoming connection.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:** `nodes` (required array), `edges` (required array).\n\nEach returned error has a `type` (`error` or `warning`), a `message`, and - when tied to a specific node - a `nodeId`. The graph is `valid` when no entries of type `error` are present.","body":{"mode":"raw","raw":"{\n  \"nodes\": [\n    {\n      \"id\": \"node_1\",\n      \"type\": \"sales-order-created\",\n      \"position\": {\n        \"x\": 80,\n        \"y\": 120\n      },\n      \"data\": {},\n      \"label\": \"Sales Order Created\"\n    },\n    {\n      \"id\": \"node_2\",\n      \"type\": \"slack-message\",\n      \"position\": {\n        \"x\": 360,\n        \"y\": 120\n      },\n      \"data\": {\n        \"channel\": \"#orders\"\n      },\n      \"label\": \"Send Slack Message\"\n    }\n  ],\n  \"edges\": [\n    {\n      \"id\": \"edge_1\",\n      \"source\": \"node_1\",\n      \"target\": \"node_2\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/validate","host":["{{baseUrl}}"],"path":["api","automation","workflows","validate"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"valid\": true,\n    \"errors\": []\n  }\n}"}]},{"name":"Publish Workflow","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/publish","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","publish"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Publish a workflow so its trigger becomes live. The graph is validated first - on failure nothing changes and the validation errors are returned with status 422. On success the version number is incremented, `publishedAt` is set, and the trigger type/configuration are re-derived from the graph.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: workflow = workflow id."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/publish","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","publish"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"7\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"published\",\n  \"version\": 3,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": \"2026-06-15T11:05:00+00:00\",\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Toggle Workflow","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/toggle","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","toggle"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Toggle a workflow between `published` (trigger live) and `disabled` (trigger paused). Only workflows in one of those two states can be toggled - draft workflows must be published first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: workflow = workflow id."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/toggle","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","toggle"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"7\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"disabled\",\n  \"version\": 3,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": \"2026-06-15T11:05:00+00:00\",\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Clone Workflow","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/clone","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","clone"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Duplicate a workflow as a new Draft. The clone copies the graph, settings, and trigger configuration, and is named \"&lt;name> (Copy)\".\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: workflow = workflow id."},"response":[{"name":"Created","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/clone","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","clone"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"9\",\n  \"uuid\": \"0f7a3c2e-9d41-4b8a-b1f2-6a5c88e01234\",\n  \"name\": \"Notify on new sales orders (Copy)\",\n  \"description\": \"Posts a Slack message whenever a sales order is created\",\n  \"status\": \"draft\",\n  \"version\": 1,\n  \"category\": \"orders\",\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"node_1\",\n        \"type\": \"sales-order-created\",\n        \"position\": {\n          \"x\": 80,\n          \"y\": 120\n        },\n        \"data\": {},\n        \"label\": \"Sales Order Created\"\n      },\n      {\n        \"id\": \"node_2\",\n        \"type\": \"slack-message\",\n        \"position\": {\n          \"x\": 360,\n          \"y\": 120\n        },\n        \"data\": {\n          \"channel\": \"#orders\"\n        },\n        \"label\": \"Send Slack Message\"\n      }\n    ],\n    \"edges\": [\n      {\n        \"id\": \"edge_1\",\n        \"source\": \"node_1\",\n        \"target\": \"node_2\"\n      }\n    ],\n    \"viewport\": {\n      \"x\": 0,\n      \"y\": 0,\n      \"zoom\": 1\n    }\n  },\n  \"settings\": null,\n  \"triggerType\": \"event\",\n  \"triggerConfig\": null,\n  \"createdAt\": \"2026-05-02T10:00:00+00:00\",\n  \"updatedAt\": \"2026-07-01T08:30:00+00:00\",\n  \"publishedAt\": null,\n  \"createdBy\": \"Jane Smith\",\n  \"updatedBy\": \"Jane Smith\"\n}"}]},{"name":"Execute Workflow","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/execute","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","execute"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Manually run a published workflow. The run is queued asynchronously: the response returns the new execution record immediately (status `pending`) - poll Get Workflow Execution for progress and step-by-step results.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:** `trigger_payload` (optional object) - data made available to the trigger node, in place of a real trigger event.\n\nOnly published workflows can be executed. Returns 403 when workflow automation is disabled for the account.\n\nPath param: workflow = workflow id.","body":{"mode":"raw","raw":"{\n  \"trigger_payload\": {\n    \"salesOrderId\": 1042\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/execute","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","execute"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"513\",\n  \"workflowId\": \"7\",\n  \"workflowVersion\": 3,\n  \"status\": \"pending\",\n  \"startedAt\": null,\n  \"finishedAt\": null,\n  \"duration\": null,\n  \"triggerPayload\": {\n    \"salesOrderId\": 1042\n  },\n  \"triggerReference\": null,\n  \"errorMessage\": null\n}"}]},{"name":"Upload File and Run Workflow","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/upload-and-run","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","upload-and-run"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Upload a file to a published workflow that has a File Upload trigger as its entry node, and run the workflow against it. The request is a `multipart/form-data` upload with a single `file` field.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nThe run is queued asynchronously and the response returns 202 with an `idempotencyKey` that identifies the resulting execution - filter List Workflow Executions by `filter[search]` on that key to track it.\n\nReturns 422 when the workflow is not published, has no File Upload trigger, or the file fails the trigger's format validation.\n\nPath param: workflow = workflow id.","body":{"mode":"formdata","formdata":[{"key":"file","type":"file","src":[]}]}},"response":[{"name":"Accepted","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/upload-and-run","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","upload-and-run"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"Accepted","code":202,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Upload accepted\",\n  \"idempotencyKey\": \"1c1f7c39-3f6e-4a9f-9a44-b1f0f2f9a001\",\n  \"fileName\": \"orders.csv\"\n}"}]}]},{"name":"Workflow Executions","item":[{"name":"List Workflow Executions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions"]},"description":"Paginated list of workflow executions across all workflows, newest first. Each row includes the workflow name.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Filters:** `filter[status]`, `filter[workflow_id]`, `filter[date_range]` (last_hour, last_day, last_week, last_month), `filter[search]` (matches trigger reference or idempotency key).\n\n**Sorts:** `created_at`, `duration_ms`, `status`. Prefix with `-` for DESC. Default: `-created_at`.\n\nPagination: `page`, `per_page` (default 15).\n\nFilter values use the stored statuses: pending, running, waiting, completed, failed, canceled. Response payloads expose display statuses where completed maps to success and canceled maps to cancelled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": \"512\",\n      \"workflowId\": \"7\",\n      \"workflowVersion\": 3,\n      \"status\": \"success\",\n      \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n      \"finishedAt\": \"2026-07-05T09:12:46+00:00\",\n      \"duration\": 1650,\n      \"triggerPayload\": {\n        \"salesOrderId\": 1042\n      },\n      \"triggerReference\": \"SO-1042\",\n      \"errorMessage\": null,\n      \"workflowName\": \"Notify on new sales orders\"\n    }\n  ],\n  \"first_page_url\": \"https://your-domain.sku.io/api/automation/workflow-executions?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-domain.sku.io/api/automation/workflow-executions?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://your-domain.sku.io/api/automation/workflow-executions\",\n  \"per_page\": 15,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Get Workflow Execution Stats","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/stats","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions","stats"]},"description":"Aggregate execution statistics across all workflows: total, successful, and failed run counts, the failure rate percentage, and the average run duration in milliseconds.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/stats","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions","stats"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"totalRuns\": 1284,\n    \"successfulRuns\": 1210,\n    \"failedRuns\": 74,\n    \"failureRate\": 5.8,\n    \"avgDuration\": 2140\n  }\n}"}]},{"name":"Get Workflow Execution","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]},"description":"Get a single execution with its full step-by-step results - per node: input, output, logs, timing, attempt count, and per-item success/error counts.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: execution = execution id.\n\nFilter values use the stored statuses: pending, running, waiting, completed, failed, canceled. Response payloads expose display statuses where completed maps to success and canceled maps to cancelled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"512\",\n  \"workflowId\": \"7\",\n  \"workflowVersion\": 3,\n  \"status\": \"success\",\n  \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n  \"finishedAt\": \"2026-07-05T09:12:46+00:00\",\n  \"duration\": 1650,\n  \"triggerPayload\": {\n    \"salesOrderId\": 1042\n  },\n  \"triggerReference\": \"SO-1042\",\n  \"errorMessage\": null,\n  \"steps\": [\n    {\n      \"id\": \"2201\",\n      \"executionId\": \"512\",\n      \"nodeId\": \"node_1\",\n      \"nodeName\": \"Sales Order Created\",\n      \"nodeType\": \"sales-order-created\",\n      \"status\": \"success\",\n      \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n      \"finishedAt\": \"2026-07-05T09:12:44+00:00\",\n      \"duration\": 12,\n      \"attempt\": 1,\n      \"input\": [],\n      \"output\": {\n        \"salesOrderId\": 1042,\n        \"orderNumber\": \"SO-1042\"\n      },\n      \"errorMessage\": null,\n      \"logs\": [],\n      \"itemCount\": 1,\n      \"itemSuccessCount\": 1,\n      \"itemErrorCount\": 0,\n      \"itemErrors\": []\n    },\n    {\n      \"id\": \"2202\",\n      \"executionId\": \"512\",\n      \"nodeId\": \"node_2\",\n      \"nodeName\": \"Send Slack Message\",\n      \"nodeType\": \"slack-message\",\n      \"status\": \"success\",\n      \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n      \"finishedAt\": \"2026-07-05T09:12:46+00:00\",\n      \"duration\": 1610,\n      \"attempt\": 1,\n      \"input\": {\n        \"salesOrderId\": 1042,\n        \"orderNumber\": \"SO-1042\"\n      },\n      \"output\": {\n        \"ok\": true\n      },\n      \"errorMessage\": null,\n      \"logs\": [],\n      \"itemCount\": 1,\n      \"itemSuccessCount\": 1,\n      \"itemErrorCount\": 0,\n      \"itemErrors\": []\n    }\n  ]\n}"}]},{"name":"Delete Workflow Execution","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]},"description":"Permanently delete an execution and its step results.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nPath param: execution = execution id."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{}"}]},{"name":"List Executions for Workflow","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/executions","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","executions"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]},"description":"Paginated list of executions for one workflow, newest first.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Filters:** `filter[status]`, `filter[date_range]` (last_hour, last_day, last_week, last_month), `filter[search]` (matches trigger reference or idempotency key).\n\n**Sorts:** `created_at`. Prefix with `-` for DESC. Default: `-created_at`.\n\nPagination: `page`, `per_page` (default 10).\n\nPath param: workflow = workflow id.\n\nFilter values use the stored statuses: pending, running, waiting, completed, failed, canceled. Response payloads expose display statuses where completed maps to success and canceled maps to cancelled."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflows/{workflow}/executions","host":["{{baseUrl}}"],"path":["api","automation","workflows",":workflow","executions"],"variable":[{"key":"workflow","value":"7","description":"The workflow ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"current_page\": 1,\n  \"data\": [\n    {\n      \"id\": \"512\",\n      \"workflowId\": \"7\",\n      \"workflowVersion\": 3,\n      \"status\": \"success\",\n      \"startedAt\": \"2026-07-05T09:12:44+00:00\",\n      \"finishedAt\": \"2026-07-05T09:12:46+00:00\",\n      \"duration\": 1650,\n      \"triggerPayload\": {\n        \"salesOrderId\": 1042\n      },\n      \"triggerReference\": \"SO-1042\",\n      \"errorMessage\": null\n    }\n  ],\n  \"first_page_url\": \"https://your-domain.sku.io/api/automation/workflows/7/executions?page=1\",\n  \"from\": 1,\n  \"last_page\": 1,\n  \"last_page_url\": \"https://your-domain.sku.io/api/automation/workflows/7/executions?page=1\",\n  \"links\": [],\n  \"next_page_url\": null,\n  \"path\": \"https://your-domain.sku.io/api/automation/workflows/7/executions\",\n  \"per_page\": 10,\n  \"prev_page_url\": null,\n  \"to\": 1,\n  \"total\": 1\n}"}]},{"name":"Replay Workflow Execution","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}/replay","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution","replay"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]},"description":"Re-run a past execution with the same trigger payload and the same workflow graph snapshot it originally ran against. A new execution record is created and queued asynchronously - the original execution is untouched.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nReturns 403 when workflow automation is disabled for the account.\n\nPath param: execution = execution id to replay."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/{execution}/replay","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions",":execution","replay"],"variable":[{"key":"execution","value":"512","description":"The execution ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": \"514\",\n  \"workflowId\": \"7\",\n  \"workflowVersion\": 3,\n  \"status\": \"pending\",\n  \"startedAt\": null,\n  \"finishedAt\": null,\n  \"duration\": null,\n  \"triggerPayload\": {\n    \"salesOrderId\": 1042\n  },\n  \"triggerReference\": \"SO-1042\",\n  \"errorMessage\": null\n}"}]},{"name":"Bulk Delete Workflow Executions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/bulk-delete","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions","bulk-delete"]},"description":"Permanently delete multiple executions and their step results in one call.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Body fields:** `ids` (required, array of execution ids).","body":{"mode":"raw","raw":"{\n  \"ids\": [\n    510,\n    511,\n    512\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/automation/workflow-executions/bulk-delete","host":["{{baseUrl}}"],"path":["api","automation","workflow-executions","bulk-delete"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"3 execution(s) deleted\"\n}"}]}]},{"name":"Workflow Node Types","item":[{"name":"List Workflow Node Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-nodes","host":["{{baseUrl}}"],"path":["api","automation","workflow-nodes"]},"description":"Catalog of every node type available for building workflow graphs. Use the `type` values here as `nodes[*].type` when creating or updating a workflow.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\nEach definition describes the node's category (`triggers`, `actions`, `logic`, ...), its inputs and outputs, the schema of the data it emits (`outputSchema`), and the settings it accepts (key, type, whether required, and default value)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/automation/workflow-nodes","host":["{{baseUrl}}"],"path":["api","automation","workflow-nodes"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"type\": \"schedule-trigger\",\n      \"label\": \"Schedule\",\n      \"category\": \"triggers\",\n      \"icon\": \"mdi-clock-outline\",\n      \"color\": \"#9C27B0\",\n      \"description\": \"Triggers on a recurring schedule using cron expressions\",\n      \"inputs\": [],\n      \"outputs\": [\n        {\n          \"key\": \"main\",\n          \"label\": \"Main Output\",\n          \"type\": \"main\",\n          \"description\": \"Schedule trigger data\"\n        }\n      ],\n      \"outputSchema\": {\n        \"scheduledAt\": {\n          \"label\": \"Scheduled At\",\n          \"type\": \"date\"\n        }\n      },\n      \"settings\": [\n        {\n          \"key\": \"cronExpression\",\n          \"label\": \"Cron Expression\",\n          \"type\": \"text\",\n          \"required\": true,\n          \"description\": \"Cron schedule (e.g., \\\"0 9 * * 1-5\\\" for weekdays at 9am)\",\n          \"placeholder\": \"0 9 * * *\"\n        },\n        {\n          \"key\": \"timezone\",\n          \"label\": \"Timezone\",\n          \"type\": \"text\",\n          \"description\": \"IANA timezone (e.g., America/New_York)\",\n          \"defaultValue\": \"UTC\"\n        }\n      ],\n      \"supportsBranching\": false\n    }\n  ]\n}"}]}]},{"name":"Workflow Templates","item":[{"name":"List Workflow Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-templates","host":["{{baseUrl}}"],"path":["api","automation","workflow-templates"]},"description":"Returns all official workflow templates, ordered for the template gallery.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** `200 OK` — wrapped in `{data: [...]}`, NOT a paginator. The list is expected to be small (a handful of official templates).\n\n**Response shape:**\n```json\n{\n  \"data\": [\n    {\n      \"slug\": \"import-products-csv-upload\",\n      \"name\": \"Import Products from CSV Upload\",\n      \"description\": \"User drops a CSV through the workflow webhook...\",\n      \"category\": \"imports\",\n      \"thumbnailPath\": null,\n      \"isOfficial\": true,\n      \"version\": 1,\n      \"parameterPrompts\": [\n        {\n          \"key\": \"allowedExtensions\",\n          \"path\": \"nodes.0.data.allowedExtensions\",\n          \"label\": \"Allowed file extensions\",\n          \"type\": \"string\",\n          \"required\": false,\n          \"default\": \"csv\",\n          \"help_text\": \"Comma-separated list of file extensions to accept (e.g. csv,tsv)\"\n        }\n      ],\n      \"requiredCredentials\": [],\n      \"nodeCount\": 4,\n      \"updatedAt\": \"2026-04-16T12:34:56+00:00\"\n    }\n  ]\n}\n```\n\n**Route name:** `automation.templates.index`"}},{"name":"Get Workflow Template","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-templates/{slug}","host":["{{baseUrl}}"],"path":["api","automation","workflow-templates",":slug"],"variable":[{"key":"slug","value":"import-products-csv-upload","description":"Template slug. Seeded values: `import-products-csv-upload`, `import-products-ftp-hourly`, `import-supplier-products-csv-upload`."}]},"description":"Fetches a single workflow template by slug, including the full `parameterPrompts` and `requiredCredentials` arrays needed to drive the wizard.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** `200 OK` — wrapped in `{data: {...}}` with the same workflow template object shape as the list endpoint. The `workflow_json` graph itself is NOT returned by this resource — only `nodeCount` is exposed. The graph is only materialised server-side during `instantiate`.\n\n**Errors:**\n- `404 Not Found` — unknown slug. Response body: `{\"message\": \"No query results for model [WorkflowTemplate].\"}`\n\n**Route name:** `automation.templates.show`"}},{"name":"Instantiate Workflow Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflow-templates/{slug}/instantiate","host":["{{baseUrl}}"],"path":["api","automation","workflow-templates",":slug","instantiate"],"variable":[{"key":"slug","value":"import-products-ftp-hourly","description":"Template slug to instantiate from."}]},"description":"Creates a new **draft** workflow from the template. The server deep-copies the template's `workflow_json`, applies each `parameters[key]` value at its declared `path` (from the template's `parameterPrompts`), then persists the result as a new draft workflow. The template row itself is never mutated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Validation (InstantiateWorkflowTemplateRequest):**\n- `name` — sometimes, string, max 128. If omitted, the template's `name` is used.\n- `parameters` — sometimes, array. Keys must match `parameterPrompts[*].key` from the template; any unknown keys are silently ignored (defense against arbitrary-path injection). Missing required prompts are NOT enforced here — the wizard is responsible for collecting them before publish. Values can be strings, booleans, integers, or credential UUIDs depending on the prompt `type`.\n\n**Behaviour notes:**\n- The created workflow is a draft (`status = draft`). Publishing is a separate explicit step (`POST /api/automation/workflows/{workflow}/publish`).\n- The draft's `settings.instantiated_from_template` stores `{ slug, version }` for drift tracking.\n- `trigger_type` is re-derived from the first trigger node; do NOT pass it in.\n\n**Response:** `201 Created` with a workflow object (same shape as `POST /api/automation/workflows`):\n```json\n{\n  \"data\": {\n    \"id\": \"42\",\n    \"uuid\": \"...\",\n    \"name\": \"My FTP Product Import\",\n    \"description\": \"Polls an FTP directory every hour...\",\n    \"status\": \"draft\",\n    \"version\": 1,\n    \"category\": \"imports\",\n    \"graph\": {\n      \"nodes\": [ ... ],\n      \"edges\": [ ... ],\n      \"viewport\": { \"x\": 0, \"y\": 0, \"zoom\": 1 }\n    },\n    \"settings\": {\n      \"instantiated_from_template\": { \"slug\": \"import-products-ftp-hourly\", \"version\": 1 }\n    },\n    \"triggerType\": \"webhook\",\n    \"triggerConfig\": null,\n    \"createdAt\": \"2026-04-16T12:34:56+00:00\",\n    \"updatedAt\": \"2026-04-16T12:34:56+00:00\",\n    \"publishedAt\": null,\n    \"createdBy\": \"Jane Doe\",\n    \"updatedBy\": \"Jane Doe\"\n  }\n}\n```\n\n**Errors:**\n- `404 Not Found` — unknown slug.\n- `422 Unprocessable Entity` — validation failure (e.g. `name` longer than 128 chars).\n  ```json\n  { \"message\": \"Workflow name must be 128 characters or fewer\", \"errors\": { \"name\": [\"Workflow name must be 128 characters or fewer\"] } }\n  ```\n\n**Route name:** `automation.templates.instantiate`","body":{"mode":"raw","raw":"{\n  \"name\": \"My FTP Product Import\",\n  \"parameters\": {\n    \"ftpCredential\": \"00000000-0000-0000-0000-000000000000\",\n    \"downloadCredential\": \"00000000-0000-0000-0000-000000000000\",\n    \"directory\": \"/inbox/products\",\n    \"pattern\": \"*.csv\"\n  }\n}","options":{"raw":{"language":"json"}}}}}]},{"name":"Workflow Credentials","item":[{"name":"List Workflow Credentials","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials?page=1&per_page=15","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials"],"query":[{"key":"page","value":"1","description":"Page number (1-based).","disabled":true},{"key":"per_page","value":"15","description":"Page size. Defaults to the manager/repository default.","disabled":true}]},"description":"Returns a paginated list of workflow credentials for the authenticated user's tenant.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** Standard Laravel `LengthAwarePaginator` shape where `data[*]` are workflow credential object objects. Each item exposes `uuid`, `name`, `type`, `typeLabel`, `fields` (secrets redacted), optional `createdBy` (when `creator` is loaded), `createdAt`, and `updatedAt`.\n\n**Route name:** `automation.credentials.index`"}},{"name":"Create Workflow Credential","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials"]},"description":"Creates a new workflow credential. Secret fields listed in `CredentialTypeEnum::secretFields` are redacted in the response `fields` object.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Validation (StoreWorkflowCredentialRequest):**\n- `name` — required, string, max 128\n- `type` — required, string, must be a valid `CredentialTypeEnum`: `basic_auth`, `api_key`, `bearer_token`, `ftp`, `sftp`, `google_oauth`, `webhook_token`\n- `data` — required, array (shape varies by type)\n\n**Expected `data` shape per type:**\n- `basic_auth`: `{ username, password }`\n- `api_key`: `{ key, header?: \"X-API-Key\" }`\n- `bearer_token`: `{ token }`\n- `ftp` / `sftp`: `{ host, port, username, password?, privateKey?, passphrase? }`\n- `google_oauth`: `{ accessToken, refreshToken, clientId, clientSecret }`\n- `webhook_token`: `{ token }`\n\n**Response:** `201 Created` with workflow credential object:\n```json\n{\n  \"data\": {\n    \"uuid\": \"...\",\n    \"name\": \"...\",\n    \"type\": \"sftp\",\n    \"typeLabel\": \"SFTP\",\n    \"fields\": { \"host\": \"...\", \"port\": 22, \"username\": \"...\", \"password\": \"********\", \"privateKey\": \"********\", \"passphrase\": \"********\" },\n    \"createdBy\": { \"id\": 1, \"name\": \"Jane Doe\" },\n    \"createdAt\": \"2026-04-16T12:34:56+00:00\",\n    \"updatedAt\": \"2026-04-16T12:34:56+00:00\"\n  }\n}\n```\n\n**Route name:** `automation.credentials.store`","body":{"mode":"raw","raw":"{\n  \"name\": \"Warehouse SFTP (Prod)\",\n  \"type\": \"sftp\",\n  \"data\": {\n    \"host\": \"sftp.example.com\",\n    \"port\": 22,\n    \"username\": \"sku-integrations\",\n    \"password\": \"super-secret-pass\",\n    \"privateKey\": \"-----BEGIN OPENSSH PRIVATE KEY-----\\n...\\n-----END OPENSSH PRIVATE KEY-----\",\n    \"passphrase\": \"optional\"\n  }\n}","options":{"raw":{"language":"json"}}}}},{"name":"Lookup Workflow Credentials by Type","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials/lookup?type=basic_auth","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials","lookup"],"query":[{"key":"type","value":"basic_auth","description":"Required. One of `basic_auth`, `api_key`, `bearer_token`, `ftp`, `sftp`, `google_oauth`, `webhook_token`. An invalid or missing type returns an empty list.","disabled":true}]},"description":"Lightweight dropdown lookup used by node config UIs. Returns only `uuid` + `name` for credentials of the requested type.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response shape:**\n```json\n{\n  \"data\": [\n    { \"uuid\": \"...\", \"name\": \"...\" }\n  ]\n}\n```\n\nIf `type` is missing or not a valid `CredentialTypeEnum` case the endpoint silently returns `{\"data\": []}` (200 OK).\n\n**Route name:** `automation.credentials.lookup`"}},{"name":"Get Workflow Credential","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials/{uuid}","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials",":uuid"],"variable":[{"key":"uuid","value":"00000000-0000-0000-0000-000000000000","description":"The credential's UUID (not numeric ID)."}]},"description":"Fetches a single workflow credential by UUID. 404 if not found.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** `200 OK` with workflow credential object (same shape as create). Secret fields are redacted.\n\n**Route name:** `automation.credentials.show`"}},{"name":"Update Workflow Credential","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials/{uuid}","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials",":uuid"],"variable":[{"key":"uuid","value":"00000000-0000-0000-0000-000000000000","description":"The credential's UUID."}]},"description":"Updates an existing workflow credential. Only the fields sent are updated.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Validation (UpdateWorkflowCredentialRequest):**\n- `name` — sometimes, string, max 128\n- `data` — sometimes, array\n\n`type` is not updatable via this endpoint. `updated_by` is set automatically from the authenticated user.\n\n**Response:** `200 OK` with workflow credential object (secrets redacted in `fields`).\n\n**Route name:** `automation.credentials.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Warehouse SFTP (Prod) - Renamed\",\n  \"data\": {\n    \"host\": \"sftp.example.com\",\n    \"port\": 2222,\n    \"username\": \"sku-integrations\",\n    \"password\": \"rotated-secret\"\n  }\n}","options":{"raw":{"language":"json"}}}}},{"name":"Delete Workflow Credential","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/automation/workflow-credentials/{uuid}","host":["{{baseUrl}}"],"path":["api","automation","workflow-credentials",":uuid"],"variable":[{"key":"uuid","value":"00000000-0000-0000-0000-000000000000","description":"The credential's UUID."}]},"description":"Deletes a workflow credential by UUID. 404 if not found.\n\n**Authorization**\nAny valid API token can call this endpoint — no specific scope required. [Manage tokens](https://app.sku.io/settings/api).\n\n**Response:** `200 OK`\n```json\n{ \"message\": \"Credential deleted\" }\n```\n\n**Route name:** `automation.credentials.destroy`"}}]},{"name":"Report Templates","item":[{"name":"List Report Templates","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/report-templates","host":["{{baseUrl}}"],"path":["api","report-templates"]},"description":"Returns all report templates for the account. Report templates store saved configurations for various reports.\n\n**Required scope: `reports:read`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/report-templates","host":["{{baseUrl}}"],"path":["api","report-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Monthly Sales Summary\",\n      \"content\": {\n        \"date_range\": \"last_30_days\",\n        \"group_by\": \"sales_channel\",\n        \"columns\": [\n          \"revenue\",\n          \"orders\",\n          \"units\"\n        ]\n      },\n      \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n      \"updated_at\": \"2024-01-15T10:00:00.000000Z\"\n    }\n  ]\n}"}]},{"name":"Create Report Template","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/report-templates","host":["{{baseUrl}}"],"path":["api","report-templates"]},"description":"Creates a new report template. The content field stores arbitrary JSON configuration for the report.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- name (required, string): Display name for the template\n- content (required, array/object): Report configuration (arbitrary JSON)\n\n**Requires permission:** `reports.create`","body":{"mode":"raw","raw":"{\n  \"name\": \"Weekly Inventory Report\",\n  \"content\": {\n    \"date_range\": \"last_7_days\",\n    \"group_by\": \"warehouse\",\n    \"columns\": [\n      \"sku\",\n      \"on_hand\",\n      \"available\"\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/report-templates","host":["{{baseUrl}}"],"path":["api","report-templates"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 2,\n    \"name\": \"Weekly Inventory Report\",\n    \"content\": {\n      \"date_range\": \"last_7_days\",\n      \"group_by\": \"warehouse\",\n      \"columns\": [\n        \"sku\",\n        \"on_hand\",\n        \"available\"\n      ]\n    },\n    \"created_at\": \"2024-01-20T14:30:00.000000Z\",\n    \"updated_at\": \"2024-01-20T14:30:00.000000Z\"\n  }\n}"}]},{"name":"Update Report Template","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/report-templates/{report_template}","host":["{{baseUrl}}"],"path":["api","report-templates",":report_template"],"variable":[{"key":"report_template","value":"1","description":"Report template ID"}]},"description":"Updates a report template. Both name and content are optional on update.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\nRequest Body:\n- name (sometimes, string): Display name for the template\n- content (sometimes, array/object): Report configuration\n\n**Requires permission:** `reports.update`","body":{"mode":"raw","raw":"{\n  \"name\": \"Updated Report Name\",\n  \"content\": {\n    \"date_range\": \"last_30_days\",\n    \"columns\": [\n      \"sku\",\n      \"revenue\"\n    ]\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/report-templates/{report_template}","host":["{{baseUrl}}"],"path":["api","report-templates",":report_template"],"variable":[{"key":"report_template","value":"1","description":"Report template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"Updated Report Name\",\n    \"content\": {\n      \"date_range\": \"last_30_days\",\n      \"columns\": [\n        \"sku\",\n        \"revenue\"\n      ]\n    },\n    \"created_at\": \"2024-01-15T10:00:00.000000Z\",\n    \"updated_at\": \"2024-01-20T15:00:00.000000Z\"\n  }\n}"}]},{"name":"Delete Report Template","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/report-templates/{report_template}","host":["{{baseUrl}}"],"path":["api","report-templates",":report_template"],"variable":[{"key":"report_template","value":"1","description":"Report template ID"}]},"description":"Permanently deletes a report template.\n\n**Required scope: `reports:write`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `reports.delete`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/report-templates/{report_template}","host":["{{baseUrl}}"],"path":["api","report-templates",":report_template"],"variable":[{"key":"report_template","value":"1","description":"Report template ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": null\n}"}]}]},{"name":"Webhooks","item":[{"name":"List Outbound Webhook Event Types","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-events","host":["{{baseUrl}}"],"path":["api","webhook-events"]},"description":"Returns the full catalog of subscribable events. Each entry includes the wire `event` name, human `label`/`description`, UI `group`, the `required_scope` needed to subscribe and view samples, and a one-record `sample_payload` shaped exactly like the live webhook payload. Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhook-events","host":["{{baseUrl}}"],"path":["api","webhook-events"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"event\": \"sales_order.created\",\n      \"label\": \"New Sales Order\",\n      \"description\": \"Fires when a new sales order is created (any channel or manual).\",\n      \"group\": \"Sales Orders\",\n      \"required_scope\": \"orders:read\",\n      \"sample_payload\": [\n        {\n          \"event\": \"sales_order.created\",\n          \"occurred_at\": \"2026-06-15T14:03:11+00:00\",\n          \"data\": {\n            \"id\": 4821,\n            \"order_number\": \"SO-10293\",\n            \"status\": \"open\",\n            \"fulfillment_status\": \"unfulfilled\",\n            \"currency\": \"USD\",\n            \"subtotal\": \"129.90\",\n            \"tax_total\": \"10.39\",\n            \"total\": \"140.29\",\n            \"line_count\": 2,\n            \"customer_name\": \"Jane Doe\",\n            \"customer_email\": \"jane@example.com\",\n            \"lines\": [\n              {\n                \"id\": 88231,\n                \"sku\": \"WIDGET-BLK\",\n                \"name\": \"Black Widget\",\n                \"quantity\": 2,\n                \"unit_price\": \"49.95\",\n                \"total\": \"99.90\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    {\n      \"event\": \"inventory.adjusted\",\n      \"label\": \"Inventory Adjusted\",\n      \"description\": \"Fires when on-hand inventory is adjusted.\",\n      \"group\": \"Inventory\",\n      \"required_scope\": \"inventory:read\",\n      \"sample_payload\": []\n    }\n  ]\n}"}]},{"name":"Get Outbound Event Sample Payload","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-events/{event}/sample","host":["{{baseUrl}}"],"path":["api","webhook-events",":event","sample"],"variable":[{"key":"event","value":"sales_order.created","description":"Required. Wire event name. One of: sales_order.created, sales_order.shipped, sales_order.cancelled, purchase_order.created, purchase_order.approved, purchase_order.submitted, purchase_order.received, inventory.adjusted, product.created, customer.created."}]},"description":"Returns up to 3 most-recent real records for the named event, each shaped exactly like the live webhook payload. Backs sample-record discovery for connected apps. Returns an empty `data` array if the tenant has no matching records yet.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\nRequires `webhooks:manage` AND the event's own READ scope (e.g. `orders:read` for sales_order.* events) — a token with only `webhooks:manage` receives 403."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhook-events/{event}/sample","host":["{{baseUrl}}"],"path":["api","webhook-events",":event","sample"],"variable":[{"key":"event","value":"sales_order.created","description":"Required. Wire event name. One of: sales_order.created, sales_order.shipped, sales_order.cancelled, purchase_order.created, purchase_order.approved, purchase_order.submitted, purchase_order.received, inventory.adjusted, product.created, customer.created."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"event\": \"sales_order.created\",\n      \"occurred_at\": \"2026-06-15T14:03:11+00:00\",\n      \"data\": {\n        \"id\": 4821,\n        \"order_number\": \"SO-10293\",\n        \"customer_po_number\": \"PO-55821\",\n        \"status\": \"open\",\n        \"fulfillment_status\": \"unfulfilled\",\n        \"currency\": \"USD\",\n        \"subtotal\": \"129.90\",\n        \"tax_total\": \"10.39\",\n        \"total\": \"140.29\",\n        \"line_count\": 2,\n        \"customer_id\": 312,\n        \"customer_name\": \"Jane Doe\",\n        \"customer_email\": \"jane@example.com\",\n        \"customer_company\": \"Acme Co\",\n        \"shipping_name\": \"Jane Doe\",\n        \"shipping_city\": \"San Francisco\",\n        \"shipping_province\": \"CA\",\n        \"shipping_zip\": \"94103\",\n        \"shipping_country\": \"US\",\n        \"store_id\": 7,\n        \"store_name\": \"Shopify US\",\n        \"warehouse_id\": 2,\n        \"warehouse_name\": \"Main Warehouse\",\n        \"order_date\": \"2026-06-15T14:03:11+00:00\",\n        \"ship_by_date\": \"2026-06-18T00:00:00+00:00\",\n        \"fulfilled_at\": null,\n        \"canceled_at\": null,\n        \"created_at\": \"2026-06-15T14:03:11+00:00\",\n        \"updated_at\": \"2026-06-15T14:03:11+00:00\",\n        \"lines\": [\n          {\n            \"id\": 88231,\n            \"sku\": \"WIDGET-BLK\",\n            \"name\": \"Black Widget\",\n            \"quantity\": 2,\n            \"unit_price\": \"49.95\",\n            \"total\": \"99.90\"\n          },\n          {\n            \"id\": 88232,\n            \"sku\": \"GADGET-SM\",\n            \"name\": \"Small Gadget\",\n            \"quantity\": 1,\n            \"unit_price\": \"30.00\",\n            \"total\": \"30.00\"\n          }\n        ]\n      }\n    }\n  ]\n}"}]},{"name":"List Webhook Subscriptions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions"]},"description":"Paginated list of every webhook subscription on the tenant. The signing `secret` is never included here — it is shown only once in the create response. Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"event\": \"sales_order.created\",\n      \"target_url\": \"https://hooks.example.com/standard/123456/abcdef\",\n      \"source\": \"api\",\n      \"is_active\": true,\n      \"failure_count\": 0,\n      \"disabled_reason\": null,\n      \"last_delivery_at\": \"2026-06-15T14:05:00+00:00\",\n      \"last_delivery_status\": 200,\n      \"created_at\": \"2026-06-15T13:00:00+00:00\",\n      \"updated_at\": \"2026-06-15T14:05:00+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 1,\n  \"from\": 1,\n  \"to\": 1\n}"}]},{"name":"Create Webhook Subscription","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions"]},"description":"Create a subscription. Body fields:\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api).\n\n- `event` (required, string) — wire event name; must be one of the catalog events (see List Events). The token must also hold that event's READ scope.\n- `target_url` (required, string, max 2048, valid URL) — HTTPS endpoint to receive deliveries. Must pass the SSRF guard (public host only).\n\nThe signing `secret` is returned in the response exactly once and is never retrievable again — store it immediately.\n\nIdempotent on (event, target_url): a duplicate POST returns the existing subscription with HTTP 200 (and no `secret`) instead of creating a new one (HTTP 201).","body":{"mode":"raw","raw":"{\n  \"event\": \"sales_order.created\",\n  \"target_url\": \"https://hooks.example.com/standard/123456/abcdef\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions"]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"event\": \"sales_order.created\",\n    \"target_url\": \"https://hooks.example.com/standard/123456/abcdef\",\n    \"source\": \"api\",\n    \"is_active\": true,\n    \"failure_count\": 0,\n    \"disabled_reason\": null,\n    \"last_delivery_at\": \"2026-06-15T14:05:00+00:00\",\n    \"last_delivery_status\": 200,\n    \"created_at\": \"2026-06-15T13:00:00+00:00\",\n    \"updated_at\": \"2026-06-15T14:05:00+00:00\"\n  }\n}"}]},{"name":"Get Webhook Subscription","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]},"description":"Returns a single subscription owned by the authenticated user/tenant. Never includes the signing `secret`. Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"event\": \"sales_order.created\",\n    \"target_url\": \"https://hooks.example.com/standard/123456/abcdef\",\n    \"source\": \"api\",\n    \"is_active\": true,\n    \"failure_count\": 0,\n    \"disabled_reason\": null,\n    \"last_delivery_at\": \"2026-06-15T14:05:00+00:00\",\n    \"last_delivery_status\": 200,\n    \"created_at\": \"2026-06-15T13:00:00+00:00\",\n    \"updated_at\": \"2026-06-15T14:05:00+00:00\"\n  }\n}"}]},{"name":"Delete Webhook Subscription","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]},"description":"Delete (unsubscribe) a subscription. Idempotent — always returns 204, even if no matching row existed (clients may retry unsubscribe calls). Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"No Content","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]}},"status":"No Content","code":204,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":""}]},{"name":"List Deliveries","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}/deliveries","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id","deliveries"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]},"description":"Paginated delivery log for one subscription, newest first. Each row captures one delivery attempt: HTTP `response_status`/`response_body`, `duration_ms`, `attempt` number, whether it `succeeded`, and whether it was `throttled` (dropped before dispatch because the tenant's per-minute outbound rate cap was hit — `succeeded: false`, `attempt: 0`, `response_status: null`). The full signed `payload` that was (or would have been) sent is included. Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}/deliveries","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id","deliveries"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 9001,\n      \"delivery_id\": \"f1e2d3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f\",\n      \"event\": \"sales_order.created\",\n      \"attempt\": 1,\n      \"response_status\": 200,\n      \"response_body\": \"OK\",\n      \"duration_ms\": 142,\n      \"succeeded\": true,\n      \"throttled\": false,\n      \"payload\": {\n        \"event\": \"sales_order.created\",\n        \"delivery_id\": \"f1e2d3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f\",\n        \"occurred_at\": \"2026-06-15T14:05:00+00:00\",\n        \"data\": {\n          \"id\": 4821,\n          \"order_number\": \"SO-10293\",\n          \"status\": \"open\"\n        }\n      },\n      \"created_at\": \"2026-06-15T14:05:00+00:00\"\n    },\n    {\n      \"id\": 9002,\n      \"delivery_id\": \"a9b8c7d6-1234-5678-90ab-cdef01234567\",\n      \"event\": \"sales_order.created\",\n      \"attempt\": 0,\n      \"response_status\": null,\n      \"response_body\": \"Dropped: tenant outbound webhook rate limit exceeded.\",\n      \"duration_ms\": 0,\n      \"succeeded\": false,\n      \"throttled\": true,\n      \"payload\": {\n        \"event\": \"sales_order.created\",\n        \"delivery_id\": \"a9b8c7d6-1234-5678-90ab-cdef01234567\",\n        \"occurred_at\": \"2026-06-15T14:05:01+00:00\",\n        \"data\": {\n          \"id\": 4822,\n          \"order_number\": \"SO-10294\",\n          \"status\": \"open\"\n        }\n      },\n      \"created_at\": \"2026-06-15T14:05:01+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Send Test Delivery","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}/test","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id","test"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]},"description":"Send a synchronous test delivery to the subscription's target URL with a signed `{ \"_test\": true }` payload. Runs inline (not queued) so the UI can show the result immediately, and records a row in the delivery log regardless of outcome. Always returns 200 with the generated `delivery_id` even if the target responds with an error (inspect the delivery log for the captured status). Requires the `webhooks:manage` scope.\n\n**Required scope: `webhooks:manage`**\nGrant this scope to your token under [Settings → Developer → Personal Access Tokens](https://app.sku.io/settings/api)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/webhook-subscriptions/{id}/test","host":["{{baseUrl}}"],"path":["api","webhook-subscriptions",":id","test"],"variable":[{"key":"id","value":"42","description":"Required. Numeric subscription id."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"message\": \"Test delivery sent.\",\n  \"delivery_id\": \"f1e2d3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f\"\n}"}]}]}]},{"name":"Other","item":[{"name":"API","item":[{"name":"List Supplier Contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"List all contacts attached to a supplier, paginated. Supports search (title/notes), role/primary/has-email filters, advanced per-column filters, and sorting.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": [\n    {\n      \"id\": 42,\n      \"name\": \"Jane Buyer\",\n      \"email\": \"jane.buyer@example.com\",\n      \"phone\": \"+1 415-555-0100\",\n      \"role\": \"accounts_payable\",\n      \"role_label\": \"Accounts Payable\",\n      \"title\": \"AP Specialist\",\n      \"is_primary\": true,\n      \"notes\": \"Prefers email over phone.\",\n      \"link_type\": \"supplier\",\n      \"link_id\": 12,\n      \"created_at\": \"2026-07-13T14:22:05+00:00\",\n      \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n    },\n    {\n      \"id\": 43,\n      \"name\": \"Sam Sales\",\n      \"email\": \"sam.sales@example.com\",\n      \"phone\": \"+1 415-555-0100\",\n      \"role\": \"sales_rep\",\n      \"role_label\": \"Sales Rep\",\n      \"title\": \"Account Executive\",\n      \"is_primary\": false,\n      \"notes\": \"Prefers email over phone.\",\n      \"link_type\": \"supplier\",\n      \"link_id\": 12,\n      \"created_at\": \"2026-07-13T14:22:05+00:00\",\n      \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n    }\n  ],\n  \"current_page\": 1,\n  \"last_page\": 1,\n  \"per_page\": 10,\n  \"total\": 2,\n  \"from\": 1,\n  \"to\": 2\n}"}]},{"name":"Create Supplier Contact","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]},"description":"Add a new contact to a supplier. Fields: name (required), email, phone, role (default general), title, is_primary, notes (max 500). The first contact added to a supplier automatically becomes primary; setting is_primary demotes the previous primary.\n\nRole options: general, sales_rep, account_manager, customer_service, accounts_payable, accounts_receivable, purchasing, shipping_receiving, warehouse_manager, operations, billing, owner, other.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Buyer\",\n  \"email\": \"jane.buyer@example.com\",\n  \"phone\": \"+1 415-555-0100\",\n  \"role\": \"accounts_payable\",\n  \"title\": \"AP Specialist\",\n  \"is_primary\": true,\n  \"notes\": \"Prefers email over phone.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"supplier\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Export Contacts","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/export?format=csv","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts","export"],"query":[{"key":"format","value":"csv","description":"Export format: csv (default) or xlsx","disabled":true}],"variable":[{"key":"supplier","value":"1","description":"Supplier ID"}]},"description":"Download all contacts belonging to the supplier as a CSV or XLSX file. Columns: Contact ID, Name, Email, Phone, Role, Title, Primary, Notes, Created At, Updated At. The file mirrors the contacts bulk-import template, so an exported file can be edited and re-imported (rows with a Contact ID or a matching email update the existing contact; others are created).\n\nOptional comma-separated column keys (`name,role,title,email,phone,notes,created_at`) to narrow the exported fields; `Contact ID` is always included so the file can round-trip as an update. Omit for the full field set.\n\nOptional. `filtered` applies the request's filter/sort parameters (same syntax as the list endpoint) instead of exporting every contact."}},{"name":"Get Supplier Contact","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Get a single contact belonging to the supplier. A contact id that belongs to a different supplier returns 404.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"GET","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"supplier\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Update Supplier Contact","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Update a contact belonging to the supplier. Full update — name is required. Setting is_primary promotes this contact and demotes the previous primary.\n\nRole options: general, sales_rep, account_manager, customer_service, accounts_payable, accounts_receivable, purchasing, shipping_receiving, warehouse_manager, operations, billing, owner, other.\n\nAuthentication: Requires Bearer token.","body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Buyer\",\n  \"email\": \"jane.buyer@example.com\",\n  \"phone\": \"+1 415-555-0100\",\n  \"role\": \"accounts_payable\",\n  \"title\": \"AP Specialist\",\n  \"is_primary\": true,\n  \"notes\": \"Prefers email over phone.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"PUT","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"supplier\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Delete Supplier Contact","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Delete a contact from the supplier. If the deleted contact was primary and other contacts remain, the oldest remaining contact is promoted to primary.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"success\": true,\n  \"message\": \"Contact deleted.\"\n}"}]},{"name":"Set Supplier Contact as Primary","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}/make-primary","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact","make-primary"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]},"description":"Promote a contact to be the supplier's primary contact, demoting the previous primary.\n\nAuthentication: Requires Bearer token."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/v2/suppliers/{supplier}/contacts/{contact}/make-primary","host":["{{baseUrl}}"],"path":["api","v2","suppliers",":supplier","contacts",":contact","make-primary"],"variable":[{"key":"supplier","value":"12","description":"Supplier ID"},{"key":"contact","value":"42","description":"Contact ID"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 42,\n    \"name\": \"Jane Buyer\",\n    \"email\": \"jane.buyer@example.com\",\n    \"phone\": \"+1 415-555-0100\",\n    \"role\": \"accounts_payable\",\n    \"role_label\": \"Accounts Payable\",\n    \"title\": \"AP Specialist\",\n    \"is_primary\": true,\n    \"notes\": \"Prefers email over phone.\",\n    \"link_type\": \"supplier\",\n    \"link_id\": 12,\n    \"created_at\": \"2026-07-13T14:22:05+00:00\",\n    \"updated_at\": \"2026-07-13T14:22:05+00:00\"\n  }\n}"}]},{"name":"Request Purchase Order Approval","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/request-approval","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","request-approval"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Submit a draft purchase order for approval. Notifies every user who holds the purchase_orders.approve permission. The purchase order must be a draft with at least one line, and must not already have a pending request.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`\n\nThe optional notes field (max 1000 characters) is shown to approvers with the request. The response includes notified_approvers — the number of users notified.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Urgent restock for July promotion.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/request-approval","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","request-approval"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"data\": {\n    \"id\": 101,\n    \"purchase_order_number\": \"PO-101\",\n    \"order_status\": \"draft\",\n    \"approval_status\": \"pending_approval\",\n    \"approval_requested_at\": \"2026-07-14T09:12:33+00:00\",\n    \"approval_requested_by\": {\n      \"id\": 7,\n      \"name\": \"Jane Clerk\"\n    },\n    \"approval_request_notes\": \"Urgent restock for July promotion.\",\n    \"approval_actioned_at\": null,\n    \"approval_actioned_by\": null,\n    \"approval_action_notes\": null\n  },\n  \"notified_approvers\": 2\n}"}]},{"name":"Withdraw Purchase Order Approval Request","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Withdraw a pending approval request, returning the purchase order to the not-requested state. Only the user who requested approval (or an admin) can withdraw it.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.update`"},"response":[{"name":"OK","originalRequest":{"method":"DELETE","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 101,\n  \"purchase_order_number\": \"PO-101\",\n  \"order_status\": \"draft\",\n  \"approval_status\": \"not_requested\",\n  \"approval_requested_at\": null,\n  \"approval_requested_by\": null,\n  \"approval_request_notes\": null,\n  \"approval_actioned_at\": null,\n  \"approval_actioned_by\": null,\n  \"approval_action_notes\": null\n}"}]},{"name":"Approve Purchase Order Approval Request","request":{"method":"POST","header":[],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request/approve","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request","approve"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Approve a pending approval request. Runs the standard purchase order approval: the order moves to open, inventory becomes inbound, and backorder coverage is applied. The requester is notified that their purchase order was approved.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.approve`\n\nReturns 422 if the request was already approved, rejected, or withdrawn (for example by another approver acting first)."},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request/approve","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request","approve"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 101,\n  \"purchase_order_number\": \"PO-101\",\n  \"order_status\": \"open\",\n  \"approval_status\": \"approved\",\n  \"approval_requested_at\": \"2026-07-14T09:12:33+00:00\",\n  \"approval_requested_by\": {\n    \"id\": 7,\n    \"name\": \"Jane Clerk\"\n  },\n  \"approval_request_notes\": \"Urgent restock for July promotion.\",\n  \"approval_actioned_at\": \"2026-07-14T10:05:00+00:00\",\n  \"approval_actioned_by\": {\n    \"id\": 3,\n    \"name\": \"John Manager\"\n  },\n  \"approval_action_notes\": null\n}"}]},{"name":"Reject Purchase Order Approval Request","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request/reject","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request","reject"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]},"description":"Reject a pending approval request with a reason. The purchase order stays in draft, and the requester is notified with the reason so they can amend the order and request approval again.\n\nAuthentication: Requires Bearer token.\n\n**Requires permission:** `purchase_orders.approve`\n\nThe notes field (rejection reason) is required, max 1000 characters.","body":{"mode":"raw","raw":"{\n  \"notes\": \"Quantities are wrong — should be 74, not 76.\"\n}","options":{"raw":{"language":"json"}}}},"response":[{"name":"OK","originalRequest":{"method":"POST","url":{"raw":"{{baseUrl}}/api/purchase-orders/{purchase_order}/approval-request/reject","host":["{{baseUrl}}"],"path":["api","purchase-orders",":purchase_order","approval-request","reject"],"variable":[{"key":"purchase_order","value":"101","description":"The purchase order ID."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"body":"{\n  \"id\": 101,\n  \"purchase_order_number\": \"PO-101\",\n  \"order_status\": \"draft\",\n  \"approval_status\": \"rejected\",\n  \"approval_requested_at\": \"2026-07-14T09:12:33+00:00\",\n  \"approval_requested_by\": {\n    \"id\": 7,\n    \"name\": \"Jane Clerk\"\n  },\n  \"approval_request_notes\": \"Urgent restock for July promotion.\",\n  \"approval_actioned_at\": \"2026-07-14T10:05:00+00:00\",\n  \"approval_actioned_by\": {\n    \"id\": 3,\n    \"name\": \"John Manager\"\n  },\n  \"approval_action_notes\": \"Quantities are wrong — should be 74, not 76.\"\n}"}]}]}]}]}